浏览代码

Merge remote-tracking branch 'origin/developerL' into developer

kaick 1 年之前
父节点
当前提交
02ea1dcd63
共有 45 个文件被更改,包括 2823 次插入76 次删除
  1. 47 0
      pom.xml
  2. 1 7
      src/main/java/com/caimei365/manager/FastDFS/FastDFSClient.java
  3. 2 0
      src/main/java/com/caimei365/manager/ManagerApplication.java
  4. 32 0
      src/main/java/com/caimei365/manager/config/TaskPoolConfig.java
  5. 7 6
      src/main/java/com/caimei365/manager/config/WebConfig.java
  6. 36 0
      src/main/java/com/caimei365/manager/controller/caimei/HomeApi.java
  7. 148 0
      src/main/java/com/caimei365/manager/controller/caimei/productArchive/ProductArchiveController.java
  8. 14 0
      src/main/java/com/caimei365/manager/dao/HomeDao.java
  9. 89 0
      src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveContentMapper.java
  10. 92 0
      src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveFileMapper.java
  11. 91 0
      src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveMapper.java
  12. 12 0
      src/main/java/com/caimei365/manager/entity/caimei/CmBehaviorRecord.java
  13. 60 0
      src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchive.java
  14. 120 0
      src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchiveContent.java
  15. 59 0
      src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchiveFile.java
  16. 31 0
      src/main/java/com/caimei365/manager/entity/po/KeyPo.java
  17. 14 0
      src/main/java/com/caimei365/manager/service/caimei/HomeService.java
  18. 40 0
      src/main/java/com/caimei365/manager/service/caimei/impl/AsyncService.java
  19. 13 0
      src/main/java/com/caimei365/manager/service/caimei/impl/HomeServiceImpl.java
  20. 51 0
      src/main/java/com/caimei365/manager/service/caimei/productArchive/CmProductArchiveContentService.java
  21. 45 0
      src/main/java/com/caimei365/manager/service/caimei/productArchive/CmProductArchiveService.java
  22. 97 0
      src/main/java/com/caimei365/manager/service/caimei/productArchive/impl/CmProductArchiveContentServiceImpl.java
  23. 72 0
      src/main/java/com/caimei365/manager/service/caimei/productArchive/impl/CmProductArchiveServiceImpl.java
  24. 1 3
      src/main/java/com/caimei365/manager/service/caimei/providers/impl/CmProvidersContractServiceImpl.java
  25. 1 9
      src/main/java/com/caimei365/manager/service/caimei/providers/impl/CmProvidersServiceImpl.java
  26. 1 15
      src/main/java/com/caimei365/manager/service/caimei/providers/utils/ProvidersTemplate.java
  27. 80 0
      src/main/java/com/caimei365/manager/utils/Base64Util.java
  28. 60 0
      src/main/java/com/caimei365/manager/utils/CmdExecuter.java
  29. 52 0
      src/main/java/com/caimei365/manager/utils/DocUtil.java
  30. 251 0
      src/main/java/com/caimei365/manager/utils/FFMPEG.java
  31. 2 8
      src/main/java/com/caimei365/manager/utils/ImageUtils.java
  32. 48 26
      src/main/java/com/caimei365/manager/utils/OSSUtils.java
  33. 141 0
      src/main/java/com/caimei365/manager/utils/PdfUtil.java
  34. 93 0
      src/main/java/com/caimei365/manager/utils/Ppt2Pdf.java
  35. 266 0
      src/main/java/com/caimei365/manager/utils/WaterMarkUtils.java
  36. 31 0
      src/main/java/com/caimei365/manager/utils/formDataUtils.java
  37. 15 0
      src/main/resources/excel-license.xml
  38. 13 0
      src/main/resources/license-slides.xml
  39. 16 0
      src/main/resources/mapper/CmBehaciorRecordDao.xml
  40. 33 1
      src/main/resources/mapper/HomeDao.xml
  41. 1 1
      src/main/resources/mapper/KeyWordDao.xml
  42. 200 0
      src/main/resources/mapper/productArchive/CmProductArchiveContentMapper.xml
  43. 169 0
      src/main/resources/mapper/productArchive/CmProductArchiveFileMapper.xml
  44. 161 0
      src/main/resources/mapper/productArchive/CmProductArchiveMapper.xml
  45. 15 0
      src/main/resources/word-license.xml

+ 47 - 0
pom.xml

@@ -17,6 +17,53 @@
         <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>
+            <version>4.1.2</version>
+        </dependency>
+        <dependency>
+            <groupId>com.documents4j</groupId>
+            <artifactId>documents4j-local</artifactId>
+            <version>1.0.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.documents4j</groupId>
+            <artifactId>documents4j-transformer-msoffice-word</artifactId>
+            <version>1.0.3</version>
+        </dependency>
+        <!--        pdfbox-->
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itext-asian</artifactId>
+            <version>5.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.pdfbox</groupId>
+            <artifactId>pdfbox</artifactId>
+            <version>2.0.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.itextpdf</groupId>
+            <artifactId>itextpdf</artifactId>
+            <version>5.3.2</version>
+        </dependency>
         <!--      图像生成-->
         <dependency>
             <groupId>com.google.zxing</groupId>

+ 1 - 7
src/main/java/com/caimei365/manager/FastDFS/FastDFSClient.java

@@ -1,9 +1,6 @@
 package com.caimei365.manager.FastDFS;
 
-import com.caimei365.manager.config.thinkgem.Global;
-import com.caimei365.manager.entity.po.UploadFilePo;
-import com.caimei365.manager.service.caimei.providers.utils.ImageUtils;
-import com.caimei365.manager.utils.FileIOUtils;
+import com.caimei365.manager.utils.ImageUtils;
 import com.github.tobato.fastdfs.domain.StorePath;
 import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
 import com.github.tobato.fastdfs.service.FastFileStorageClient;
@@ -14,14 +11,11 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
-import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.awt.image.BufferedImage;
 import java.io.*;
-import java.net.URL;
 import java.net.URLEncoder;
-import java.util.List;
 import java.util.UUID;
 
 @Slf4j

+ 2 - 0
src/main/java/com/caimei365/manager/ManagerApplication.java

@@ -2,7 +2,9 @@ package com.caimei365.manager;
 
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
 
+@EnableAsync
 @SpringBootApplication
 public class ManagerApplication {
 

+ 32 - 0
src/main/java/com/caimei365/manager/config/TaskPoolConfig.java

@@ -0,0 +1,32 @@
+package com.caimei365.manager.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/11/12
+ */
+@Configuration
+public class TaskPoolConfig {
+    @Bean("taskExecutor")
+    public Executor taskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(10);
+        executor.setMaxPoolSize(20);
+        executor.setQueueCapacity(200);
+        executor.setKeepAliveSeconds(60);
+        executor.setThreadNamePrefix("asyncTask-");
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.setAwaitTerminationSeconds(60);
+        return executor;
+    }
+}

+ 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();
     }
 }

+ 36 - 0
src/main/java/com/caimei365/manager/controller/caimei/HomeApi.java

@@ -2,16 +2,22 @@ package com.caimei365.manager.controller.caimei;
 
 import cn.hutool.core.date.DateTime;
 import com.caimei365.manager.config.utils.DateUtil;
+import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
 import com.caimei365.manager.service.caimei.HomeService;
+import com.github.pagehelper.PageHelper;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
 import javax.validation.constraints.NotNull;
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -67,4 +73,34 @@ public class HomeApi {
         }
         return homeService.getAccessRecordCount(startCreateTime, endCreateTime);
     }
+
+    /**
+     * 关键词下拉选择项
+     */
+    @GetMapping("/findKeyWordList")
+    public ResponseJson findKeyWordList(String keyword,
+                                        @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                        @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        return ResponseJson.success(new PaginationVo(homeService.findKeyWordList(keyword)));
+    }
+
+    /**
+     * 已上线商品列表
+     */
+    @GetMapping("/findProductList")
+    public ResponseJson findProductList(String shopName,
+                                        String productName,
+                                        Integer productId,
+                                        @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                        @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmProductArchive> list = homeService.findProductList(new CmProductArchive()
+                .setProductId(productId)
+                .setProductName(productName)
+                .setShopName(shopName)
+        );
+        return ResponseJson.success(new PaginationVo(list));
+    }
+
 }

+ 148 - 0
src/main/java/com/caimei365/manager/controller/caimei/productArchive/ProductArchiveController.java

@@ -0,0 +1,148 @@
+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;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveContent;
+import com.caimei365.manager.entity.caimei.providers.CmProviders;
+import com.caimei365.manager.service.caimei.productArchive.CmProductArchiveContentService;
+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.*;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import javax.imageio.stream.ImageOutputStream;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * 内容库管理接口
+ */
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("/productArchive")
+public class ProductArchiveController {
+
+    @Resource
+    private CmProductArchiveService cmProductArchiveService;
+    @Resource
+    private CmProductArchiveContentService cmProductArchiveContentService;
+
+    @GetMapping("/list")
+    public ResponseJson productArchiveList(String productName,
+                                           String productType,
+                                           Integer productClassify,
+                                           @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                           @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmProductArchive> list = cmProductArchiveService.getCmProductArchiveList(new CmProductArchive()
+                .setProductName(productName)
+                .setProductType(productType)
+                .setProductClassify(productClassify)
+        );
+        return ResponseJson.success(new PaginationVo(list));
+    }
+
+    @GetMapping("/from")
+    public ResponseJson productArchiveFrom(String id) {
+        return ResponseJson.success(cmProductArchiveService.getCmProductArchive(new CmProductArchive().setId(id)));
+    }
+
+    @PostMapping("/add")
+    public ResponseJson productArchiveAdd(@RequestBody CmProductArchive cmProductArchive
+    ) {
+        // if (null == cmProviders.getName() ||
+        //         null == cmProviders.getLinkMan() ||
+        // ) {
+        //     return ResponseJson.error("参数异常!");
+        // }
+        cmProductArchiveService.addCmProductArchive(cmProductArchive);
+        return ResponseJson.success();
+    }
+
+    @GetMapping("/content/list")
+    public ResponseJson productArchiveContentList(String title,
+                                                  Integer stageStatus,
+                                                  Integer allStatus,
+                                                  String labelIds,
+                                                  @NotNull(message = "productArchiveId不能为空") Integer productArchiveId,
+                                                  @NotBlank(message = "type不能为空") String type,
+                                                  @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                  @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmProductArchiveContent> list = cmProductArchiveContentService.getCmProductArchiveContentList(new CmProductArchiveContent()
+                .setType(type)
+                .setProductArchiveId(productArchiveId)
+                .setTitle(title)
+                .setStageStatus(stageStatus)
+                .setAllStatus(allStatus)
+                .setLabelIds(labelIds)
+        );
+        return ResponseJson.success(new PaginationVo(list));
+    }
+
+    @GetMapping("/content/from")
+    public ResponseJson productArchiveContentFrom(String id) {
+        return ResponseJson.success(cmProductArchiveContentService.getCmProductArchiveContent(new CmProductArchiveContent().setId(id)));
+    }
+    @PostMapping("/content/add")
+    public ResponseJson productArchiveContentAdd(@RequestBody CmProductArchiveContent cmProductArchiveContent
+    ) {
+        // if (null == cmProviders.getName() ||
+        //         null == cmProviders.getLinkMan() ||
+        // ) {
+        //     return ResponseJson.error("参数异常!");
+        // }
+        cmProductArchiveContentService.addCmProductArchiveContent(cmProductArchiveContent);
+        return ResponseJson.success();
+    }
+
+    @PostMapping("content/del")
+    public ResponseJson providersUpdateStatus(@NotBlank(message = "ids不能为空") String ids,
+                                              @NotNull(message = "productArchiveId不能为空") Integer productArchiveId,
+                                              @NotBlank(message = "type不能为空") String type) {
+        for (String id : ids.split(",")) {
+            cmProductArchiveContentService.delCmProductArchiveContent(new CmProductArchiveContent()
+                    .setId(id)
+                    .setProductArchiveId(productArchiveId)
+                    .setType(type)
+            );
+        }
+        return ResponseJson.success();
+    }
+
+
+    @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));
+    }
+
+
+}

+ 14 - 0
src/main/java/com/caimei365/manager/dao/HomeDao.java

@@ -1,5 +1,8 @@
 package com.caimei365.manager.dao;
 
+import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+import com.caimei365.manager.entity.po.KeyPo;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -73,4 +76,15 @@ public interface HomeDao {
      * 热门搜索词
      */
     List<String> countKeyword(@Param("startCreateTime") Date startCreateTime, @Param("endCreateTime") Date endCreateTime);
+    /**
+     * 关键词下拉选择项
+     */
+    List<KeyWord> findKeyWordList(String keyword);
+
+    /**
+     * 已上线商品列表
+     */
+    List<CmProductArchive> findProductList(CmProductArchive cmProductArchive);
+
+
 }

+ 89 - 0
src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveContentMapper.java

@@ -0,0 +1,89 @@
+package com.caimei365.manager.dao.productArchive;
+
+import java.util.List;
+
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveContent;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 商品资料内容Mapper接口
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Mapper
+public interface CmProductArchiveContentMapper
+{
+    /**
+     * 通过对象查询商品资料内容列表
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容集合
+     */
+    List<CmProductArchiveContent> getCmProductArchiveContentList(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 通过Id查询商品资料内容对象
+     *
+     * @param id 商品资料内容主键
+     * @return 商品资料内容
+     */
+    CmProductArchiveContent getCmProductArchiveContentById(String id);
+
+    /**
+     * 通过对象查询商品资料内容对象
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容
+     */
+    CmProductArchiveContent getByCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 通过对象查询商品资料内容Id
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return String
+     */
+    String getById(CmProductArchiveContent cmProductArchiveContent);
+
+
+    /**
+     * 通过对象查询商品资料内容记录总数
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容Integer
+     */
+    int getCount(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 新增商品资料内容
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 结果
+     */
+    int addCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 修改商品资料内容
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 结果
+     */
+    int updateCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 删除商品资料内容
+     *
+     * @param id 商品资料内容主键
+     * @return 结果
+     */
+    int delCmProductArchiveContentById(String id);
+
+    /**
+     * 批量删除商品资料内容
+     * @return 结果
+     */
+    int delCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+}

+ 92 - 0
src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveFileMapper.java

@@ -0,0 +1,92 @@
+package com.caimei365.manager.dao.productArchive;
+
+import java.util.List;
+
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveFile;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+
+/**
+ * 商品资料文件Mapper接口
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Mapper
+public interface CmProductArchiveFileMapper
+{
+    /**
+     * 通过对象查询商品资料文件列表
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return 商品资料文件集合
+     */
+    List<CmProductArchiveFile> getCmProductArchiveFileList(CmProductArchiveFile cmProductArchiveFile);
+
+    /**
+     * 通过Id查询商品资料文件对象
+     *
+     * @param id 商品资料文件主键
+     * @return 商品资料文件
+     */
+    CmProductArchiveFile getCmProductArchiveFileById(String id);
+
+    /**
+     * 通过对象查询商品资料文件对象
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return 商品资料文件
+     */
+    CmProductArchiveFile getByCmProductArchiveFile(CmProductArchiveFile cmProductArchiveFile);
+
+    /**
+     * 通过对象查询商品资料文件Id
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return String
+     */
+    String getById(CmProductArchiveFile cmProductArchiveFile);
+
+
+    /**
+     * 通过对象查询商品资料文件记录总数
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return 商品资料文件Integer
+     */
+    int getCount(CmProductArchiveFile cmProductArchiveFile);
+
+    /**
+     * 新增商品资料文件
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return 结果
+     */
+    int addCmProductArchiveFile(CmProductArchiveFile cmProductArchiveFile);
+
+    /**
+     * 修改商品资料文件
+     *
+     * @param cmProductArchiveFile 商品资料文件
+     * @return 结果
+     */
+    int updateCmProductArchiveFile(CmProductArchiveFile cmProductArchiveFile);
+
+    /**
+     * 删除商品资料文件
+     *
+     * @param id 商品资料文件主键
+     * @return 结果
+     */
+    int delCmProductArchiveFileById(String id);
+
+    /**
+     * 批量删除商品资料文件
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int delCmProductArchiveFile(CmProductArchiveFile cmProductArchiveFile);
+
+}

+ 91 - 0
src/main/java/com/caimei365/manager/dao/productArchive/CmProductArchiveMapper.java

@@ -0,0 +1,91 @@
+package com.caimei365.manager.dao.productArchive;
+
+import java.util.List;
+
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * 商品资料库Mapper接口
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Mapper
+public interface CmProductArchiveMapper
+{
+    /**
+     * 通过对象查询商品资料库列表
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库集合
+     */
+    List<CmProductArchive> getCmProductArchiveList(CmProductArchive cmProductArchive);
+
+    /**
+     * 通过Id查询商品资料库对象
+     *
+     * @param id 商品资料库主键
+     * @return 商品资料库
+     */
+    CmProductArchive getCmProductArchiveById(String id);
+
+    /**
+     * 通过对象查询商品资料库对象
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库
+     */
+    CmProductArchive getByCmProductArchive(CmProductArchive cmProductArchive);
+
+    /**
+     * 通过对象查询商品资料库Id
+     *
+     * @param cmProductArchive 商品资料库
+     * @return String
+     */
+    String getById(CmProductArchive cmProductArchive);
+
+
+    /**
+     * 通过对象查询商品资料库记录总数
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库Integer
+     */
+    int getCount(CmProductArchive cmProductArchive);
+
+    /**
+     * 新增商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 结果
+     */
+    int addCmProductArchive(CmProductArchive cmProductArchive);
+
+    /**
+     * 修改商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 结果
+     */
+    int updateCmProductArchive(CmProductArchive cmProductArchive);
+
+    /**
+     * 删除商品资料库
+     *
+     * @param id 商品资料库主键
+     * @return 结果
+     */
+    int delCmProductArchiveById(String id);
+
+    /**
+     * 批量删除商品资料库
+     *
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    int delCmProductArchive(CmProductArchive cmProductArchive);
+
+}

+ 12 - 0
src/main/java/com/caimei365/manager/entity/caimei/CmBehaviorRecord.java

@@ -269,4 +269,16 @@ public class CmBehaviorRecord {
      */
     @ExcelIgnore
     private String pageLabels;
+
+    /**
+     * 记录起始者userId
+     *
+     */
+    @ExcelIgnore
+    private String headUserId;
+    /**
+     * 商品资料库id
+     */
+    @ExcelIgnore
+    private String productArchiveId;
 }

+ 60 - 0
src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchive.java

@@ -0,0 +1,60 @@
+package com.caimei365.manager.entity.caimei.productArchive;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.type.Alias;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 商品资料库对象 cm_product_archive
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Accessors(chain  = true )
+@Data
+@Alias("CmProductArchive")
+public class CmProductArchive implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private String id;
+
+    /** 商品id */
+    private Integer productId;
+
+    /** 商品名称 */
+    private String productName;
+
+    /** 供应商名称 */
+    private String shopName;
+
+    /** 商品图片 */
+    private String productImage;
+
+    /** 商品属性:1产品,2仪器 */
+    private String productType;
+    /** 创建人 */
+    private String createBy;
+
+    /** 商品分类:1医美,2生美 */
+    private Integer productClassify;
+
+    /** 添加时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date addTime;
+
+
+
+
+}
+
+
+

+ 120 - 0
src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchiveContent.java

@@ -0,0 +1,120 @@
+package com.caimei365.manager.entity.caimei.productArchive;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+import java.io.Serializable;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.type.Alias;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 商品资料内容对象 cm_product_archive_content
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Accessors(chain = true)
+@Data
+@Alias("CmProductArchiveContent")
+public class CmProductArchiveContent implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * $column.columnComment
+     */
+    private String id;
+
+    /**
+     * 商品资料库id
+     */
+    private Integer productArchiveId;
+
+    /**
+     * 资料标题
+     */
+    private String title;
+
+    /**
+     * 资料类型:
+     * 1图片资料,
+     * 2视频资料,
+     * 3文件资料,
+     * 4文本资料
+     * 5话术资料
+     */
+    private String type;
+
+    /**
+     * 内容
+     */
+    private String content;
+    /**
+     * 创建人
+     */
+    private String createBy;
+
+    /**
+     * 用户阶段状态:
+     * 1认知阶段、
+     * 2兴趣阶段、
+     * 3决策阶段、
+     * 4购买阶段
+     */
+    private Integer stageStatus;
+
+    /**
+     * 所有状态:
+     * 1企业,
+     * 2个人
+     */
+    private Integer allStatus;
+
+    /**
+     * 标签库ids
+     */
+    private String labelIds;
+    /**
+     * 标签库关键词s
+     */
+    private String keywords;
+
+    /**
+     * 添加时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date addTime;
+
+    //点击量统计
+    /**
+     * 开始点击量时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date startPvCreateTime;
+    /**
+     * 结束点击量时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date endPvCreateTime;
+    /**
+     * 点击量
+     */
+    private Integer pv;
+    /**
+     * 点击量
+     */
+    private List<CmProductArchiveFile> archiveFiles;
+
+
+}
+
+
+

+ 59 - 0
src/main/java/com/caimei365/manager/entity/caimei/productArchive/CmProductArchiveFile.java

@@ -0,0 +1,59 @@
+package com.caimei365.manager.entity.caimei.productArchive;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.type.Alias;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import java.util.Date;
+
+/**
+ * 商品资料文件对象 cm_product_archive_file
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Accessors(chain  = true )
+@Data
+@Alias("CmProductArchiveFile")
+public class CmProductArchiveFile implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private String id;
+
+    /** 资料库内容id */
+    private Integer archiveContentId;
+
+    /** 文件名 */
+    private String fileName;
+
+    /** oss名称 */
+    private String ossName;
+
+    /** 水印oss名称 */
+    private String waterOssName;
+
+    /** oss链接 */
+    private String ossUrl;
+
+    /** 水印oss链接 */
+    private String waterOssUrl;
+
+    /** html链接\n */
+    private String htmlUrl;
+
+    /** 上传时间 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date uploadTime;
+
+
+}
+
+
+

+ 31 - 0
src/main/java/com/caimei365/manager/entity/po/KeyPo.java

@@ -0,0 +1,31 @@
+package com.caimei365.manager.entity.po;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.apache.ibatis.type.Alias;
+
+import java.io.Serializable;
+
+/**
+ * KeyPo
+ *
+ * @author Kaick
+ * @date 2023-12-25
+ */
+@Accessors(chain = true)
+@Data
+@Alias("KeyPo")
+public class KeyPo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * key
+     */
+    private String k;
+
+
+    /**
+     * value
+     */
+    private Object v;
+
+}

+ 14 - 0
src/main/java/com/caimei365/manager/service/caimei/HomeService.java

@@ -1,9 +1,13 @@
 package com.caimei365.manager.service.caimei;
 
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+import com.caimei365.manager.entity.po.KeyPo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.Date;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -29,4 +33,14 @@ public interface HomeService {
      * 访问统计
      */
     ResponseJson<Map<String, Object>> getAccessRecordCount(Date startCreateTime, Date endCreateTime);
+
+    /**
+     * 关键词下拉选择项
+     */
+    List<KeyWord> findKeyWordList(String keyword);
+
+    /**
+     * 已上线商品列表
+     */
+    List<CmProductArchive> findProductList(CmProductArchive cmProductArchive);
 }

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

@@ -0,0 +1,40 @@
+package com.caimei365.manager.service.caimei.impl;
+
+
+import com.caimei365.manager.dao.productArchive.CmProductArchiveFileMapper;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveFile;
+import com.caimei365.manager.utils.WaterMarkUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 功能描述:
+ * @auther: Kaick
+ * @date: 2024/1/11 14:27
+ */
+@Slf4j
+@Component
+public class AsyncService {
+    @Resource
+    private CmProductArchiveFileMapper cmProductArchiveFileMapper;
+
+    @Async("taskExecutor")
+    public void setWaterOss(CmProductArchiveFile archiveFile) {
+        String ossName = archiveFile.getOssName();
+        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
+                    .setHtmlUrl("水印文件生成失败,请稍后重试!");
+        } else {
+            productArchiveFile
+                    .setWaterOssName((String) map.get("ossName"))
+                    .setWaterOssUrl((String) map.get("ossUrl"));
+        }
+        cmProductArchiveFileMapper.updateCmProductArchiveFile(productArchiveFile);
+    }
+}

+ 13 - 0
src/main/java/com/caimei365/manager/service/caimei/impl/HomeServiceImpl.java

@@ -4,6 +4,9 @@ import com.caimei.utils.AppUtils;
 import com.caimei365.manager.config.utils.DateUtil;
 import com.caimei365.manager.dao.HomeDao;
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+import com.caimei365.manager.entity.po.KeyPo;
 import com.caimei365.manager.service.caimei.HomeService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -166,6 +169,16 @@ public class HomeServiceImpl implements HomeService {
         return ResponseJson.success(data);
     }
 
+    @Override
+    public List<KeyWord> findKeyWordList(String keyword) {
+        return homeDao.findKeyWordList( keyword);
+    }
+
+    @Override
+    public List<CmProductArchive> findProductList(CmProductArchive cmProductArchive) {
+        return homeDao.findProductList(cmProductArchive);
+    }
+
     public List<Map<String, Object>> setCreateTime(Date startCreateTime, Date endCreateTime) {
         List<Map<String, Object>> list = new ArrayList<>();
         // Calendar获取日期字符串

+ 51 - 0
src/main/java/com/caimei365/manager/service/caimei/productArchive/CmProductArchiveContentService.java

@@ -0,0 +1,51 @@
+package com.caimei365.manager.service.caimei.productArchive;
+
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveContent;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveFile;
+
+import java.util.List;
+
+/**
+ * 商品资料内容Service接口
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+public interface CmProductArchiveContentService
+{
+    /**
+     * 通过对象查询商品资料内容列表
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容集合
+     */
+    List<CmProductArchiveContent> getCmProductArchiveContentList(CmProductArchiveContent cmProductArchiveContent);
+
+    /**
+     * 通过对象查询商品资料内容列表
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容集合
+     */
+    CmProductArchiveContent getCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+
+    /**
+     * 新增商品资料内容
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 结果
+     */
+    int addCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+
+    /**
+     * 删除商品资料内容信息
+     *
+     * @return 结果
+     */
+    int delCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent);
+
+}
+
+

+ 45 - 0
src/main/java/com/caimei365/manager/service/caimei/productArchive/CmProductArchiveService.java

@@ -0,0 +1,45 @@
+package com.caimei365.manager.service.caimei.productArchive;
+
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+
+import java.util.List;
+
+/**
+ * 商品资料库Service接口
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+public interface CmProductArchiveService
+{
+    /**
+     * 通过对象查询商品资料库列表
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库集合
+     */
+    List<CmProductArchive> getCmProductArchiveList(CmProductArchive cmProductArchive);
+
+    /**
+     * 通过对象查询商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库集合
+     */
+    CmProductArchive getCmProductArchive(CmProductArchive cmProductArchive);
+
+
+    /**
+     * 新增商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 结果
+     */
+    int addCmProductArchive(CmProductArchive cmProductArchive);
+
+
+
+}
+
+
+

+ 97 - 0
src/main/java/com/caimei365/manager/service/caimei/productArchive/impl/CmProductArchiveContentServiceImpl.java

@@ -0,0 +1,97 @@
+package com.caimei365.manager.service.caimei.productArchive.impl;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import com.caimei365.manager.dao.productArchive.CmProductArchiveContentMapper;
+import com.caimei365.manager.dao.productArchive.CmProductArchiveFileMapper;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveContent;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchiveFile;
+import com.caimei365.manager.service.caimei.impl.AsyncService;
+import com.caimei365.manager.service.caimei.productArchive.CmProductArchiveContentService;
+import com.caimei365.manager.utils.WaterMarkUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+
+import javax.annotation.Resource;
+
+/**
+ * 商品资料内容Service业务层处理
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Service
+public class CmProductArchiveContentServiceImpl implements CmProductArchiveContentService {
+    @Resource
+    private CmProductArchiveContentMapper cmProductArchiveContentMapper;
+    @Resource
+    private CmProductArchiveFileMapper cmProductArchiveFileMapper;
+    @Resource
+    private AsyncService asyncService;
+    /**
+     * 通过对象查询商品资料内容列表
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容
+     */
+    @Override
+    public List<CmProductArchiveContent> getCmProductArchiveContentList(CmProductArchiveContent cmProductArchiveContent) {
+        return cmProductArchiveContentMapper.getCmProductArchiveContentList(cmProductArchiveContent);
+    }
+
+    /**
+     * 通过对象查询商品资料内容
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 商品资料内容
+     */
+    @Override
+    public CmProductArchiveContent getCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent) {
+        CmProductArchiveContent byCmProductArchiveContent = cmProductArchiveContentMapper.getByCmProductArchiveContent(cmProductArchiveContent);
+        if (byCmProductArchiveContent != null) {
+            byCmProductArchiveContent.setArchiveFiles(cmProductArchiveFileMapper.getCmProductArchiveFileList(new CmProductArchiveFile().setArchiveContentId(Integer.valueOf(byCmProductArchiveContent.getId()))));
+        }
+        return byCmProductArchiveContent;
+    }
+
+
+    /**
+     * 新增商品资料内容
+     *
+     * @param cmProductArchiveContent 商品资料内容
+     * @return 结果
+     */
+    @Override
+    public int addCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent) {
+        if (StringUtils.isBlank(cmProductArchiveContent.getId())) {
+            cmProductArchiveContent.setAddTime(new Date());
+            cmProductArchiveContentMapper.addCmProductArchiveContent(cmProductArchiveContent);
+        } else {
+            cmProductArchiveContentMapper.updateCmProductArchiveContent(cmProductArchiveContent);
+            cmProductArchiveFileMapper.delCmProductArchiveFile(new CmProductArchiveFile().setArchiveContentId(Integer.valueOf(cmProductArchiveContent.getId())));
+        }
+        if (StringUtils.equals("5", cmProductArchiveContent.getType()) ||
+                StringUtils.equals("6", cmProductArchiveContent.getType())) {
+            return 1;
+        }
+        for (CmProductArchiveFile archiveFile : cmProductArchiveContent.getArchiveFiles()) {
+            archiveFile.setArchiveContentId(Integer.valueOf(cmProductArchiveContent.getId()));
+            cmProductArchiveFileMapper.addCmProductArchiveFile(archiveFile);
+            asyncService.setWaterOss(archiveFile);
+        }
+        return 1;
+    }
+
+    public int delCmProductArchiveContent(CmProductArchiveContent cmProductArchiveContent) {
+        return cmProductArchiveContentMapper.delCmProductArchiveContent(cmProductArchiveContent);
+    }
+
+
+}
+
+
+

+ 72 - 0
src/main/java/com/caimei365/manager/service/caimei/productArchive/impl/CmProductArchiveServiceImpl.java

@@ -0,0 +1,72 @@
+package com.caimei365.manager.service.caimei.productArchive.impl;
+
+import java.util.Date;
+import java.util.List;
+
+import com.caimei365.manager.dao.productArchive.CmProductArchiveMapper;
+import com.caimei365.manager.entity.caimei.productArchive.CmProductArchive;
+import com.caimei365.manager.service.caimei.productArchive.CmProductArchiveService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+
+import javax.annotation.Resource;
+
+/**
+ * 商品资料库Service业务层处理
+ *
+ * @author Kaick
+ * @date 2023-12-22
+ */
+@Service
+public class CmProductArchiveServiceImpl implements CmProductArchiveService
+{
+    @Resource
+    private CmProductArchiveMapper cmProductArchiveMapper;
+
+    /**
+     * 通过对象查询商品资料库列表
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库
+     */
+    @Override
+    public List<CmProductArchive> getCmProductArchiveList(CmProductArchive cmProductArchive)
+    {
+        return cmProductArchiveMapper.getCmProductArchiveList(cmProductArchive);
+    }
+    /**
+     * 通过对象查询商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 商品资料库
+     */
+    @Override
+    public CmProductArchive getCmProductArchive(CmProductArchive cmProductArchive)
+    {
+        return cmProductArchiveMapper.getByCmProductArchive(cmProductArchive);
+    }
+
+
+    /**
+     * 新增商品资料库
+     *
+     * @param cmProductArchive 商品资料库
+     * @return 结果
+     */
+    @Override
+    public int addCmProductArchive(CmProductArchive cmProductArchive) {
+        if (StringUtils.isBlank(cmProductArchive.getId())) {
+            cmProductArchive.setAddTime(new Date());
+            return cmProductArchiveMapper.addCmProductArchive(cmProductArchive);
+        } else {
+            return cmProductArchiveMapper.updateCmProductArchive(cmProductArchive);
+        }
+    }
+
+
+
+}
+
+
+

+ 1 - 3
src/main/java/com/caimei365/manager/service/caimei/providers/impl/CmProvidersContractServiceImpl.java

@@ -5,7 +5,6 @@ import java.io.IOException;
 import java.net.URL;
 import java.util.Date;
 import java.util.List;
-import java.util.NoSuchElementException;
 
 import com.caimei365.manager.FastDFS.FastDFSClient;
 import com.caimei365.manager.dao.CmRelatedImageMapper;
@@ -15,11 +14,10 @@ import com.caimei365.manager.entity.caimei.CmRelatedImage;
 import com.caimei365.manager.entity.caimei.providers.CmProviders;
 import com.caimei365.manager.entity.caimei.providers.CmProvidersContract;
 import com.caimei365.manager.service.caimei.providers.CmProvidersContractService;
-import com.caimei365.manager.service.caimei.providers.utils.ImageUtils;
+import com.caimei365.manager.utils.ImageUtils;
 import com.caimei365.manager.service.caimei.providers.utils.ProvidersTemplate;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
 import javax.annotation.Resource;
 import javax.imageio.ImageIO;

+ 1 - 9
src/main/java/com/caimei365/manager/service/caimei/providers/impl/CmProvidersServiceImpl.java

@@ -1,12 +1,8 @@
 package com.caimei365.manager.service.caimei.providers.impl;
 
-import java.awt.image.BufferedImage;
 import java.io.File;
-import java.io.IOException;
-import java.net.URL;
 import java.util.Date;
 import java.util.List;
-import java.util.NoSuchElementException;
 
 import com.caimei365.manager.FastDFS.FastDFSClient;
 import com.caimei365.manager.config.utils.DateUtil;
@@ -21,17 +17,13 @@ import com.caimei365.manager.entity.caimei.providers.CmProvidersContract;
 import com.caimei365.manager.entity.po.UploadFilePo;
 import com.caimei365.manager.service.caimei.providers.CmProvidersContractService;
 import com.caimei365.manager.service.caimei.providers.CmProvidersService;
-import com.caimei365.manager.service.caimei.providers.utils.ImageUtils;
-import com.caimei365.manager.service.caimei.providers.utils.ProvidersTemplate;
+import com.caimei365.manager.utils.ImageUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.poi.ss.formula.functions.T;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.transaction.interceptor.TransactionAspectSupport;
 
 import javax.annotation.Resource;
-import javax.imageio.ImageIO;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 

+ 1 - 15
src/main/java/com/caimei365/manager/service/caimei/providers/utils/ProvidersTemplate.java

@@ -1,26 +1,12 @@
 package com.caimei365.manager.service.caimei.providers.utils;
 
-import com.caimei365.manager.FastDFS.FastDFSClient;
 import com.caimei365.manager.config.utils.DateUtil;
-import com.caimei365.manager.dao.providers.CmProvidersMapper;
-import com.caimei365.manager.entity.po.UploadFilePo;
-import com.caimei365.manager.utils.FileIOUtils;
-import com.google.zxing.BarcodeFormat;
-import com.google.zxing.EncodeHintType;
-import com.google.zxing.MultiFormatWriter;
-import com.google.zxing.common.BitMatrix;
+import com.caimei365.manager.utils.ImageUtils;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.stereotype.Component;
 
-import javax.annotation.Resource;
-import javax.imageio.ImageIO;
-import javax.xml.crypto.Data;
 import java.awt.*;
 import java.awt.image.BufferedImage;
-import java.io.*;
-import java.net.URL;
 import java.util.*;
-import java.util.List;
 
 /**
  * @author :Kaick

+ 80 - 0
src/main/java/com/caimei365/manager/utils/Base64Util.java

@@ -0,0 +1,80 @@
+package com.caimei365.manager.utils;
+
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Decoder;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class Base64Util implements MultipartFile {
+    private final byte[] imgContent;
+    private final String header;
+
+    public Base64Util(byte[] imgContent, String header) {
+        this.imgContent = imgContent;
+        this.header = header.split(";")[0];
+    }
+
+    @Override
+    public String getName() {
+        return System.currentTimeMillis() + Math.random() + "." + header.split("/")[1];
+    }
+
+    @Override
+    public String getOriginalFilename() {
+        return System.currentTimeMillis() + (int) Math.random() * 10000 + "." + header.split("/")[1];
+    }
+
+    @Override
+    public String getContentType() {
+        return header.split(":")[1];
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return imgContent == null || imgContent.length == 0;
+    }
+
+    @Override
+    public long getSize() {
+        return imgContent.length;
+    }
+
+    @Override
+    public byte[] getBytes() throws IOException {
+        return imgContent;
+    }
+
+    @Override
+    public ByteArrayInputStream getInputStream() throws IOException {
+        return new ByteArrayInputStream(imgContent);
+    }
+
+    @Override
+    public void transferTo(File dest) throws IOException, IllegalStateException {
+        new FileOutputStream(dest).write(imgContent);
+    }
+
+    public static MultipartFile base64ToMultipart(String base64) {
+        try {
+            String[] baseStrs = base64.split(",");
+
+            BASE64Decoder decoder = new BASE64Decoder();
+            byte[] b = new byte[0];
+            b = decoder.decodeBuffer(baseStrs[1]);
+
+            for (int i = 0; i < b.length; ++i) {
+                if (b[i] < 0) {
+                    b[i] += 256;
+                }
+            }
+            return new Base64Util(b, baseStrs[0]);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+}

+ 60 - 0
src/main/java/com/caimei365/manager/utils/CmdExecuter.java

@@ -0,0 +1,60 @@
+package com.caimei365.manager.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+
+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 {
+            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) {
+                log.info("第" + lineNumber + "行:" + line);
+                lineNumber = lineNumber + 1;
+                returnStringList.add(FFMPEG.dealString(line));
+            }
+            String info = "";
+            for (int i = returnStringList.size() - 1; i >= 0; i--) {
+                if (null != returnStringList.get(i) && returnStringList.get(i).startsWith("frame=")) {
+                    info = returnStringList.get(i);
+                    break;
+                }
+            }
+            if (null != info) {
+                converted_time = info.split("time=")[1].split("bitrate=")[0].trim();
+            }
+        } catch (IndexOutOfBoundsException ex) {
+            converted_time = null;
+            log.error("CmdExecuter异常:"+ex);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("CmdExecuter异常:"+e);
+        } finally {
+            try {
+                int resultCode = proc.waitFor();
+                log.info("resultCode:"+resultCode);
+                stdout.close();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return converted_time;
+    }
+}

+ 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();
+        }
+    }
+
+}

+ 251 - 0
src/main/java/com/caimei365/manager/utils/FFMPEG.java

@@ -0,0 +1,251 @@
+package com.caimei365.manager.utils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+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/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";
+            logoPath = "D\\\\:logo.png";
+        }
+    }
+
+    /**
+     * 日志对象
+     */
+    private static Logger logger = LoggerFactory.getLogger(FFMPEG.class);
+
+    public static String dealString(String str) {
+        Matcher m = Pattern.compile("^frame=.*").matcher(str);
+        String msg = "";
+        while (m.find()) {
+            msg = m.group();
+        }
+        return msg;
+    }
+
+    /**
+     * 如果是数字就是成功的时间(秒数)
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNumeric(String str) {
+        Pattern pattern = Pattern.compile("[0-9]*");
+        Matcher isNum = pattern.matcher(str);
+        if (!isNum.matches()) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 如果返回不是null的值就是成功(值为转换用时单位:秒)
+     *
+     * @param instr
+     * @return
+     */
+    public static String returnSecond(String instr) {
+        String returnValue = null;
+        if (null != instr) {
+            String[] a = instr.split("\\.");
+            String[] b = a[0].split(":");
+            int returnNumber = 0;
+            if (null != instr && b[0].length() != 0) {
+                returnNumber = Integer.valueOf(b[0]) * 60 * 60 + Integer.valueOf(b[1]) * 60 + Integer.valueOf(b[2]);
+                returnValue = String.valueOf(returnNumber);
+            } else {
+                returnValue = null;
+            }
+        }
+        return returnValue;
+    }
+
+    /**
+     * 获取视频格式(转码前的格式和转码后的格式都可以调用)
+     *
+     * @param outputPath
+     * @return
+     */
+    public static String returnVideoFormat(String outputPath) {
+        return outputPath.substring(outputPath.lastIndexOf(".") + 1);
+    }
+
+    /**
+     * @ HashMap<String,String> dto 参数传递对象<br>
+     * dto中包含的参数<br>
+     * (必填)1.ffmpeg_path:ffmpeg执行文件地址,如 d:\\ffmpeg\\ffmpeg.exe Linux下直接调用ffmpeg命令(当然你事先已经有这个程序了)<br>
+     * (必填)2.input_path:原视频路径<br>
+     * (必填)3.video_converted_path:转换后视频输出路径<br>
+     * (可选)4.screen_size:视频尺寸 长度乘宽度 乘号用英文小写"x"如 512x480<br>
+     * (可选)5.logo:水印地址(其实在ffmpeg中有一个专门的watermark参数,logo跟它有何不同,我还没看,不过对我来说效果一样 貌似需要png图片才行)<br>
+     * (可选,如果填写必须有logo才行,默认为0)6.xaxis:水印logo的横坐标(只有logo参数为一个正确路径才行) 比如0<br>
+     * (可选,如果填写必须有logo才行,默认为0)6.yaxis:水印logo的纵坐标(只有logo参数为一个正确路径才行) 比如0<br>
+     * (可选)vb:视频比特率,传入一个数值,单位在程序里面拼接了k
+     * (可选)ab:音频比特率,传入一个数值,单位在程序里面拼接了k
+     */
+    public String videoTransfer(HashMap<String, String> dto) {
+        // String ffmpeg_path,String input_path,String video_converted_path,String logo,String screen_size,String xaxis,String yaxis,String vb,String ab
+        List<String> cmd = new ArrayList<String>();
+        cmd.add(dto.get("ffmpeg_path"));
+        cmd.add("-y");
+        cmd.add("-i");
+        cmd.add(dto.get("input_path"));
+        if (null != dto.get("screen_size")) {
+            cmd.add("-s");
+            cmd.add(dto.get("screen_size"));
+        }
+        int markHeight= 50;
+        int markWidth = 50;
+        if (!org.springframework.util.StringUtils.isEmpty(dto.get("width"))) {
+            markHeight = (int) (Integer.parseInt(dto.get("width")) * 0.1);
+            markWidth = markHeight;
+        }
+        if (null != dto.get("logo")) {
+            String logo = dto.get("logo");
+            //-vf:视频旋转
+            cmd.add("-vf");
+            String xaxis = dto.get("xaxis");
+            String yaxis = dto.get("yaxis");
+            xaxis = xaxis != null && !"".equals(xaxis) ? xaxis : "0";
+            yaxis = yaxis != null && !"".equals(yaxis) ? yaxis : "0";
+            String logoString = "movie=" + logo + "[logo],[in][logo]overlay=x=" + xaxis + ":y=" + yaxis + "[out]";
+            cmd.add(logoString);
+        }
+        cmd.add("-strict");
+        cmd.add("-2");
+        if (null != dto.get("vb") && !dto.get("vb").equals("")) {
+            cmd.add("-vb");
+            cmd.add(dto.get("vb") + "k");
+        }
+        if (null != dto.get("ab") && !dto.get("ab").equals("")) {
+            cmd.add("-ab");
+            cmd.add(dto.get("ab") + "k");
+        }
+        cmd.add("-q:v");
+        cmd.add("4");
+        // h264转码,可以在video标签内播放
+        cmd.add("-vcodec");
+        cmd.add("libx264");
+        cmd.add(dto.get("video_converted_path"));
+        String converted_time = CmdExecuter.exec(cmd);
+        //获取转换时间
+        return returnSecond(converted_time);
+    }
+
+    public static Map<String, Object> setVideoWaterMark(String fileUrl, String filePath) {
+        HashMap<String, String> dto = new HashMap<String, String>();
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        filePath = filePath + uuid + ".mp4";
+        //ffmpeg程序路径
+        dto.put("ffmpeg_path", ffmepgPath);
+        logger.info("ffmepg程序路径:" + ffmepgPath);
+        //视频输入路径
+        dto.put("input_path", fileUrl);
+        logger.info("输入文件路径:" + fileUrl);
+        //视频输出路径
+        dto.put("video_converted_path", filePath);
+        // 白名单
+        dto.put("whitelist", "file,http,https,rtp,udp,tcp,tls");
+        //可选(注意windows下面的logo地址前面要写4个反斜杠,如果用浏览器里面调用servlet并传参只用两个,如 d:\\:/ffmpeg/input/logo.png)
+        dto.put("logo", logoPath);
+        logger.info("视频水印图片路径:" + logoPath);
+        Map<String, String> videoSize = new FFMPEG().getVideoSize(dto);
+        //长度
+        dto.put("height", videoSize.get("height"));
+        //宽度
+        dto.put("width", videoSize.get("width"));
+        //logo X坐标
+        dto.put("xaxis", "30");
+        //logo Y坐标
+        dto.put("yaxis", "30");
+        String secondsString = new FFMPEG().videoTransfer(dto);
+        logger.info("转换共用:" + secondsString + "秒");
+        if (StringUtils.isBlank(secondsString)) {
+            throw new RuntimeException("视频添加水印异常!");
+        }
+        return OSSUtils.fileUpload(new File(filePath));
+    }
+
+    /**
+     * 获取视频长宽
+     * @param dto
+     * @return
+     */
+    public Map<String,String> getVideoSize(HashMap<String, String> dto) {
+        Map<String, String> map = new HashMap<>(2);
+        List<String> cmd = new ArrayList<String>();
+        cmd.add(dto.get("ffmpeg_path"));
+        cmd.add("-protocol_whitelist");
+        cmd.add(dto.get("whitelist"));
+        cmd.add("-i");
+        cmd.add(dto.get("input_path"));
+        String height = "";
+        String width = "";
+        try {
+            ProcessBuilder builder = new ProcessBuilder();
+            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()));
+            StringBuffer sb = new StringBuffer();
+            String line = "";
+            while ((line = br.readLine()) != null) {
+                sb.append(line);
+            }
+            br.close();
+            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("\\),");
+            String sb1 = "";
+            String sizeStr = "";
+            if (split.length > 3) {
+                sb1 = split[2];
+            }
+            String[] split1 = sb1.split(",");
+            if (split1.length > 0) {
+                sizeStr = split1[0];
+            }
+            String[] xes = sizeStr.split("x");
+            if (xes.length > 1) {
+                height = xes[0].trim().split(" ")[0];
+                width = xes[1].trim().split(" ")[0];
+            }
+        } catch (Exception e) {
+            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);
+        return map;
+    }
+}

+ 2 - 8
src/main/java/com/caimei365/manager/service/caimei/providers/utils/ImageUtils.java → src/main/java/com/caimei365/manager/utils/ImageUtils.java

@@ -1,21 +1,15 @@
-package com.caimei365.manager.service.caimei.providers.utils;
+package com.caimei365.manager.utils;
 
 import com.caimei365.manager.FastDFS.FastDFSClient;
 import com.caimei365.manager.entity.po.UploadFilePo;
-import com.caimei365.manager.utils.FileIOUtils;
-import com.github.tobato.fastdfs.service.FastFileStorageClient;
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.EncodeHintType;
 import com.google.zxing.MultiFormatWriter;
-import com.google.zxing.WriterException;
 import com.google.zxing.common.BitMatrix;
-import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.Resource;
 import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.image.BufferedImage;
@@ -121,7 +115,7 @@ public class ImageUtils {
             return FastDFSClient.saveFile(new ByteArrayInputStream(os.toByteArray()));
         } catch (Exception e) {
             e.printStackTrace();
-            log.error("生成图片异常!");
+            log.error("生成图片异常!>>>>>>>>>>>>>"+e);
             return null;
         }
     }

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

@@ -6,30 +6,36 @@ import com.aliyun.oss.model.GetObjectRequest;
 import com.aliyun.oss.model.ObjectMetadata;
 import com.aliyun.oss.model.UploadFileRequest;
 import com.caimei365.manager.config.thinkgem.Global;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.env.Environment;
 import org.springframework.stereotype.Component;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.io.File;
 import java.io.IOException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.UUID;
-
+@Slf4j
 @Component
 public class OSSUtils {
 
-    @Resource private Environment environment;
+    @Resource
+    private Environment environment;
 
-    private String endpoint; // = "https://oss-cn-shenzhen.aliyuncs.com";
-    private String accessKeyId; // = "LTAI4GBL3o4YkWnbKYgf2Xia";
-    private String accessKeySecret;//  = "dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK";
-    private String privateBucket; // = "caimei-oss";
-    private String config; // = Global.getConfig("cm.config");
+    private static String endpoint; // = "https://oss-cn-shenzhen.aliyuncs.com";
+    private static String accessKeyId; // = "LTAI4GBL3o4YkWnbKYgf2Xia";
+    private static String accessKeySecret;//  = "dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK";
+    private static String privateBucket; // = "caimei-oss";
+    private static String config; // = Global.getConfig("cm.config");
 
+    @PostConstruct
     public void setValue() {
         endpoint = environment.getProperty("aliyun.endpoint");
         accessKeyId = environment.getProperty("aliyun.accessKeyId");
@@ -38,14 +44,13 @@ public class OSSUtils {
         config = environment.getProperty("cm.config");
     }
 
-    public  String ossUpload(String fileName, File file, String contentType) {
-        setValue();
+    public static String ossUpload(String fileName, File file, String contentType) {
         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();
@@ -76,12 +81,34 @@ public class OSSUtils {
         return url;
     }
 
+    public static Map<String, Object> fileUpload(File file) {
+        Map<String, Object> map = new HashMap<>();
+        String fileAllName = file.getName();
+        String contentType = OSSUtils.getContentType(fileAllName);
+        try {
+            //上传oss
+            String url = OSSUtils.ossUpload(fileAllName, file, contentType);
+            //删除本地文件
+            OSSUtils.deleteFile(file);
+            map.put("success", true);
+            map.put("msg", "操作成功");
+            map.put("ossUrl", url);
+            map.put("ossName", fileAllName);
+            log.info("上传成功!!!");
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.put("success", false);
+            map.put("msg", "操作失败");
+            log.info("上传异常!!!");
+        }
+        return map;
+    }
+
 
     /**
      * 通过文件名判断并获取OSS服务文件上传时文件的contentType
      */
-    public String getContentType(String fileName) {
-        setValue();
+    public static String getContentType(String fileName) {
         String fileExtension = fileName.substring(fileName.lastIndexOf("."));
         if (".bmp".equalsIgnoreCase(fileExtension)) {
             return "image/bmp";
@@ -116,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)) {
@@ -134,8 +161,7 @@ public class OSSUtils {
         return "text/html";
     }
 
-    public void deleteFile(File... files) {
-        setValue();
+    public static void deleteFile(File... files) {
         for (File file : files) {
             //logger.info("File:[{}]",file.getAbsolutePath());
             if (file.exists()) {
@@ -144,8 +170,7 @@ public class OSSUtils {
         }
     }
 
-    public File ossUpload(MultipartFile file) throws IOException {
-        setValue();
+    public static File ossUpload(MultipartFile file) throws IOException {
         // 获取文件名
         String fileName = file.getOriginalFilename();
         // 获取文件后缀
@@ -163,8 +188,7 @@ public class OSSUtils {
      *
      * @param fileName 文件名称
      */
-    public String getOssUrl(String fileName) {
-        setValue();
+    public static String getOssUrl(String fileName) {
         OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         // 设置URL过期时间为1个小时
         Date expiration = new Date(new Date().getTime() + 3600L * 1000);
@@ -181,12 +205,12 @@ public class OSSUtils {
 
     /**
      * 生成商品资料库链接
+     *
      * @param ossName
      * @param uploadTime
      * @return
      */
-    public String generateProductArchiveUrl(String ossName, Date uploadTime) {
-        setValue();
+    public static String generateProductArchiveUrl(String ossName, Date uploadTime) {
         OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         // 设置URL过期时间为1个小时
         Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000);
@@ -212,8 +236,7 @@ public class OSSUtils {
      *
      * @param fileName 文件名称或文件夹名称
      */
-    public void deleteSingleFile(String fileName) {
-        setValue();
+    public static void deleteSingleFile(String fileName) {
         // 创建OSSClient实例。
         OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         // 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。
@@ -236,8 +259,7 @@ public class OSSUtils {
     /**
      * oss单个文件下载
      */
-    public void downFile(String ossName, String fileName) {
-        setValue();
+    public static void downFile(String ossName, String fileName) {
         // 创建OSSClient实例。
         OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
         // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。

+ 141 - 0
src/main/java/com/caimei365/manager/utils/PdfUtil.java

@@ -0,0 +1,141 @@
+package com.caimei365.manager.utils;
+
+import com.aspose.cells.License;
+import com.aspose.cells.PdfSaveOptions;
+import com.aspose.cells.Workbook;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.FileOutputStream;
+import java.io.InputStream;
+@Slf4j
+public class PdfUtil {
+
+    /**
+     * excel 转 pdf
+     *
+     * @param excelFilePath excel文件路径
+     */
+    public static void excel2pdf(String excelFilePath) {
+        excel2pdf(excelFilePath, null, null);
+    }
+
+    /**
+     * excel 转 pdf
+     *
+     * @param excelFilePath excel文件路径
+     * @param convertSheets 需要转换的sheet
+     */
+    public static void excel2pdf(String excelFilePath, int[] convertSheets) {
+        excel2pdf(excelFilePath, null, convertSheets);
+    }
+
+    /**
+     * excel 转 pdf
+     *
+     * @param excelFilePath excel文件路径
+     * @param pdfFilePath   pdf文件路径
+     */
+    public static void excel2pdf(String excelFilePath, String pdfFilePath) {
+        excel2pdf(excelFilePath, pdfFilePath, null);
+    }
+
+    /**
+     * excel 转 pdf
+     *
+     * @param excelFilePath excel文件路径
+     * @param pdfFilePath   pdf文件路径
+     * @param convertSheets 需要转换的sheet
+     */
+    public static void excel2pdf(String excelFilePath, String pdfFilePath, int[] convertSheets) {
+        try {
+            pdfFilePath = pdfFilePath == null ? getPdfFilePath(excelFilePath) : pdfFilePath;
+            // 验证 License
+            getLicense();
+            Workbook wb = new Workbook(excelFilePath);
+            FileOutputStream fileOS = new FileOutputStream(pdfFilePath);
+            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
+            pdfSaveOptions.setOnePagePerSheet(true);
+            if (null != convertSheets) {
+                printSheetPage(wb, convertSheets);
+            }
+            wb.save(fileOS, pdfSaveOptions);
+            fileOS.flush();
+            fileOS.close();
+            log.error("convert success");
+        } catch (Exception e) {
+            log.error("convert failed");
+            e.printStackTrace();
+        }
+    }
+    /**
+     * excel 转 pdf
+     *
+     * @param excelFilePathStream excel文件Stream
+     * @param pdfFilePath   pdf文件路径
+     * @param convertSheets 需要转换的sheet
+     */
+    public static void excel2pdf(InputStream excelFilePathStream, String pdfFilePath, int[] convertSheets) {
+        try {
+            // 验证 License
+            getLicense();
+            Workbook wb = new Workbook(excelFilePathStream);
+            FileOutputStream fileOS = new FileOutputStream(pdfFilePath);
+            PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();
+            pdfSaveOptions.setOnePagePerSheet(true);
+            if (null != convertSheets) {
+                printSheetPage(wb, convertSheets);
+            }
+            wb.save(fileOS, pdfSaveOptions);
+            fileOS.flush();
+            fileOS.close();
+            log.info("文件转换成功!");
+        } catch (Exception e) {
+            log.error("文件转换失败!");
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 获取 生成的 pdf 文件路径,默认与源文件同一目录
+     *
+     * @param excelFilePath excel文件
+     * @return 生成的 pdf 文件
+     */
+    private static String getPdfFilePath(String excelFilePath) {
+        return excelFilePath.split(".")[0] + ".pdf";
+    }
+
+    /**
+     * 获取 license 去除水印
+     * 若不验证则转化出的pdf文档会有水印产生
+     */
+    private static void getLicense() {
+        String licenseFilePath = "excel-license.xml";
+        try {
+            InputStream is = PdfUtil.class.getClassLoader().getResourceAsStream(licenseFilePath);
+            License license = new License();
+            license.setLicense(is);
+        } catch (Exception e) {
+            log.error("license verify failed");
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 隐藏workbook中不需要的sheet页。
+     *
+     * @param sheets 显示页的sheet数组
+     */
+    private static void printSheetPage(Workbook wb, int[] sheets) {
+        for (int i = 1; i < wb.getWorksheets().getCount(); i++) {
+            wb.getWorksheets().get(i).setVisible(false);
+        }
+        if (null == sheets || sheets.length == 0) {
+            wb.getWorksheets().get(0).setVisible(true);
+        } else {
+            for (int i = 0; i < sheets.length; i++) {
+                wb.getWorksheets().get(i).setVisible(true);
+            }
+        }
+    }
+}

+ 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();
+        }
+    }
+}

+ 266 - 0
src/main/java/com/caimei365/manager/utils/WaterMarkUtils.java

@@ -0,0 +1,266 @@
+package com.caimei365.manager.utils;
+
+import cn.hutool.core.io.FileTypeUtil;
+import com.caimei365.manager.config.utils.UploadImageUtils;
+import com.documents4j.api.DocumentType;
+import com.documents4j.api.IConverter;
+import com.documents4j.job.LocalConverter;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.Element;
+import com.itextpdf.text.pdf.*;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+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.blend.BlendMode;
+import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
+import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
+import org.apache.pdfbox.rendering.PDFRenderer;
+import org.apache.pdfbox.util.Matrix;
+import org.apache.poi.sl.usermodel.PictureData;
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
+import org.apache.poi.xslf.usermodel.XMLSlideShow;
+import org.apache.poi.xslf.usermodel.XSLFPictureShape;
+import org.apache.poi.xslf.usermodel.XSLFSlide;
+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.dom4j.DocumentException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+import sun.misc.BASE64Encoder;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+import java.util.List;
+
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2021/9/18
+ */
+@Component
+public class WaterMarkUtils {
+    @Resource
+    private Environment environment;
+    private static String config;
+    private static String outPath = "/mnt/newdatadrive/data/runtime/jar-instance/manager-api/tempImage/";
+    private static String logoPath = "/mnt/newdatadrive/data/runtime/jar-instance/manager-api/logo/";
+    private final static List<String> imageTypes = Arrays.asList("xbm", "tif", "pjp", "svgz", "jpg", "jpeg", "ico", "tiff", "gif", "svg", "jfif", "webp", "png", "bmp", "pjpeg", "avif");
+    private final static List<String> videoTypes = Arrays.asList("asx", "asf", "mpg", "wmv", "3gp", "mp4", "mov", "avi", "flv");
+
+    @PostConstruct
+    public void setValue() {
+        config = environment.getProperty("cm.config");
+        if ("dev".equals(config)) {
+            outPath = "D:/";
+            logoPath = "D:/";
+        }
+    }
+
+    /**
+     * 日志对象
+     */
+    private static Logger log = LoggerFactory.getLogger(WaterMarkUtils.class);
+    // 水印透明度
+    private static float alpha = 0.15f;
+    // 水印之间的间隔
+    private static final int XMOVE = 150;
+    // 水印之间的间隔
+    private static final int YMOVE = 150;
+
+
+    public static Map<String, Object> addWaterMark(String fileType, String fileUrl) {
+        try {
+            if (imageTypes.contains(fileType)) {
+                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")||fileType.contains("ppt")) {
+                return setWaterMarkPDF(fileUrl, fileType);
+            } else {
+                throw new NullPointerException("文件格式不正确!");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("文件添加水印异常!>>>>>>>>>文件后缀:{}>>>>>>>文件地址:{}", fileType, fileUrl);
+            log.error("添加水印异常:" + e);
+            return null;
+        }
+    }
+
+
+    /**
+     * 生成水印PDF
+     *
+     * @return
+     */
+    private static Map<String, Object> setWaterMarkPDF(String fileUrl, String fileType) throws Exception {
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = outPath + uuid + ".pdf";
+        URL url = new URL(fileUrl);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        if (200 != conn.getResponseCode()) {
+            throw new RuntimeException("请求失败了: http response code: " + conn.getResponseCode());
+        }
+        PDDocument doc = null;
+        if (fileType.contains("pdf")) {
+            doc = PDDocument.load(url.openStream());
+        } else if (fileType.contains("doc")) {
+            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();
+        gs.setNonStrokingAlphaConstant(0.15F);// 设置透明度
+        gs.setAlphaSourceFlag(true);
+        gs.setBlendMode(BlendMode.NORMAL);
+        for (int i = 0; i < doc.getNumberOfPages(); i++) {
+            PDPage page = doc.getPage(i);
+            PDPageContentStream contentStream = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
+            contentStream.setGraphicsStateParameters(gs);
+            int height = (int) page.getMediaBox().getHeight();
+            int width = (int) page.getMediaBox().getWidth();
+            int size = width > height ? width : height;
+            // 根据纸张大小多次添加, 水印文字成30度角倾斜
+            for (int x = 0; x < size; x += XMOVE) {
+                for (int y = -size / 2; y < size; y += YMOVE) {
+                    Matrix matrix = new Matrix();
+                    // 旋转
+                    matrix.rotate(Math.toRadians(30));
+                    // 先移位
+                    matrix.translate(x, y);
+                    // 修改尺寸(必须在旋转后面,否则会变形)
+                    matrix.scale(114, 38);
+                    contentStream.drawImage(pdImage, matrix);
+                }
+            }
+            contentStream.close();
+        }
+        doc.save(filePath);
+        doc.close();
+        return OSSUtils.fileUpload(new File(filePath));
+    }
+
+
+    private static Map<String, Object> setWaterMarkPPT(String fileUrl) {
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = outPath + uuid + ".pptx";
+        try (FileOutputStream out = new FileOutputStream(filePath)) {
+            URL url = new URL(fileUrl);
+            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+            if (200 != conn.getResponseCode()) {
+                throw new RuntimeException("请求失败了: http response code: " + conn.getResponseCode());
+            }
+            XMLSlideShow ppt = new XMLSlideShow(url.openStream());
+            BufferedImage waterMarkImageBig = createWaterMarkImageBig(1282, 723);
+            for (XSLFSlide slide : ppt.getSlides()) {
+                XSLFPictureShape slidePicture = slide.createPicture(ppt.addPicture(ImageUtils.bufImg2Bytes(waterMarkImageBig), PictureData.PictureType.PNG));
+                slidePicture.setAnchor(slidePicture.getAnchor());
+            }
+            ppt.write(out);
+            ppt.close();
+            return OSSUtils.fileUpload(new File(filePath));
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("PPT添加水印异常:" + e);
+            return null;
+        }
+    }
+
+    /**
+     * 生成水印图片
+     *
+     * @return
+     */
+    private static Map<String, Object> setWaterMarkImage(String fileUrl) throws Exception {
+        URL url = new URL(fileUrl);
+        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
+        if (200 != conn.getResponseCode()) {
+            throw new RuntimeException("请求失败了: http response code: " + conn.getResponseCode());
+        }
+        BufferedImage bufferedImage = ImageIO.read(url);
+        ArrayList list = new ArrayList();
+        //合成图片Map
+        HashMap<String, Object> imageFileMap = new HashMap<>();
+        imageFileMap.put("type", 1);
+        imageFileMap.put("image", createWaterMarkImageBig(bufferedImage.getWidth(), bufferedImage.getHeight()));
+        imageFileMap.put("x", 0);
+        imageFileMap.put("y", 0);
+        list.add(imageFileMap);
+        Map<String, Object> map = new HashMap<>();
+        map.put("ossUrl", ImageUtils.imageTemplate(bufferedImage, list));
+        return map;
+    }
+
+    /**
+     * 生成水印图片背景
+     *
+     * @return
+     */
+    public static BufferedImage createWaterMarkImageBig(int width, int height) throws Exception {
+        BufferedImage bufferedImage = ImageIO.read(new File(logoPath + "logo.png"));
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);// 获取bufferedImage对象
+        Graphics2D g2d = image.createGraphics();
+        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+        g2d.rotate(Math.toRadians(-30));
+        int size = width > height ? width : height;
+        for (int x = -size / 2; x < size; x += XMOVE) {
+            for (int y = 0; y < size; y += YMOVE) {
+                g2d.drawImage(bufferedImage, x, y, 114, 38, null);
+            }
+        }
+        // 释放资源
+        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);
+    }
+}

+ 31 - 0
src/main/java/com/caimei365/manager/utils/formDataUtils.java

@@ -6,6 +6,7 @@ import com.caimei365.manager.FastDFS.FastDFSClient;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.multipart.MultipartFile;
@@ -54,6 +55,36 @@ public class formDataUtils {
         }
         return map;
     }
+    @ResponseBody
+    @PostMapping("/oss/MultiPictareaddData")
+    public Map<String, Object> fileUpload(MultipartFile multipartFile) {
+        Map<String, Object> map = new HashMap<>();
+        String fileAllName = multipartFile.getOriginalFilename();
+        String fileType = fileAllName.substring(fileAllName.lastIndexOf(".") + 1);
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = uuid + "." + fileType;
+        String contentType = OSSUtils.getContentType(fileAllName);
+        try {
+            //保存本地
+            File file = OSSUtils.ossUpload(multipartFile);
+            log.info("默认路径>>>" + file.getAbsolutePath());
+            //上传oss
+            String url = OSSUtils.ossUpload(filePath, file, contentType);
+            //删除本地文件
+            OSSUtils.deleteFile(file);
+            map.put("success", true);
+            map.put("msg", "操作成功");
+            map.put("url", url);
+            map.put("fileName", fileAllName);
+            map.put("ossName", filePath);
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.put("success", false);
+            map.put("msg", "操作失败");
+            log.info("上传异常!!!");
+        }
+        return map;
+    }
 
     private String saveFile(HttpServletRequest request, MultipartFile file) throws IOException {
         String originalFilename = file.getOriginalFilename();

+ 15 - 0
src/main/resources/excel-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>

+ 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>

+ 16 - 0
src/main/resources/mapper/CmBehaciorRecordDao.xml

@@ -60,6 +60,8 @@
         cbri.region,
         cbri.label,
         cbri.relevanceShop,
+        cbri.headUserId,
+        cbri.productArchiveId,
         cbri.addTime
         FROM cm_behavior_record_index cbri
         left join user u on u.userId = cbri.userId
@@ -91,6 +93,12 @@
             <if test="spName != null and spName != ''">
                 AND cbri.spName = #{spName}
             </if>
+            <if test="headUserId != null and headUserId != ''">
+                AND cbri.headUserId = #{headUserId}
+            </if>
+            <if test="productArchiveId != null and productArchiveId != ''">
+                AND cbri.productArchiveId = #{productArchiveId}
+            </if>
             <if test="relevanceShop != null and relevanceShop != ''">
                 AND (cbri.relevanceShop like concat('%',#{relevanceShop},'%')
                     <if test="behaviorType == 2">
@@ -146,6 +154,8 @@
         cbrt.accessClient,
         cbrt.region,
         cbrt.label,
+        cbrt.headUserId,
+        cbrt.productArchiveId,
         cbrt.relevanceShop,
         cbrt.addTime
         FROM cm_behavior_record_today cbrt
@@ -177,6 +187,12 @@
             <if test="spName != null and spName != ''">
                 AND cbrt.spName = #{spName}
             </if>
+            <if test="headUserId != null and headUserId != ''">
+                AND cbrt.headUserId = #{headUserId}
+            </if>
+            <if test="productArchiveId != null and productArchiveId != ''">
+                AND cbrt.productArchiveId = #{productArchiveId}
+            </if>
             <if test="relevanceShop != null and relevanceShop != ''">
                 AND cbrt.relevanceShop like concat('%',#{relevanceShop},'%')
             </if>

+ 33 - 1
src/main/resources/mapper/HomeDao.xml

@@ -2,7 +2,8 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.caimei365.manager.dao.HomeDao">
     <select id="countAllUsers" resultType="java.lang.Integer">
-        SELECT IFNULL(COUNT(*), 0) FROM user
+        SELECT IFNULL(COUNT(*), 0)
+        FROM user
     </select>
     <select id="countAllProducts" resultType="java.lang.Integer">
         SELECT IFNULL(COUNT(*), 0)
@@ -152,4 +153,35 @@
         limit 0,10
     </select>
 
+    <select id="findKeyWordList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
+        SELECT cusf.id AS id, cusf.keyword as keyword
+        FROM cm_user_search_frequency cusf
+        WHERE cusf.delStatus = 1
+        <if test="keyword != null  and keyword != ''">and cusf.keyword like concat('%', #{keyword}, '%')</if>
+
+        ORDER BY cusf.frequency DESC, cusf.searchTime DESC
+    </select>
+
+
+    <select id="findProductList" resultType="CmProductArchive">
+        SELECT b.name as shopName,
+        a.name as productName,
+        a.`productID` as productId,
+        a.mainImage as productImage
+        FROM product a
+        LEFT JOIN shop b ON b.shopID = a.shopID
+        left join cm_organize_product_info copi on copi.productId = a.productID
+        left join cm_product_archive cpa on cpa.productId = a.productID
+        WHERE cpa.productId is null and copi.organizeId = 0
+        AND copi.validFlag = 2
+        AND a.productCategory = 1
+        AND a.shopID not in (SELECT s.`value` FROM `sys_dict` s WHERE s.type = 'heheShopID')
+        AND a.productID NOT IN (6060, 6061, 6062, 6063, 6064, 6065, 6066, 6067, 6068, 6069)
+        <if test="productId != null ">and a.productId = #{productId}</if>
+        <if test="productName != null  and productName != ''">and a.name like concat('%', #{productName}, '%')</if>
+        <if test="shopName != null  and shopName != ''">and b.name like concat('%', #{shopName}, '%')</if>
+        group by a.productID
+        order by a.productID desc
+    </select>
+
 </mapper>

+ 1 - 1
src/main/resources/mapper/KeyWordDao.xml

@@ -117,7 +117,7 @@
                             and a.onlineStatus = 2
                             and a.labelIds LIKE CONCAT('%',cusf.id,'%')LIMIT 0,1)
             as cm_baike_product,
-            (SELECT id from  cm_product_archive
+            (SELECT id from  cm_product_archive_content
                             WHERE labelIds LIKE CONCAT('%',cusf.id,'%') LIMIT 0,1)
             as cm_product_archive
         from  cm_user_search_frequency as cusf

+ 200 - 0
src/main/resources/mapper/productArchive/CmProductArchiveContentMapper.xml

@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.caimei365.manager.dao.productArchive.CmProductArchiveContentMapper">
+
+    <resultMap type="CmProductArchiveContent" id="CmProductArchiveContentResult">
+        <result property="id"    column="id"    />
+        <result property="productArchiveId"    column="productArchiveId"    />
+        <result property="title"    column="title"    />
+        <result property="type"    column="type"    />
+        <result property="content"    column="content"    />
+        <result property="stageStatus"    column="stageStatus"    />
+        <result property="allStatus"    column="allStatus"    />
+        <result property="labelIds"    column="labelIds"    />
+        <result property="addTime"    column="addTime"    />
+    </resultMap>
+
+    <sql id="selectCmProductArchiveContentVo">
+         select
+         cm_product_archive_content.id,
+         cm_product_archive_content.productArchiveId,
+         cm_product_archive_content.title,
+         cm_product_archive_content.type,
+         cm_product_archive_content.content,
+         cm_product_archive_content.stageStatus,
+         cm_product_archive_content.allStatus,
+         cm_product_archive_content.labelIds,
+         cm_product_archive_content.createBy,
+         cm_product_archive_content.addTime
+    </sql>
+
+    <select id="getByCmProductArchiveContent" parameterType="CmProductArchiveContent" resultMap="CmProductArchiveContentResult">
+        <include refid="selectCmProductArchiveContentVo"/>
+        ,(SELECT  GROUP_CONCAT(cusf.keyword) FROM cm_user_search_frequency cusf WHERE FIND_IN_SET(cusf.id ,cm_product_archive_content.labelIds)) as keywords
+        from cm_product_archive_content AS cm_product_archive_content
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_content.id = #{id}</if>
+            <if test="productArchiveId != null "> and cm_product_archive_content.productArchiveId = #{productArchiveId}</if>
+            <if test="title != null  and title != ''"> and cm_product_archive_content.title = #{title}</if>
+            <if test="type != null  and type != ''"> and cm_product_archive_content.type = #{type}</if>
+            <if test="content != null  and content != ''"> and cm_product_archive_content.content = #{content}</if>
+            <if test="stageStatus != null "> and cm_product_archive_content.stageStatus = #{stageStatus}</if>
+            <if test="allStatus != null "> and cm_product_archive_content.allStatus = #{allStatus}</if>
+            <if test="labelIds != null  and labelIds != ''"> and cm_product_archive_content.labelIds = #{labelIds}</if>
+            <if test="createBy != null  and createBy != ''"> and cm_product_archive_content.createBy = #{createBy}</if>
+            <if test="addTime != null "> and cm_product_archive_content.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive_content.id
+        limit 0,1
+    </select>
+
+    <select id="getCmProductArchiveContentList" parameterType="CmProductArchiveContent" resultMap="CmProductArchiveContentResult">
+        <include refid="selectCmProductArchiveContentVo"/>
+        ,IFNULL((select sum(c.pv) from cm_praise_statistics c where  c.delFlag = 0 and c.type = 1 and cm_product_archive_content.id = c.authorId  <if test="startPvCreateTime != null ">AND c.createTime >= #{startPvCreateTime} </if><if test="endPvCreateTime != null ">AND c.createTime <![CDATA[ <= ]]> #{endPvCreateTime} </if>), 0) as pv
+        ,(SELECT  GROUP_CONCAT(cusf.keyword) FROM cm_user_search_frequency cusf WHERE FIND_IN_SET(cusf.id ,cm_product_archive_content.labelIds)) as keywords
+        from cm_product_archive_content AS cm_product_archive_content
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_content.id = #{id}</if>
+            <if test="productArchiveId != null "> and cm_product_archive_content.productArchiveId = #{productArchiveId}</if>
+            <if test="title != null  and title != ''"> and cm_product_archive_content.title  like concat('%', #{title}, '%')</if>
+            <if test="type != null  and type != ''">
+                and cm_product_archive_content.type
+                <if test="type.toUpperCase().indexOf('=')==-1">
+                    = #{type}
+                </if>
+                <if test="type.toUpperCase().indexOf('=')!=-1">
+                    <if test="type.toUpperCase().indexOf('NOT')!=-1"> not </if>
+                    <if test="type.toUpperCase().indexOf('IN')!=-1"> in </if>
+                    <foreach item="typeIn" collection="type.substring(type.toUpperCase().indexOf('=')+1,type.length()).trim().split(',')" open="(" separator="," close=")">
+                        #{typeIn}
+                    </foreach>
+                </if>
+            </if>
+            <if test="content != null  and content != ''"> and cm_product_archive_content.content = #{content}</if>
+            <if test="stageStatus != null "> and cm_product_archive_content.stageStatus = #{stageStatus}</if>
+            <if test="allStatus != null "> and cm_product_archive_content.allStatus = #{allStatus}</if>
+            <if test="labelIds != null  and labelIds != ''">
+                AND
+                <foreach item="labelIdIn" collection="labelIds.split(',')" open="(" separator="or" close=")">
+                    cm_product_archive_content.labelIds like concat('%', #{labelIdIn}, '%')
+                </foreach>
+             </if>
+            <if test="createBy != null  and createBy != ''"> and cm_product_archive_content.createBy = #{createBy}</if>
+            <if test="addTime != null "> and cm_product_archive_content.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive_content.id
+        order by cm_product_archive_content.addTime desc
+    </select>
+
+    <select id="getCount" parameterType="CmProductArchiveContent" resultType="int">
+        select count(1)
+        from cm_product_archive_content AS cm_product_archive_content
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_content.id = #{id}</if>
+            <if test="productArchiveId != null "> and cm_product_archive_content.productArchiveId = #{productArchiveId}</if>
+            <if test="title != null  and title != ''"> and cm_product_archive_content.title = #{title}</if>
+            <if test="type != null  and type != ''"> and cm_product_archive_content.type = #{type}</if>
+            <if test="content != null  and content != ''"> and cm_product_archive_content.content = #{content}</if>
+            <if test="stageStatus != null "> and cm_product_archive_content.stageStatus = #{stageStatus}</if>
+            <if test="allStatus != null "> and cm_product_archive_content.allStatus = #{allStatus}</if>
+            <if test="labelIds != null  and labelIds != ''"> and cm_product_archive_content.labelIds = #{labelIds}</if>
+            <if test="createBy != null  and createBy != ''"> and cm_product_archive_content.createBy = #{createBy}</if>
+            <if test="addTime != null "> and cm_product_archive_content.addTime = #{addTime}</if>
+        </where>
+    </select>
+
+    <select id="getCmProductArchiveContentById" parameterType="String" resultMap="CmProductArchiveContentResult">
+        <include refid="selectCmProductArchiveContentVo"/>
+        from cm_product_archive_content AS cm_product_archive_content
+        where    cm_product_archive_content.id = #{id}
+    </select>
+
+
+    <select id="getById" parameterType="CmProductArchiveContent" resultType="String">
+        select id
+        from cm_product_archive_content AS cm_product_archive_content
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_content.id = #{id}</if>
+            <if test="productArchiveId != null "> and cm_product_archive_content.productArchiveId = #{productArchiveId}</if>
+            <if test="title != null  and title != ''"> and cm_product_archive_content.title = #{title}</if>
+            <if test="type != null  and type != ''"> and cm_product_archive_content.type = #{type}</if>
+            <if test="content != null  and content != ''"> and cm_product_archive_content.content = #{content}</if>
+            <if test="stageStatus != null "> and cm_product_archive_content.stageStatus = #{stageStatus}</if>
+            <if test="allStatus != null "> and cm_product_archive_content.allStatus = #{allStatus}</if>
+            <if test="labelIds != null  and labelIds != ''"> and cm_product_archive_content.labelIds = #{labelIds}</if>
+            <if test="createBy != null  and createBy != ''"> and cm_product_archive_content.createBy = #{createBy}</if>
+            <if test="addTime != null "> and cm_product_archive_content.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive_content.id
+        limit 0,1
+    </select>
+
+    <insert id="addCmProductArchiveContent" parameterType="CmProductArchiveContent" useGeneratedKeys="true" keyProperty="id">
+        insert into cm_product_archive_content
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null and id != ''">id,</if>
+            <if test="productArchiveId != null">productArchiveId,</if>
+            <if test="title != null and title != ''">title,</if>
+            <if test="type != null and type != ''">type,</if>
+            <if test="content != null and content != ''">content,</if>
+            <if test="stageStatus != null">stageStatus,</if>
+            <if test="allStatus != null">allStatus,</if>
+            <if test="labelIds != null and labelIds != ''">labelIds,</if>
+            <if test="createBy != null and createBy != ''">createBy,</if>
+            <if test="addTime != null">addTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null and id != ''">#{id},</if>
+            <if test="productArchiveId != null">#{productArchiveId},</if>
+            <if test="title != null and title != ''">#{title},</if>
+            <if test="type != null and type != ''">#{type},</if>
+            <if test="content != null and content != ''">#{content},</if>
+            <if test="stageStatus != null">#{stageStatus},</if>
+            <if test="allStatus != null">#{allStatus},</if>
+            <if test="labelIds != null and labelIds != ''">#{labelIds},</if>
+            <if test="createBy != null and createBy != ''">#{createBy},</if>
+            <if test="addTime != null">#{addTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateCmProductArchiveContent" parameterType="CmProductArchiveContent">
+        update cm_product_archive_content
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="productArchiveId != null">productArchiveId = #{productArchiveId},</if>
+            <if test="title != null and title != ''">title = #{title},</if>
+            <if test="type != null and type != ''">type = #{type},</if>
+            <if test="content != null and content != ''">content = #{content},</if>
+            <if test="stageStatus != null">stageStatus = #{stageStatus},</if>
+            <if test="allStatus != null">allStatus = #{allStatus},</if>
+            <if test="labelIds != null and labelIds != ''">labelIds = #{labelIds},</if>
+            <if test="createBy != null and createBy != ''">createBy = #{createBy},</if>
+            <if test="addTime != null">addTime = #{addTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="delCmProductArchiveContentById" parameterType="String">
+        delete
+        from cm_product_archive_content where id = #{id}
+    </delete>
+
+    <delete id="delCmProductArchiveContent" parameterType="CmProductArchiveContent">
+        delete
+        from cm_product_archive_content AS cm_product_archive_content
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_content.id = #{id}</if>
+            <if test="productArchiveId != null "> and cm_product_archive_content.productArchiveId = #{productArchiveId}</if>
+            <if test="title != null  and title != ''"> and cm_product_archive_content.title = #{title}</if>
+            <if test="type != null  and type != ''"> and cm_product_archive_content.type = #{type}</if>
+            <if test="content != null  and content != ''"> and cm_product_archive_content.content = #{content}</if>
+            <if test="stageStatus != null "> and cm_product_archive_content.stageStatus = #{stageStatus}</if>
+            <if test="allStatus != null "> and cm_product_archive_content.allStatus = #{allStatus}</if>
+            <if test="labelIds != null  and labelIds != ''"> and cm_product_archive_content.labelIds = #{labelIds}</if>
+            <if test="createBy != null  and createBy != ''"> and cm_product_archive_content.createBy = #{createBy}</if>
+            <if test="addTime != null "> and cm_product_archive_content.addTime = #{addTime}</if>
+        </where>
+    </delete>
+
+</mapper>

+ 169 - 0
src/main/resources/mapper/productArchive/CmProductArchiveFileMapper.xml

@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.caimei365.manager.dao.productArchive.CmProductArchiveFileMapper">
+
+    <resultMap type="CmProductArchiveFile" id="CmProductArchiveFileResult">
+        <result property="id"    column="id"    />
+        <result property="archiveContentId"    column="archiveContentId"    />
+        <result property="fileName"    column="fileName"    />
+        <result property="ossName"    column="ossName"    />
+        <result property="waterOssName"    column="waterOssName"    />
+        <result property="ossUrl"    column="ossUrl"    />
+        <result property="waterOssUrl"    column="waterOssUrl"    />
+        <result property="htmlUrl"    column="htmlUrl"    />
+        <result property="uploadTime"    column="uploadTime"    />
+    </resultMap>
+
+    <sql id="selectCmProductArchiveFileVo">
+         select
+         cm_product_archive_file.id,
+         cm_product_archive_file.archiveContentId,
+         cm_product_archive_file.fileName,
+         cm_product_archive_file.ossName,
+         cm_product_archive_file.waterOssName,
+         cm_product_archive_file.ossUrl,
+         cm_product_archive_file.waterOssUrl,
+         cm_product_archive_file.htmlUrl,
+         cm_product_archive_file.uploadTime
+    </sql>
+
+    <select id="getByCmProductArchiveFile" parameterType="CmProductArchiveFile" resultMap="CmProductArchiveFileResult">
+        <include refid="selectCmProductArchiveFileVo"/>
+        from cm_product_archive_file AS cm_product_archive_file
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_file.id = #{id}</if>
+            <if test="archiveContentId != null "> and cm_product_archive_file.archiveContentId = #{archiveContentId}</if>
+            <if test="fileName != null  and fileName != ''"> and cm_product_archive_file.fileName like concat('%', #{fileName}, '%')</if>
+            <if test="ossName != null  and ossName != ''"> and cm_product_archive_file.ossName like concat('%', #{ossName}, '%')</if>
+            <if test="waterOssName != null  and waterOssName != ''"> and cm_product_archive_file.waterOssName like concat('%', #{waterOssName}, '%')</if>
+            <if test="ossUrl != null  and ossUrl != ''"> and cm_product_archive_file.ossUrl = #{ossUrl}</if>
+            <if test="waterOssUrl != null  and waterOssUrl != ''"> and cm_product_archive_file.waterOssUrl = #{waterOssUrl}</if>
+            <if test="htmlUrl != null  and htmlUrl != ''"> and cm_product_archive_file.htmlUrl = #{htmlUrl}</if>
+            <if test="uploadTime != null "> and cm_product_archive_file.uploadTime = #{uploadTime}</if>
+        </where>
+        group by cm_product_archive_file.id
+        limit 0,1
+    </select>
+
+    <select id="getCmProductArchiveFileList" parameterType="CmProductArchiveFile" resultMap="CmProductArchiveFileResult">
+        <include refid="selectCmProductArchiveFileVo"/>
+        from cm_product_archive_file AS cm_product_archive_file
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_file.id = #{id}</if>
+            <if test="archiveContentId != null "> and cm_product_archive_file.archiveContentId = #{archiveContentId}</if>
+            <if test="fileName != null  and fileName != ''"> and cm_product_archive_file.fileName like concat('%', #{fileName}, '%')</if>
+            <if test="ossName != null  and ossName != ''"> and cm_product_archive_file.ossName like concat('%', #{ossName}, '%')</if>
+            <if test="waterOssName != null  and waterOssName != ''"> and cm_product_archive_file.waterOssName like concat('%', #{waterOssName}, '%')</if>
+            <if test="ossUrl != null  and ossUrl != ''"> and cm_product_archive_file.ossUrl = #{ossUrl}</if>
+            <if test="waterOssUrl != null  and waterOssUrl != ''"> and cm_product_archive_file.waterOssUrl = #{waterOssUrl}</if>
+            <if test="htmlUrl != null  and htmlUrl != ''"> and cm_product_archive_file.htmlUrl = #{htmlUrl}</if>
+            <if test="uploadTime != null "> and cm_product_archive_file.uploadTime = #{uploadTime}</if>
+        </where>
+        group by cm_product_archive_file.id
+        order by cm_product_archive_file.uploadTime desc
+    </select>
+
+    <select id="getCount" parameterType="CmProductArchiveFile" resultType="int">
+        select count(1)
+        from cm_product_archive_file AS cm_product_archive_file
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_file.id = #{id}</if>
+            <if test="archiveContentId != null "> and cm_product_archive_file.archiveContentId = #{archiveContentId}</if>
+            <if test="fileName != null  and fileName != ''"> and cm_product_archive_file.fileName like concat('%', #{fileName}, '%')</if>
+            <if test="ossName != null  and ossName != ''"> and cm_product_archive_file.ossName like concat('%', #{ossName}, '%')</if>
+            <if test="waterOssName != null  and waterOssName != ''"> and cm_product_archive_file.waterOssName like concat('%', #{waterOssName}, '%')</if>
+            <if test="ossUrl != null  and ossUrl != ''"> and cm_product_archive_file.ossUrl = #{ossUrl}</if>
+            <if test="waterOssUrl != null  and waterOssUrl != ''"> and cm_product_archive_file.waterOssUrl = #{waterOssUrl}</if>
+            <if test="htmlUrl != null  and htmlUrl != ''"> and cm_product_archive_file.htmlUrl = #{htmlUrl}</if>
+            <if test="uploadTime != null "> and cm_product_archive_file.uploadTime = #{uploadTime}</if>
+        </where>
+    </select>
+
+    <select id="getCmProductArchiveFileById" parameterType="String" resultMap="CmProductArchiveFileResult">
+        <include refid="selectCmProductArchiveFileVo"/>
+        from cm_product_archive_file AS cm_product_archive_file
+        where    cm_product_archive_file.id = #{id}
+    </select>
+
+
+    <select id="getById" parameterType="CmProductArchiveFile" resultType="String">
+        select id
+        from cm_product_archive_file AS cm_product_archive_file
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_file.id = #{id}</if>
+            <if test="archiveContentId != null "> and cm_product_archive_file.archiveContentId = #{archiveContentId}</if>
+            <if test="fileName != null  and fileName != ''"> and cm_product_archive_file.fileName like concat('%', #{fileName}, '%')</if>
+            <if test="ossName != null  and ossName != ''"> and cm_product_archive_file.ossName like concat('%', #{ossName}, '%')</if>
+            <if test="waterOssName != null  and waterOssName != ''"> and cm_product_archive_file.waterOssName like concat('%', #{waterOssName}, '%')</if>
+            <if test="ossUrl != null  and ossUrl != ''"> and cm_product_archive_file.ossUrl = #{ossUrl}</if>
+            <if test="waterOssUrl != null  and waterOssUrl != ''"> and cm_product_archive_file.waterOssUrl = #{waterOssUrl}</if>
+            <if test="htmlUrl != null  and htmlUrl != ''"> and cm_product_archive_file.htmlUrl = #{htmlUrl}</if>
+            <if test="uploadTime != null "> and cm_product_archive_file.uploadTime = #{uploadTime}</if>
+        </where>
+        group by cm_product_archive_file.id
+        limit 0,1
+    </select>
+
+    <insert id="addCmProductArchiveFile" parameterType="CmProductArchiveFile" useGeneratedKeys="true" keyProperty="id">
+        insert into cm_product_archive_file
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="archiveContentId != null">archiveContentId,</if>
+            <if test="fileName != null and fileName != ''">fileName,</if>
+            <if test="ossName != null and ossName != ''">ossName,</if>
+            <if test="waterOssName != null and waterOssName != ''">waterOssName,</if>
+            <if test="ossUrl != null and ossUrl != ''">ossUrl,</if>
+            <if test="waterOssUrl != null and waterOssUrl != ''">waterOssUrl,</if>
+            <if test="htmlUrl != null and htmlUrl != ''">htmlUrl,</if>
+            <if test="uploadTime != null">uploadTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="archiveContentId != null">#{archiveContentId},</if>
+            <if test="fileName != null and fileName != ''">#{fileName},</if>
+            <if test="ossName != null and ossName != ''">#{ossName},</if>
+            <if test="waterOssName != null and waterOssName != ''">#{waterOssName},</if>
+            <if test="ossUrl != null and ossUrl != ''">#{ossUrl},</if>
+            <if test="waterOssUrl != null and waterOssUrl != ''">#{waterOssUrl},</if>
+            <if test="htmlUrl != null and htmlUrl != ''">#{htmlUrl},</if>
+            <if test="uploadTime != null">#{uploadTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateCmProductArchiveFile" parameterType="CmProductArchiveFile">
+        update cm_product_archive_file
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="archiveContentId != null">archiveContentId = #{archiveContentId},</if>
+            <if test="fileName != null and fileName != ''">fileName = #{fileName},</if>
+            <if test="ossName != null and ossName != ''">ossName = #{ossName},</if>
+            <if test="waterOssName != null and waterOssName != ''">waterOssName = #{waterOssName},</if>
+            <if test="ossUrl != null and ossUrl != ''">ossUrl = #{ossUrl},</if>
+            <if test="waterOssUrl != null and waterOssUrl != ''">waterOssUrl = #{waterOssUrl},</if>
+            <if test="htmlUrl != null and htmlUrl != ''">htmlUrl = #{htmlUrl},</if>
+            <if test="uploadTime != null">uploadTime = #{uploadTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="delCmProductArchiveFileById" parameterType="String">
+        delete
+        from cm_product_archive_file where id = #{id}
+    </delete>
+
+    <delete id="delCmProductArchiveFile" parameterType="CmProductArchiveFile">
+        delete
+        from cm_product_archive_file AS cm_product_archive_file
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive_file.id = #{id}</if>
+            <if test="archiveContentId != null "> and cm_product_archive_file.archiveContentId = #{archiveContentId}</if>
+            <if test="fileName != null  and fileName != ''"> and cm_product_archive_file.fileName like concat('%', #{fileName}, '%')</if>
+            <if test="ossName != null  and ossName != ''"> and cm_product_archive_file.ossName like concat('%', #{ossName}, '%')</if>
+            <if test="waterOssName != null  and waterOssName != ''"> and cm_product_archive_file.waterOssName like concat('%', #{waterOssName}, '%')</if>
+            <if test="ossUrl != null  and ossUrl != ''"> and cm_product_archive_file.ossUrl = #{ossUrl}</if>
+            <if test="waterOssUrl != null  and waterOssUrl != ''"> and cm_product_archive_file.waterOssUrl = #{waterOssUrl}</if>
+            <if test="htmlUrl != null  and htmlUrl != ''"> and cm_product_archive_file.htmlUrl = #{htmlUrl}</if>
+            <if test="uploadTime != null "> and cm_product_archive_file.uploadTime = #{uploadTime}</if>
+        </where>
+    </delete>
+
+</mapper>

+ 161 - 0
src/main/resources/mapper/productArchive/CmProductArchiveMapper.xml

@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.caimei365.manager.dao.productArchive.CmProductArchiveMapper">
+
+    <resultMap type="CmProductArchive" id="CmProductArchiveResult">
+        <result property="id"    column="id"    />
+        <result property="productId"    column="productId"    />
+        <result property="productName"    column="productName"    />
+        <result property="shopName"    column="shopName"    />
+        <result property="productImage"    column="productImage"    />
+        <result property="productType"    column="productType"    />
+        <result property="productClassify"    column="productClassify"    />
+        <result property="addTime"    column="addTime"    />
+    </resultMap>
+
+    <sql id="selectCmProductArchiveVo">
+         select
+         cm_product_archive.id,
+         cm_product_archive.productId,
+         cm_product_archive.productName,
+         cm_product_archive.shopName,
+         cm_product_archive.productImage,
+         cm_product_archive.productType,
+         cm_product_archive.productClassify,
+         cm_product_archive.addTime
+    </sql>
+
+    <select id="getByCmProductArchive" parameterType="CmProductArchive" resultMap="CmProductArchiveResult">
+        <include refid="selectCmProductArchiveVo"/>
+        from cm_product_archive AS cm_product_archive
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive.id = #{id}</if>
+            <if test="productId != null "> and cm_product_archive.productId = #{productId}</if>
+            <if test="productName != null  and productName != ''"> and cm_product_archive.productName like concat('%', #{productName}, '%')</if>
+            <if test="shopName != null  and shopName != ''"> and cm_product_archive.shopName like concat('%', #{shopName}, '%')</if>
+            <if test="productImage != null  and productImage != ''"> and cm_product_archive.productImage = #{productImage}</if>
+            <if test="productType != null  and productType != ''"> and cm_product_archive.productType = #{productType}</if>
+            <if test="productClassify != null "> and cm_product_archive.productClassify = #{productClassify}</if>
+            <if test="addTime != null "> and cm_product_archive.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive.id
+        limit 0,1
+    </select>
+
+    <select id="getCmProductArchiveList" parameterType="CmProductArchive" resultMap="CmProductArchiveResult">
+        <include refid="selectCmProductArchiveVo"/>
+        from cm_product_archive AS cm_product_archive
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive.id = #{id}</if>
+            <if test="productId != null "> and cm_product_archive.productId = #{productId}</if>
+            <if test="productName != null  and productName != ''"> and cm_product_archive.productName like concat('%', #{productName}, '%')</if>
+            <if test="shopName != null  and shopName != ''"> and cm_product_archive.shopName like concat('%', #{shopName}, '%')</if>
+            <if test="productImage != null  and productImage != ''"> and cm_product_archive.productImage = #{productImage}</if>
+            <if test="productType != null  and productType != ''"> and cm_product_archive.productType = #{productType}</if>
+            <if test="productClassify != null "> and cm_product_archive.productClassify = #{productClassify}</if>
+            <if test="addTime != null "> and cm_product_archive.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive.id
+        order by cm_product_archive.addTime desc
+    </select>
+
+    <select id="getCount" parameterType="CmProductArchive" resultType="int">
+        select count(1)
+        from cm_product_archive AS cm_product_archive
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive.id = #{id}</if>
+            <if test="productId != null "> and cm_product_archive.productId = #{productId}</if>
+            <if test="productName != null  and productName != ''"> and cm_product_archive.productName like concat('%', #{productName}, '%')</if>
+            <if test="shopName != null  and shopName != ''"> and cm_product_archive.shopName like concat('%', #{shopName}, '%')</if>
+            <if test="productImage != null  and productImage != ''"> and cm_product_archive.productImage = #{productImage}</if>
+            <if test="productType != null  and productType != ''"> and cm_product_archive.productType = #{productType}</if>
+            <if test="productClassify != null "> and cm_product_archive.productClassify = #{productClassify}</if>
+            <if test="addTime != null "> and cm_product_archive.addTime = #{addTime}</if>
+        </where>
+    </select>
+
+    <select id="getCmProductArchiveById" parameterType="String" resultMap="CmProductArchiveResult">
+        <include refid="selectCmProductArchiveVo"/>
+        from cm_product_archive AS cm_product_archive
+        where  cm_product_archive.id = #{id}
+    </select>
+
+
+    <select id="getById" parameterType="CmProductArchive" resultType="String">
+        select id
+        from cm_product_archive AS cm_product_archive
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive.id = #{id}</if>
+            <if test="productId != null "> and cm_product_archive.productId = #{productId}</if>
+            <if test="productName != null  and productName != ''"> and cm_product_archive.productName like concat('%', #{productName}, '%')</if>
+            <if test="shopName != null  and shopName != ''"> and cm_product_archive.shopName like concat('%', #{shopName}, '%')</if>
+            <if test="productImage != null  and productImage != ''"> and cm_product_archive.productImage = #{productImage}</if>
+            <if test="productType != null  and productType != ''"> and cm_product_archive.productType = #{productType}</if>
+            <if test="productClassify != null "> and cm_product_archive.productClassify = #{productClassify}</if>
+            <if test="addTime != null "> and cm_product_archive.addTime = #{addTime}</if>
+        </where>
+        group by cm_product_archive.id
+        limit 0,1
+    </select>
+
+    <insert id="addCmProductArchive" parameterType="CmProductArchive" useGeneratedKeys="true" keyProperty="id">
+        insert into cm_product_archive
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null and id != ''">id,</if>
+            <if test="productId != null">productId,</if>
+            <if test="productName != null and productName != ''">productName,</if>
+            <if test="shopName != null and shopName != ''">shopName,</if>
+            <if test="productImage != null and productImage != ''">productImage,</if>
+            <if test="productType != null and productType != ''">productType,</if>
+            <if test="productClassify != null">productClassify,</if>
+            <if test="addTime != null">addTime,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null and id != ''">#{id},</if>
+            <if test="productId != null">#{productId},</if>
+            <if test="productName != null and productName != ''">#{productName},</if>
+            <if test="shopName != null and shopName != ''">#{shopName},</if>
+            <if test="productImage != null and productImage != ''">#{productImage},</if>
+            <if test="productType != null and productType != ''">#{productType},</if>
+            <if test="productClassify != null">#{productClassify},</if>
+            <if test="addTime != null">#{addTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateCmProductArchive" parameterType="CmProductArchive">
+        update cm_product_archive
+        <trim prefix="SET" suffixOverrides=",">
+            productId = #{productId},
+            <if test="productName != null and productName != ''">productName = #{productName},</if>
+            <if test="shopName != null and shopName != ''">shopName = #{shopName},</if>
+            <if test="productImage != null and productImage != ''">productImage = #{productImage},</if>
+            <if test="productType != null and productType != ''">productType = #{productType},</if>
+            <if test="productClassify != null">productClassify = #{productClassify},</if>
+            <if test="addTime != null">addTime = #{addTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="delCmProductArchiveById" parameterType="String">
+        delete
+        from cm_product_archive where id = #{id}
+    </delete>
+
+    <delete id="delCmProductArchive" parameterType="CmProductArchive">
+        delete
+        from cm_product_archive AS cm_product_archive
+        <where>
+            <if test="id != null  and id != ''"> and cm_product_archive.id = #{id}</if>
+            <if test="productId != null "> and cm_product_archive.productId = #{productId}</if>
+            <if test="productName != null  and productName != ''"> and cm_product_archive.productName like concat('%', #{productName}, '%')</if>
+            <if test="shopName != null  and shopName != ''"> and cm_product_archive.shopName like concat('%', #{shopName}, '%')</if>
+            <if test="productImage != null  and productImage != ''"> and cm_product_archive.productImage = #{productImage}</if>
+            <if test="productType != null  and productType != ''"> and cm_product_archive.productType = #{productType}</if>
+            <if test="productClassify != null "> and cm_product_archive.productClassify = #{productClassify}</if>
+            <if test="addTime != null "> and cm_product_archive.addTime = #{addTime}</if>
+        </where>
+    </delete>
+
+</mapper>

+ 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>