Jelajahi Sumber

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

# Conflicts:
#	src/main/resources/mapper/CmBehaciorRecordDao.xml
kaick 1 tahun lalu
induk
melakukan
6555fe95bd
59 mengubah file dengan 4279 tambahan dan 174 penghapusan
  1. 17 0
      pom.xml
  2. 4 3
      src/main/java/com/caimei365/manager/controller/caimei/user/CmBehaviorRecordApi.java
  3. 156 0
      src/main/java/com/caimei365/manager/controller/caimei/user/CmMarketShopApi.java
  4. 127 27
      src/main/java/com/caimei365/manager/controller/caimei/user/CustomerApi.java
  5. 3 3
      src/main/java/com/caimei365/manager/dao/user/CmBehaviorRecordDao.java
  6. 306 0
      src/main/java/com/caimei365/manager/dao/user/CmMarketShopDao.java
  7. 57 4
      src/main/java/com/caimei365/manager/dao/user/CustomerServiceDao.java
  8. 8 0
      src/main/java/com/caimei365/manager/entity/caimei/CmBehaviorRecord.java
  9. 40 0
      src/main/java/com/caimei365/manager/entity/caimei/ReturnData.java
  10. 5 1
      src/main/java/com/caimei365/manager/entity/caimei/ReturnEntity.java
  11. 12 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopInfo.java
  12. 12 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopKeyword.java
  13. 4 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmRoosInformation.java
  14. 4 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopInfo.java
  15. 4 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopKeyword.java
  16. 4 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopPopUp.java
  17. 57 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopProduct.java
  18. 8 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopStatistics.java
  19. 13 4
      src/main/java/com/caimei365/manager/entity/caimei/product/Product.java
  20. 49 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/AdvertHits.java
  21. 79 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/ArticleReadVolume.java
  22. 53 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/CmMarketReport.java
  23. 77 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/CmMarketShop.java
  24. 57 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/FunnelModel.java
  25. 49 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Impressions.java
  26. 38 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/PageDuration.java
  27. 48 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Proportion.java
  28. 49 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/ReadVolume.java
  29. 33 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Remark.java
  30. 38 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Stage.java
  31. 43 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Summary.java
  32. 39 0
      src/main/java/com/caimei365/manager/entity/caimei/shopImport/Visits.java
  33. 76 0
      src/main/java/com/caimei365/manager/service/caimei/listener/AdvertHitsListener.java
  34. 78 0
      src/main/java/com/caimei365/manager/service/caimei/listener/ArticleReadVolumeListener.java
  35. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/FunnelModelListener.java
  36. 72 0
      src/main/java/com/caimei365/manager/service/caimei/listener/ImpressionsListener.java
  37. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/PageDurationListener.java
  38. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/ProportionListener.java
  39. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/ReadVolumeListener.java
  40. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/RemarkListener.java
  41. 66 0
      src/main/java/com/caimei365/manager/service/caimei/listener/StageListener.java
  42. 71 0
      src/main/java/com/caimei365/manager/service/caimei/listener/SummaryListener.java
  43. 63 0
      src/main/java/com/caimei365/manager/service/caimei/listener/VisitsLisener.java
  44. 2 1
      src/main/java/com/caimei365/manager/service/caimei/user/CmBehaviorRecordService.java
  45. 83 0
      src/main/java/com/caimei365/manager/service/caimei/user/CmMarketShopService.java
  46. 63 8
      src/main/java/com/caimei365/manager/service/caimei/user/CustomerService.java
  47. 39 2
      src/main/java/com/caimei365/manager/service/caimei/user/impl/CmBehaviorRecordServiceImpl.java
  48. 684 0
      src/main/java/com/caimei365/manager/service/caimei/user/impl/CmMarketShopServiceImpl.java
  49. 145 12
      src/main/java/com/caimei365/manager/service/caimei/user/impl/CustomerServiceImpl.java
  50. 78 0
      src/main/java/com/caimei365/manager/utils/ExtractCallback.java
  51. 130 0
      src/main/java/com/caimei365/manager/utils/FileUtil.java
  52. 13 2
      src/main/java/com/caimei365/manager/utils/formDataUtils.java
  53. 101 81
      src/main/resources/mapper/CmBehaciorRecordDao.xml
  54. 10 8
      src/main/resources/mapper/KeyWordDao.xml
  55. 2 4
      src/main/resources/mapper/svip/CmSvipHistoryDao.xml
  56. 6 0
      src/main/resources/mapper/user/CmClubRemarksDao.xml
  57. 385 0
      src/main/resources/mapper/user/CmMarketShopDao.xml
  58. 122 13
      src/main/resources/mapper/user/CustomerServiceDao.xml
  59. 182 1
      src/test/java/com/caimei365/manager/ManagerApplicationTests.java

+ 17 - 0
pom.xml

@@ -181,6 +181,23 @@
             <artifactId>jsoup</artifactId>
             <artifactId>jsoup</artifactId>
             <version>1.9.2</version>
             <version>1.9.2</version>
         </dependency>
         </dependency>
+        <!--rar解压-->
+        <dependency>
+            <groupId>net.sf.sevenzipjbinding</groupId>
+            <artifactId>sevenzipjbinding</artifactId>
+            <version>16.02-2.01</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.sevenzipjbinding</groupId>
+            <artifactId>sevenzipjbinding-all-platforms</artifactId>
+            <version>16.02-2.01</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.lingala</groupId>
+            <artifactId>zip4j</artifactId>
+            <version>1.3.3</version>
+        </dependency>
     </dependencies>
     </dependencies>
 
 
     <profiles>
     <profiles>

+ 4 - 3
src/main/java/com/caimei365/manager/controller/caimei/user/CmBehaviorRecordApi.java

@@ -17,6 +17,7 @@ import javax.swing.filechooser.FileSystemView;
 import java.io.File;
 import java.io.File;
 import java.net.URLEncoder;
 import java.net.URLEncoder;
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
  * Description
  * Description
@@ -96,9 +97,9 @@ public class CmBehaviorRecordApi {
      * @return 返回
      * @return 返回
      */
      */
     @GetMapping("/record/recordList")
     @GetMapping("/record/recordList")
-    public ResponseJson<PaginationVo<CmBehaviorRecord>> recordList (CmBehaviorRecord cmBehaviorRecord,
-                                                                    @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
-                                                                    @RequestParam(value = "pageSize",defaultValue = "20")int pageSize) {
+    public ResponseJson<Map<String, Object>> recordList (CmBehaviorRecord cmBehaviorRecord,
+                                                                        @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                        @RequestParam(value = "pageSize",defaultValue = "20")int pageSize) {
         return recordService.recordList(cmBehaviorRecord, pageNum, pageSize);
         return recordService.recordList(cmBehaviorRecord, pageNum, pageSize);
     }
     }
 
 

+ 156 - 0
src/main/java/com/caimei365/manager/controller/caimei/user/CmMarketShopApi.java

@@ -0,0 +1,156 @@
+package com.caimei365.manager.controller.caimei.user;
+
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.entity.PaginationVo;
+import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmShop;
+import com.caimei365.manager.entity.caimei.shopImport.CmMarketReport;
+import com.caimei365.manager.entity.caimei.shopImport.CmMarketShop;
+import com.caimei365.manager.service.caimei.user.CmMarketShopService;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/14
+ */
+@RestController
+@RequestMapping("/user/market")
+public class CmMarketShopApi {
+
+    @Resource private CmMarketShopService marketShopService;
+
+    /**
+     * 上传供应商营销logo
+     * @param id
+     * @param logo
+     * @return
+     */
+    @GetMapping("/uploadShopLogo")
+    public ResponseJson uploadShopLogo(Integer id, String logo) {
+        if (null == id) {
+            return  ResponseJson.error(-1, "商品营销id不能为空", null);
+        }
+        if (StringUtils.isBlank(logo) || StringUtils.isEmpty(logo)) {
+            return  ResponseJson.error(-1, "供应商营销id不能为空", null);
+        }
+        return marketShopService.uploadShopLogo(id, logo);
+    }
+
+    /**
+     * 数据报表列表
+     * @param marketId
+     * @param reportName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getMarketReport")
+    public ResponseJson<PaginationVo<CmMarketReport>> getMarketReport(Integer marketId, String reportName,
+                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        if (null == marketId) {
+            return  ResponseJson.error(-1, "商品营销id不能为空", null);
+        }
+        return marketShopService.getMarketReport(marketId, reportName, pageNum, pageSize);
+    }
+
+    /**
+     * 编辑回显
+     * @param id
+     * @return
+     */
+    @GetMapping("/getMarketReportById")
+    public ResponseJson<CmMarketReport> getMarketReportById(Integer id) {
+        if (null == id) {
+            return  ResponseJson.error(-1, "供应商营销id不能为空", null);
+        }
+        return marketShopService.getMarketReportById(id);
+    }
+
+    /**
+     * 启用数据报表
+     * @param id
+     * @return
+     */
+    @GetMapping("/updateVisible")
+    public ResponseJson updateVisible(Integer id) {
+        if (null == id) {
+            return  ResponseJson.error(-1, "供应商营销id不能为空", null);
+        }
+        return marketShopService.updateMarketReportVisible(id);
+    }
+
+    /**
+     * 删除数据报表
+     * @param id
+     * @return
+     */
+    @GetMapping("/deleteMarketReport")
+    public ResponseJson deleteMarketReport(Integer id) {
+        if (null == id) {
+            return  ResponseJson.error(-1, "供应商营销id不能为空", null);
+        }
+        return marketShopService.updateMarketReport(id);
+    }
+
+    /**
+     * 上传zip、rar文件到服务器并解压
+     * @return
+     */
+    @PostMapping("/saveMarketReport")
+    public ResponseJson saveMarketReport(@RequestParam("reportFile") MultipartFile reportFile) throws IOException {
+
+        if (reportFile.isEmpty() || reportFile == null) {
+            return ResponseJson.error(-1, "报表文件不能为空", null);
+        }
+        return marketShopService.saveMarketReport(reportFile);
+    }
+
+    /**
+     * 保存报表数据
+     * @param marketId
+     * @param id
+     * @param reportDate
+     * @param reportName
+     * @param filePath
+     * @return
+     * @throws IOException
+     */
+    @GetMapping("/saveReport")
+    public ResponseJson saveReport(Integer marketId, Integer id, String reportDate, String reportName, String filePath) throws IOException {
+        if (marketId == null) {
+            return ResponseJson.error(-1, "商品营销Id不能为空", null);
+        }
+        if (StringUtils.isBlank(reportDate) || StringUtils.isEmpty(reportDate)) {
+            return ResponseJson.error(-1, "报表时间不能为空", null);
+        }
+        if (StringUtils.isBlank(reportName) || StringUtils.isEmpty(reportName)) {
+            return ResponseJson.error(-1, "报表名称不能为空", null);
+        }
+        if (StringUtils.isBlank(filePath) || StringUtils.isEmpty(filePath)) {
+            return ResponseJson.error(-1, "报表路径不能为空", null);
+        }
+        return marketShopService.saveReport(marketId, id, reportDate, reportName, filePath);
+    }
+
+    /**
+     * 报表数据预览
+     * @param id
+     * @return
+     */
+    @GetMapping("/preview")
+    public ResponseJson<Map<String, Object>> preview(Integer id) {
+        if (id == null) {
+            return ResponseJson.error(-1, "报表id不能为空", null);
+        }
+        return marketShopService.preview(id);
+    }
+
+}

+ 127 - 27
src/main/java/com/caimei365/manager/controller/caimei/user/CustomerApi.java

@@ -7,6 +7,7 @@ import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 
 /**
 /**
  * Description
  * Description
@@ -87,6 +89,91 @@ public class CustomerApi {
         return customerService.renewCustomerShop(id, status);
         return customerService.renewCustomerShop(id, status);
     }
     }
 
 
+    /**
+     * 潜客商品列表
+     * @param id
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getShopProduct")
+    public ResponseJson<PaginationVo<CmShopProduct>> getShopProduct(Integer id, Integer productId, String productName, Integer status,
+                                                                    @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                    @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        return customerService.getShopProduct(id, productId, productName, status, pageNum, pageSize);
+    }
+
+    /**
+     * 商品列表
+     * @param shopId
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getProductList")
+    public ResponseJson<PaginationVo<Product>> getProductList(Integer shopId, Integer productId, String productName,
+                                                              @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                              @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        if (null == shopId) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        return customerService.getProductList(shopId, productId, productName, pageNum, pageSize);
+    }
+
+    /**
+     * 保存潜客供应商统计商品
+     * @param id
+     * @param productIds
+     * @return
+     */
+    @GetMapping("/saveShopProduct")
+    public ResponseJson saveShopProduct(Integer id, String productIds) {
+        if (null == id) {
+            return ResponseJson.error(-1, "潜客供应商统计id不能为空", null);
+        }
+        if (StringUtils.isBlank(productIds)) {
+            return ResponseJson.error(-1, "商品id不能为空", null);
+        }
+        return customerService.saveShopProduct(id, productIds);
+    }
+
+    /**
+     * 设置潜客商品统计状态
+     * @param id
+     * @return
+     */
+    @GetMapping("/renewShopProduct")
+    public ResponseJson renewShopProduct(Integer id, Integer status) {
+        if (null == id) {
+            return ResponseJson.error(-1, "潜客供应商商品统计id不能为空", null);
+        }
+        if (null == status) {
+            return ResponseJson.error(-1, "统计状态不能为空", null);
+        }
+        return customerService.updateProductStatus(id, status);
+    }
+
+    /**
+     * 删除潜客供应商统计商品
+     * @param id
+     * @return
+     */
+    @GetMapping("/deleteShopProduct")
+    public ResponseJson deleteShopProduct(Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "潜客供应商商品统计id不能为空", null);
+        }
+
+        return customerService.updateShopProduct(id);
+    }
+
     /**
     /**
      * 游客统计
      * 游客统计
      * @param cmRoosInformation
      * @param cmRoosInformation
@@ -98,8 +185,8 @@ public class CustomerApi {
     public ResponseJson<PaginationVo<CmRoosInformation>> getCmInformationList(CmRoosInformation cmRoosInformation,
     public ResponseJson<PaginationVo<CmRoosInformation>> getCmInformationList(CmRoosInformation cmRoosInformation,
                                                                               @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                               @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                               @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
                                                                               @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
-        if (null == cmRoosInformation.getShopId()) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        if (null == cmRoosInformation.getShopProductId()) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         return customerService.getCmInformationList(cmRoosInformation, pageNum, pageSize);
         return customerService.getCmInformationList(cmRoosInformation, pageNum, pageSize);
     }
     }
@@ -168,8 +255,8 @@ public class CustomerApi {
     public ResponseJson<PaginationVo<CmShopInfo>> getShopInfoList(CmShopInfo cmShopInfo,
     public ResponseJson<PaginationVo<CmShopInfo>> getShopInfoList(CmShopInfo cmShopInfo,
                                                                   @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                   @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                   @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
                                                                   @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
-        if (null == cmShopInfo.getShopId()) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        if (null == cmShopInfo.getShopProductId()) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         return customerService.getShopInfoList(cmShopInfo, pageNum, pageSize);
         return customerService.getShopInfoList(cmShopInfo, pageNum, pageSize);
     }
     }
@@ -191,19 +278,19 @@ public class CustomerApi {
 
 
     /**
     /**
      * 添加文章统计
      * 添加文章统计
-     * @param shopId
+     * @param shopProductId
      * @param infoIds
      * @param infoIds
      * @return
      * @return
      */
      */
     @GetMapping("/saveShopInfo")
     @GetMapping("/saveShopInfo")
-    public ResponseJson saveShopInfo(Integer shopId, String infoIds){
-        if (null == shopId) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+    public ResponseJson saveShopInfo(Integer shopProductId, String infoIds){
+        if (null == shopProductId) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         if (null == infoIds) {
         if (null == infoIds) {
             return ResponseJson.error(-1, "选择文章不能为空", null);
             return ResponseJson.error(-1, "选择文章不能为空", null);
         }
         }
-        return customerService.saveShopInfo(shopId, infoIds);
+        return customerService.saveShopInfo(shopProductId, infoIds);
     }
     }
 
 
     /**
     /**
@@ -247,8 +334,8 @@ public class CustomerApi {
     public ResponseJson<PaginationVo<CmShopKeyword>> getShopKeywordList(CmShopKeyword cmShopKeyword,
     public ResponseJson<PaginationVo<CmShopKeyword>> getShopKeywordList(CmShopKeyword cmShopKeyword,
                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
-        if (null == cmShopKeyword.getShopId()) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        if (null == cmShopKeyword.getShopProductId()) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         return customerService.getShopKeywordList(cmShopKeyword, pageNum, pageSize);
         return customerService.getShopKeywordList(cmShopKeyword, pageNum, pageSize);
     }
     }
@@ -269,19 +356,19 @@ public class CustomerApi {
 
 
     /**
     /**
      * 添加搜索词统计
      * 添加搜索词统计
-     * @param shopId
+     * @param shopProductId
      * @param keyWordIds
      * @param keyWordIds
      * @return
      * @return
      */
      */
     @GetMapping("/saveShopKeyword")
     @GetMapping("/saveShopKeyword")
-    public ResponseJson saveShopKeyword(Integer shopId, String keyWordIds){
-        if (null == shopId) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+    public ResponseJson saveShopKeyword(Integer shopProductId, String keyWordIds){
+        if (null == shopProductId) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         if (null == keyWordIds) {
         if (null == keyWordIds) {
             return ResponseJson.error(-1, "选择搜索词不能为空", null);
             return ResponseJson.error(-1, "选择搜索词不能为空", null);
         }
         }
-        return customerService.saveShopKeyword(shopId, keyWordIds);
+        return customerService.saveShopKeyword(shopProductId, keyWordIds);
     }
     }
 
 
     /**
     /**
@@ -316,15 +403,15 @@ public class CustomerApi {
 
 
     /**
     /**
      * 弹框信息回显
      * 弹框信息回显
-     * @param shopId
+     * @param shopProductId
      * @return
      * @return
      */
      */
     @GetMapping("/getShopPopUp")
     @GetMapping("/getShopPopUp")
-    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId) {
-        if (null == shopId) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopProductId) {
+        if (null == shopProductId) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
-        return customerService.getShopPopUp(shopId);
+        return customerService.getShopPopUp(shopProductId);
     }
     }
 
 
     /**
     /**
@@ -334,8 +421,8 @@ public class CustomerApi {
      */
      */
     @PostMapping("/saveShopPopUp")
     @PostMapping("/saveShopPopUp")
     public ResponseJson saveShopPopUp(@RequestBody CmShopPopUp cmShopPopUp) {
     public ResponseJson saveShopPopUp(@RequestBody CmShopPopUp cmShopPopUp) {
-        if (null == cmShopPopUp.getShopId()) {
-            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        if (null == cmShopPopUp.getShopProductId()) {
+            return ResponseJson.error(-1, "供应商商品统计Id不能为空", null);
         }
         }
         if (null == cmShopPopUp.getImage()) {
         if (null == cmShopPopUp.getImage()) {
             return ResponseJson.error(-1, "显示图不能为空", null);
             return ResponseJson.error(-1, "显示图不能为空", null);
@@ -437,6 +524,19 @@ public class CustomerApi {
         return customerService.delShopAdvertisingImage(id);
         return customerService.delShopAdvertisingImage(id);
     }
     }
 
 
+    /**
+     * 获取潜客供应商下统计商品
+     * @param shopId
+     * @return
+     */
+    @GetMapping("/getShopProductList")
+    public ResponseJson<List<CmShopProduct>> getShopProductList(Integer shopId) {
+        if (null == shopId) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        return customerService.getShopProductList(shopId);
+    }
+
     /**
     /**
      * 供应商主页统计
      * 供应商主页统计
      * @param shopId
      * @param shopId
@@ -475,13 +575,13 @@ public class CustomerApi {
      * @return
      * @return
      */
      */
     @GetMapping("/getPageShopInfo")
     @GetMapping("/getPageShopInfo")
-    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, String startTime, String endTime,
+    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, Integer productId, String startTime, String endTime,
                                                                @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
                                                                @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
         if (null == shopId) {
         if (null == shopId) {
             return ResponseJson.error(-1, "供应商Id不能为空", null);
             return ResponseJson.error(-1, "供应商Id不能为空", null);
         }
         }
-        return customerService.getPageShopInfo(shopId, startTime, endTime, pageNum, pageSize);
+        return customerService.getPageShopInfo(shopId, productId, startTime, endTime, pageNum, pageSize);
     }
     }
 
 
     /**
     /**
@@ -490,12 +590,12 @@ public class CustomerApi {
      * @return
      * @return
      */
      */
     @GetMapping("/getPageShopKeyword")
     @GetMapping("/getPageShopKeyword")
-    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, String startTime, String endTime,
+    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, Integer productId, String startTime, String endTime,
                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
         if (null == shopId) {
         if (null == shopId) {
             return ResponseJson.error(-1, "供应商Id不能为空", null);
             return ResponseJson.error(-1, "供应商Id不能为空", null);
         }
         }
-        return customerService.getPageShopKeyword(shopId, startTime, endTime, pageNum, pageSize);
+        return customerService.getPageShopKeyword(shopId, productId, startTime, endTime, pageNum, pageSize);
     }
     }
 }
 }

+ 3 - 3
src/main/java/com/caimei365/manager/dao/user/CmBehaviorRecordDao.java

@@ -2,7 +2,7 @@ package com.caimei365.manager.dao.user;
 
 
 import com.caimei365.manager.entity.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmPageType;
 import com.caimei365.manager.entity.caimei.CmPageType;
-import com.caimei365.manager.entity.caimei.RetuenEntity;
+import com.caimei365.manager.entity.caimei.ReturnEntity;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 
 
@@ -21,7 +21,7 @@ public interface CmBehaviorRecordDao {
      * @param keyword
      * @param keyword
      * @return
      * @return
      */
      */
-    List<RetuenEntity> getkeyword(@Param("keyword") String keyword);
+    List<ReturnEntity> getkeyword(@Param("keyword") String keyword);
 
 
     /**
     /**
      * 页面标签
      * 页面标签
@@ -60,7 +60,7 @@ public interface CmBehaviorRecordDao {
      * 标签库
      * 标签库
      * @return 返回
      * @return 返回
      */
      */
-    List<RetuenEntity> searchList();
+    List<ReturnEntity> searchList();
 
 
     /**
     /**
      * 供应商信息
      * 供应商信息

+ 306 - 0
src/main/java/com/caimei365/manager/dao/user/CmMarketShopDao.java

@@ -0,0 +1,306 @@
+package com.caimei365.manager.dao.user;
+
+import com.caimei365.manager.entity.caimei.CmShop;
+import com.caimei365.manager.entity.caimei.ReturnEntity;
+import com.caimei365.manager.entity.caimei.shopImport.*;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/14
+ */
+@Mapper
+public interface CmMarketShopDao {
+
+    /**
+     * 上传营销供应商logo
+     * @param id
+     * @param logo
+     */
+    void updateShopLogo(@Param("id") Integer id, @Param("logo") String logo);
+
+    /**
+     * 数据报表数据
+     * @param marketId
+     * @param reportName
+     * @return
+     */
+    List<CmMarketReport> getMarketReport(@Param("marketId") Integer marketId, @Param("reportName") String reportName);
+
+    /**
+     * 根据数据报表Id 查询报表数据
+     * @param id
+     * @return
+     */
+    CmMarketReport getMarketReportById(@Param("id") Integer id);
+
+    /**
+     * 启用数据报表
+     * @param id
+     */
+    void updateMarketReportVisible(@Param("id") Integer id);
+
+    /**
+     * 删除数据报表
+     * @param id
+     */
+    void updateMarketReport(@Param("id") Integer id);
+
+    /**
+     * 添加营销供应商数据报表
+     * @param cmMarketReport
+     */
+    void insertMarketReport(CmMarketReport cmMarketReport);
+
+    /**
+     * 阶段描述
+     * @param stage
+     */
+    void insertMarketStage(Stage stage);
+
+    /**
+     * 漏斗模型数据
+     * @param funnelModel
+     */
+    void insertMarketFunnelModel(FunnelModel funnelModel);
+
+    /**
+     * 推文数据
+     * @param articleReadVolume
+     */
+    void insertMarketArticleReadVolume(ArticleReadVolume articleReadVolume);
+
+    /**
+     * 展现量
+     * @param impressions
+     */
+    void insertMarketImpressions(Impressions impressions);
+
+    /**
+     * 点击量
+     * @param readVolume
+     */
+    void insertMarketReadVolume(ReadVolume readVolume);
+
+    /**
+     * SEO汇总
+     * @param summary
+     */
+    void insertMarketSummary(Summary summary);
+
+    /**
+     * 访问量
+     * @param visits
+     */
+    void insertMarketVisits(Visits visits);
+
+    /**
+     * 访客来源分布
+     * @param proportion
+     */
+    void insertMarketProportion(Proportion proportion);
+
+    /**
+     * 页面平均时长
+     * @param pageDuration
+     */
+    void insertMarketPageDuration(PageDuration pageDuration);
+
+    /**
+     * 广告图点击量
+     * @param mallHits
+     */
+    void insertMarketAdvertHits(AdvertHits mallHits);
+
+    /**
+     * 咨询数量
+     * @param remark
+     */
+    void insertMarketRemark(Remark remark);
+
+    /**
+     * 修改阶段信息
+     * @param marketReportId
+     */
+    void updateMarketStage(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改漏斗模型数据
+     * @param marketReportId
+     */
+    void updateMarketFunnelModel(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改推文数据
+     * @param marketReportId
+     */
+    void updateMarketArticleReadVolume(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改展现量
+     * @param marketReportId
+     */
+    void updateMarketImpressions(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改点击量
+     * @param marketReportId
+     */
+    void updateMarketReadVolume(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改SEO汇总数据
+     * @param marketReportId
+     */
+    void updateMarketSummary(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改访问量数据
+     * @param marketReportId
+     */
+    void updateMarketVisits(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改方可来源分布数据
+     * @param marketReportId
+     */
+    void updateMarketProportion(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改页面平均时长数据
+     * @param marketReportId
+     */
+    void updateMarketPageDuration(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改广告图点击量数据
+     * @param marketReportId
+     */
+    void updateMarketAdvertHits(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 修改咨询数量数据
+     * @param marketReportId
+     */
+    void updateMarketRemark(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取报表对应的供应商信息
+     * @param id
+     * @return
+     */
+    CmMarketShop getShopInfoById(@Param("id") Integer id);
+
+    /**
+     * 获取阶段描述
+     * @param marketReportId
+     * @return
+     */
+    List<Stage> getMarketStage(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取漏洞模型数据
+     * @param marketReportId
+     * @return
+     */
+    List<FunnelModel> getMarketFunnelModel(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取推文数据
+     * @param marketReportId
+     * @return
+     */
+    List<ArticleReadVolume> getMarketArticleReadVolume(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取展现量数据
+     * @param marketReportId
+     * @return
+     */
+    List<Impressions> getMarketImpressions(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取点击量数据
+     * @param marketReportId
+     * @return
+     */
+    List<ReadVolume> getMarketReadVolume(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取SEO汇总数据
+     * @param marketReportId
+     * @return
+     */
+    List<Summary> getMarketSummary(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取访问量数据
+     * @param marketReportId
+     * @return
+     */
+    List<Visits> getMarketVisits(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取访客来源分布数据
+     * @param marketReportId
+     * @return
+     */
+    List<Proportion> getMarketProportion(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取页面平均访问时长数据
+     * @param marketReportId
+     * @return
+     */
+    List<PageDuration> getMarketPageDuration(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取广告图点击量数据
+     * @param marketReportId
+     * @return
+     */
+    List<AdvertHits> getMarketAdvertHits(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 获取咨询数量数据
+     * @param marketReportId
+     * @return
+     */
+    List<Remark> getMarketRemark(@Param("marketReportId") Integer marketReportId);
+
+    /**
+     * 供应商包含的标签词
+     * @param shopId
+     * @return
+     */
+    List<String> getShopKeyword(@Param("shopId") Integer shopId);
+
+    /**
+     * 访问供应商相关用户所在地区
+     * @param accessDate
+     * @param labels
+     * @return
+     */
+    List<String> getRegion(@Param("accessDate") String accessDate, @Param("labels") List<String> labels);
+
+    /**
+     * 用户身份
+     * @param accessDate
+     * @param labels
+     * @return
+     */
+    List<ReturnEntity> getUserIdentity(@Param("accessDate") String accessDate, @Param("labels") List<String> labels);
+
+    /**
+     * 机构类型
+     * @param accessDate
+     * @param labels
+     * @return
+     */
+    List<ReturnEntity> getClubType(@Param("accessDate") String accessDate, @Param("labels") List<String> labels);
+}

+ 57 - 4
src/main/java/com/caimei365/manager/dao/user/CustomerServiceDao.java

@@ -2,6 +2,7 @@ package com.caimei365.manager.dao.user;
 
 
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 
 
@@ -48,6 +49,58 @@ public interface CustomerServiceDao {
      */
      */
     void updateCustomerShop( @Param("id") Integer id, @Param("status") Integer status);
     void updateCustomerShop( @Param("id") Integer id, @Param("status") Integer status);
 
 
+    /**
+     * 潜客收集供应商商品
+     * @param id
+     * @param productId
+     * @param productName
+     * @param status
+     * @return
+     */
+    List<CmShopProduct> getShopProduct(@Param("id") Integer id, @Param("productId") Integer productId, @Param("productName") String productName, @Param("status") Integer status);
+
+    /**
+     * 商品列表
+     * @param shopId
+     * @param productId
+     * @param productName
+     * @return
+     */
+    List<Product> getProductList(@Param("shopId") Integer shopId, @Param("productId") Integer productId, @Param("productName") String productName);
+
+    /**
+     * 潜客供应商商品ids
+     * @param shopId
+     * @return
+     */
+    List<Integer> getProductIds(@Param("shopId") Integer shopId);
+
+    /**
+     * 保存潜客供应商统计商品
+     * @param statisticsId
+     * @param productId
+     */
+    void insertShopProduct(@Param("statisticsId") Integer statisticsId, @Param("productId") Integer productId);
+
+    /**
+     * 设置潜客商品统计状态
+     * @param id
+     */
+    void updateProductStatus(@Param("id") Integer id, @Param("status") Integer status);
+
+    /**
+     * 删除潜客供应商统计商品
+     * @param id
+     */
+    void updateShopProduct(@Param("id") Integer id);
+
+    /**
+     * 获取潜客供应商下统计商品
+     * @param shopId
+     * @return
+     */
+    List<CmShopProduct> getShopProductList(@Param("shopId") Integer shopId);
+
     /**
     /**
      * 游客统计列表
      * 游客统计列表
      * @param cmRoosInformation
      * @param cmRoosInformation
@@ -169,10 +222,10 @@ public interface CustomerServiceDao {
 
 
     /**
     /**
      * 弹框数据回显
      * 弹框数据回显
-     * @param shopId
+     * @param shopProductId
      * @return
      * @return
      */
      */
-    CmShopPopUp getShopPopUp(@Param("shopId") Integer shopId);
+    CmShopPopUp getShopPopUp(@Param("shopProductId") Integer shopProductId);
 
 
     /**
     /**
      * 插入弹框数据
      * 插入弹框数据
@@ -252,13 +305,13 @@ public interface CustomerServiceDao {
      * @param shopId
      * @param shopId
      * @return
      * @return
      */
      */
-    List<CmPageShopInfo> getPageShopInfo(@Param("shopId") Integer shopId, @Param("startTime") String startTime, @Param("endTime") String endTime);
+    List<CmPageShopInfo> getPageShopInfo(@Param("shopId") Integer shopId, @Param("productId") Integer productId, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 
     /**
     /**
      * 供应商搜索词统计
      * 供应商搜索词统计
      * @param shopId
      * @param shopId
      * @return
      * @return
      */
      */
-    List<CmPageShopKeyword> getPageShopKeyword(@Param("shopId") Integer shopId, @Param("startTime") String startTime, @Param("endTime") String endTime);
+    List<CmPageShopKeyword> getPageShopKeyword(@Param("shopId") Integer shopId, @Param("productId") Integer productId, @Param("startTime") String startTime, @Param("endTime") String endTime);
 
 
 }
 }

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

@@ -179,6 +179,14 @@ public class CmBehaviorRecord {
      */
      */
     @ExcelIgnore
     @ExcelIgnore
     private String registerTime;
     private String registerTime;
+    /**
+     * 注册开始时间--筛选
+     */
+    private String registerStartTime;
+    /**
+     * 注册结束时间--筛选
+     */
+    private String registerEndTime;
     /**
     /**
      * 供应商公司名称
      * 供应商公司名称
      */
      */

+ 40 - 0
src/main/java/com/caimei365/manager/entity/caimei/ReturnData.java

@@ -0,0 +1,40 @@
+package com.caimei365.manager.entity.caimei;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/21
+ */
+@Data
+public class ReturnData {
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 值
+     */
+    private Integer value;
+    /**
+     * seo图片地址
+     */
+    private String seo;
+    /**
+     * 名称集合
+     */
+    private ArrayList<String> names;
+    /**
+     * 值集合
+     */
+    private ArrayList<Integer> values;
+    /**
+     * 备份(第二个值)值集合
+     */
+    private ArrayList<Integer> backupsValues;
+}

+ 5 - 1
src/main/java/com/caimei365/manager/entity/caimei/RetuenEntity.java → src/main/java/com/caimei365/manager/entity/caimei/ReturnEntity.java

@@ -9,11 +9,15 @@ import lombok.Data;
  * @date : 2023/3/16
  * @date : 2023/3/16
  */
  */
 @Data
 @Data
-public class RetuenEntity {
+public class ReturnEntity {
     /**
     /**
      * key
      * key
      */
      */
     private String id;
     private String id;
+    /**
+     * 名称
+     */
+    private String name;
     /**
     /**
      * value
      * value
      */
      */

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

@@ -55,4 +55,16 @@ public class CmPageShopInfo {
      * 时间
      * 时间
      */
      */
     private String accessDate;
     private String accessDate;
+    /**
+     * 商品主图
+     */
+    private String mainImage;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 商品Id
+     */
+    private Integer productId;
 }
 }

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

@@ -43,4 +43,16 @@ public class CmPageShopKeyword {
      * 时间
      * 时间
      */
      */
     private String accessDate;
     private String accessDate;
+    /**
+     * 商品主图
+     */
+    private String mainImage;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 商品Id
+     */
+    private Integer productId;
 }
 }

+ 4 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmRoosInformation.java

@@ -19,6 +19,10 @@ public class CmRoosInformation {
      * 供应商Id
      * 供应商Id
      */
      */
     private Integer shopId;
     private Integer shopId;
+    /**
+     * 营销商品id
+     */
+    private Integer shopProductId;
     /**
     /**
      * 跟进状态 0 已跟进 1 未跟进
      * 跟进状态 0 已跟进 1 未跟进
      */
      */

+ 4 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopInfo.java

@@ -17,6 +17,10 @@ public class CmShopInfo {
      * 供应商Id
      * 供应商Id
      */
      */
     private Integer shopId;
     private Integer shopId;
+    /**
+     * 营销商品id
+     */
+    private Integer shopProductId;
     /**
     /**
      * 文章Id
      * 文章Id
      */
      */

+ 4 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopKeyword.java

@@ -17,6 +17,10 @@ public class CmShopKeyword {
      * 供应商Id
      * 供应商Id
      */
      */
     private Integer shopId;
     private Integer shopId;
+    /**
+     * 营销商品id
+     */
+    private Integer shopProductId;
     /**
     /**
      * 搜索词Id
      * 搜索词Id
      */
      */

+ 4 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopPopUp.java

@@ -15,6 +15,10 @@ public class CmShopPopUp {
      * 供应商Id
      * 供应商Id
      */
      */
     private Integer shopId;
     private Integer shopId;
+    /**
+     * 营销商品id
+     */
+    private Integer shopProductId;
     /**
     /**
      * 图片
      * 图片
      */
      */

+ 57 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopProduct.java

@@ -0,0 +1,57 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2024/1/3
+ */
+@Data
+public class CmShopProduct {
+    /**
+     * id
+     */
+    private Integer id;
+    /**
+     * 供应商潜客统计Id
+     */
+    private Integer statisticsId;
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+    /**
+     * 统计状态 0 统计 1 不统计
+     */
+    private Integer status;
+    /**
+     * 营销logo
+     */
+    private String logo;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 商品图片
+     */
+    private String productImage;
+    /**
+     * 最近报表时间
+     */
+    private String recentlyTime;
+}

+ 8 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopStatistics.java

@@ -38,6 +38,14 @@ public class CmShopStatistics {
      * 统计状态 0 统计 1 不统计
      * 统计状态 0 统计 1 不统计
      */
      */
     private Integer status;
     private Integer status;
+    /**
+     * log
+     */
+    private String logo;
+    /**
+     * 最近报表时间
+     */
+    private String recentlyTime;
     /**
     /**
      * 添加时间
      * 添加时间
      */
      */

+ 13 - 4
src/main/java/com/caimei365/manager/entity/caimei/product/Product.java

@@ -687,11 +687,20 @@ public class Product {
      * 关联标签库字符串
      * 关联标签库字符串
      */
      */
     private String relatedLabels;
     private String relatedLabels;
-
-    //子订单ID
+    /**
+     * 子订单ID
+     */
     private Integer shopOrderID;
     private Integer shopOrderID;
-    //订单商品ID
+    /**
+     * 订单商品ID
+     */
     private Integer orderProductID;
     private Integer orderProductID;
-    //税率
+    /**
+     * 税率
+     */
     private Double taxRate;
     private Double taxRate;
+    /**
+     * 是否支持选择
+     */
+    private Boolean flag;
 }
 }

+ 49 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/AdvertHits.java

@@ -0,0 +1,49 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  全商城点击量
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class AdvertHits {
+
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 广告位置
+     */
+    @ExcelProperty("广告位置/时间")
+    private String position;
+    /**
+     * 首页
+     */
+    @ExcelProperty("首页")
+    private String home;
+    /**
+     * 信息中心
+     */
+    @ExcelProperty("信息中心")
+    private String infoCenter;
+    /**
+     * 点击量
+     */
+    @ExcelProperty("点击量")
+    private Integer hits;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 79 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/ArticleReadVolume.java

@@ -0,0 +1,79 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  推文阅读量
+ *
+ * @author : hzg
+ * @date : 2023/11/22
+ */
+@Data
+public class ArticleReadVolume {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 首发时间
+     */
+    @ExcelProperty("发布时间")
+    private String firstTime;
+    /**
+     * 发文主题
+     */
+    @ExcelProperty("发文主题")
+    private String title;
+    /**
+     * 跳转链接
+     */
+    @ExcelProperty("跳转链接")
+    private String link;
+    /**
+     * 主题简称
+     */
+    @ExcelProperty("主题简称")
+    private String titleReferred;
+    /**
+     * 类型
+     */
+    @ExcelProperty("类型")
+    private String type;
+    /**
+     * 首发时间
+     */
+    @ExcelProperty("首发时间")
+    private String startTime;
+    /**
+     * 文章关键词
+     */
+    @ExcelProperty("文章关键词")
+    private String keyword;
+    /**
+     * 分发渠道
+     */
+    @ExcelProperty("分发渠道")
+    private String channel;
+    /**
+     * 总点击量
+     */
+    @ExcelProperty("总点击量")
+    private Integer wechatNumber;
+    /**
+     * 总展现量
+     */
+    @ExcelProperty("总展现量")
+    private Integer touchNumber;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+
+}

+ 53 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/CmMarketReport.java

@@ -0,0 +1,53 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/15
+ */
+@Data
+public class CmMarketReport {
+    /**
+     * id
+     */
+    private Integer id;
+    /**
+     * 营销id
+     */
+    private Integer marketId;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 报表日期
+     */
+    private String reportDate;
+    /**
+     * 报表生成时间
+     */
+    private String reportTime;
+    /**
+     * 报表名称
+     */
+    private String reportName;
+    /**
+     * 文件名
+     */
+    private String fileName;
+    /**
+     * 是否启用 1 启用 2 未启用
+     */
+    private Integer visible;
+    /**
+     * '添加时间'
+     */
+    private String addTime;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    private Integer delFlag;
+}

+ 77 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/CmMarketShop.java

@@ -0,0 +1,77 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/14
+ */
+@Data
+public class CmMarketShop {
+    /**
+     * id
+     */
+    private Integer id;
+    /**
+     * 供应商id
+     */
+    private Integer shopId;
+    /**
+     * 营销供应商logo
+     */
+    private String logo;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    private Integer delFlag;
+    /**
+     * 供应商名称
+     */
+    private String name;
+    /**
+     * 供应商联系人
+     */
+    private String linkMan;
+    /**
+     * 供应商联系电话
+     */
+    private String contractMobile;
+    /**
+     * 供应商状态
+     */
+    private Integer status;
+    /**
+     * 最近报表时间
+     */
+    private String recentlyTime;
+    /**
+     * 报表名称
+     */
+    private String chartTitle;
+    /**
+     * 展现量
+     */
+    private Integer impressions;
+    /**
+     * 点击量
+     */
+    private Integer hits;
+    /**
+     * 访问量
+     */
+    private Integer visits;
+    /**
+     * 咨询量
+     */
+    private Integer consultation;
+    /**
+     * 报备&成交量
+     */
+    private Integer report;
+}

+ 57 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/FunnelModel.java

@@ -0,0 +1,57 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  用户意向分布
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class FunnelModel {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 是否可见 1 可见 2 不可见
+     */
+    private Integer visible;
+    /**
+     * 展现量
+     */
+    @ExcelProperty("展现量")
+    private Integer impressions;
+    /**
+     * 点击量
+     */
+    @ExcelProperty("点击量")
+    private Integer hits;
+    /**
+     * 访问量
+     */
+    @ExcelProperty("访问量")
+    private Integer visits;
+    /**
+     * 咨询量
+     */
+    @ExcelProperty("咨询量")
+    private Integer consultation;
+    /**
+     * 报备&成交量
+     */
+    @ExcelProperty("报备&成交量")
+    private Integer report;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private Integer delFlag;
+}

+ 49 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Impressions.java

@@ -0,0 +1,49 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  展现量
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Impressions {
+
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 公众号
+     */
+    @ExcelProperty("公众号")
+    private Integer generalNumber;
+    /**
+     * 微博
+     */
+    @ExcelProperty("微博")
+    private Integer microBlog;
+    /**
+     * 小红书
+     */
+    @ExcelProperty("小红书")
+    private Integer redBookNumber;
+    /**
+     * 其它自媒体渠道
+     */
+    @ExcelProperty("其它自媒体渠道")
+    private Integer otherNumber;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 38 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/PageDuration.java

@@ -0,0 +1,38 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  页面平均时长
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class PageDuration {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 页面类型
+     */
+    @ExcelProperty("页面类型")
+    private String pageLabel;
+    /**
+     * 平均停留时间
+     */
+    @ExcelProperty("平均停留时间")
+    private Integer accessDuration;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 48 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Proportion.java

@@ -0,0 +1,48 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  用户来源渠道占比
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Proportion {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 搜索引擎
+     */
+    @ExcelProperty("搜索引擎")
+    private Integer search;
+    /**
+     * 微信平台
+     */
+    @ExcelProperty("微信平台")
+    private Integer general;
+    /**
+     * 微博
+     */
+    @ExcelProperty("微博")
+    private Integer microBlog;
+    /**
+     * 直接访问
+     */
+    @ExcelProperty("直接访问")
+    private Integer directAccess;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 49 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/ReadVolume.java

@@ -0,0 +1,49 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  阅读量
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class ReadVolume {
+
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 公众号
+     */
+    @ExcelProperty("公众号")
+    private Integer generalNumber;
+    /**
+     * 微博
+     */
+    @ExcelProperty("微博")
+    private Integer microBlog;
+    /**
+     * 小红书
+     */
+    @ExcelProperty("小红书")
+    private Integer redBookNumber;
+    /**
+     * 其它自媒体渠道
+     */
+    @ExcelProperty("其它自媒体渠道")
+    private Integer otherNumber;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 33 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Remark.java

@@ -0,0 +1,33 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  咨询数量
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Remark {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 咨询数量
+     */
+    @ExcelProperty("咨询数量")
+    private Integer remarkNumber;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 38 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Stage.java

@@ -0,0 +1,38 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  用户身份分布
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Stage {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 阶段
+     */
+    @ExcelProperty("阶段")
+    private String stage;
+    /**
+     * 主题
+     */
+    @ExcelProperty("主题")
+    private String theme;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 43 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Summary.java

@@ -0,0 +1,43 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  用户类型分布
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Summary {
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 关键词
+     */
+    @ExcelProperty("关键词")
+    private String keyword;
+    /**
+     * SEO排名
+     */
+    @ExcelProperty("SEO排名")
+    private String seoRanking;
+    /**
+     * 占比
+     */
+    @ExcelProperty("月度搜索量")
+    private Integer searchVolume;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 39 - 0
src/main/java/com/caimei365/manager/entity/caimei/shopImport/Visits.java

@@ -0,0 +1,39 @@
+package com.caimei365.manager.entity.caimei.shopImport;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+/**
+ * Description  访问量
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Data
+public class Visits {
+
+    /**
+     * 营销数据 id
+     */
+    private Integer marketReportId;
+    /**
+     * 日期
+     */
+    private String addTime;
+    /**
+     * 机构访问量
+     */
+    @ExcelProperty("机构访问量")
+    private Integer clubNumber;
+    /**
+     * 游客访问量
+     */
+    @ExcelProperty("游客访问量")
+    private Integer touristNumber;
+    /**
+     * 删除标记 0 未删除 1 已删除
+     */
+    @ExcelIgnore
+    private String delFlag;
+}

+ 76 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/AdvertHitsListener.java

@@ -0,0 +1,76 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.AdvertHits;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Slf4j
+public class AdvertHitsListener extends AnalysisEventListener<AdvertHits> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+    // 首页图片集合
+    private Map<String, String> advertImageHomeList;
+    // 信息中心图片集合
+    private Map<String, String> advertImageInfoList;
+
+    private final Integer SIZE = 3;
+
+    private final List<AdvertHits> dataList = new ArrayList();
+
+    public AdvertHitsListener(Integer marketReportId, CmMarketShopDao marketShopDao, Map<String, String> advertImageHomeList, Map<String, String> advertImageInfoList) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+        this.advertImageHomeList = advertImageHomeList;
+        this.advertImageInfoList = advertImageInfoList;
+    }
+
+    @Override
+    public void invoke(AdvertHits data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------广告图点击量----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<AdvertHits> dataList) {
+        log.info("advertImageHomeList==="+advertImageHomeList);
+        log.info("advertImageInfoList==="+advertImageInfoList);
+        for (AdvertHits advertHits : dataList){
+            advertHits.setMarketReportId(marketReportId);
+            advertHits.setHome(advertImageHomeList.get(advertHits.getHome()));
+            advertHits.setInfoCenter(advertImageInfoList.get(advertHits.getInfoCenter()));
+            marketShopDao.insertMarketAdvertHits(advertHits);
+        }
+    }
+}

+ 78 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/ArticleReadVolumeListener.java

@@ -0,0 +1,78 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.ArticleReadVolume;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/22
+ */
+@Slf4j
+public class ArticleReadVolumeListener extends AnalysisEventListener<ArticleReadVolume> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<ArticleReadVolume> dataList = new ArrayList();
+
+    public ArticleReadVolumeListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    /**
+     * 数据解析
+     * @param data
+     * @param analysisContext
+     */
+    @Override
+    public void invoke(ArticleReadVolume data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    /**
+     * 解析完成调用
+     * @param analysisContext
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------推文阅读量----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<ArticleReadVolume> dataList) {
+        dataList.forEach(articleReadVolume -> {
+            articleReadVolume.setMarketReportId(marketReportId);
+            byte[] bytes = articleReadVolume.getTitle().getBytes(StandardCharsets.UTF_8);
+            String decodedString = new String(bytes, StandardCharsets.UTF_8);
+            articleReadVolume.setTitle(decodedString);
+            marketShopDao.insertMarketArticleReadVolume(articleReadVolume);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/FunnelModelListener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.FunnelModel;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class FunnelModelListener extends AnalysisEventListener<FunnelModel> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<FunnelModel> dataList = new ArrayList();
+
+    public FunnelModelListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(FunnelModel data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------漏斗模型数据----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<FunnelModel> dataList) {
+        dataList.forEach(funnelModel -> {
+            funnelModel.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketFunnelModel(funnelModel);
+        });
+    }
+}

+ 72 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/ImpressionsListener.java

@@ -0,0 +1,72 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Impressions;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class ImpressionsListener extends AnalysisEventListener<Impressions> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<Impressions> dataList = new ArrayList();
+
+    public ImpressionsListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    /**
+     * 解析数据
+     * @param data
+     * @param analysisContext
+     */
+    @Override
+    public void invoke(Impressions data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    /**
+     * 解析数据后调用
+     * @param analysisContext
+     */
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------展现量----------");
+        System.out.println("dataList====="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Impressions> dataList) {
+        dataList.forEach(impressions -> {
+            impressions.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketImpressions(impressions);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/PageDurationListener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.PageDuration;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class PageDurationListener extends AnalysisEventListener<PageDuration> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<PageDuration> dataList = new ArrayList();
+
+    public PageDurationListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(PageDuration data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------页面平均时长----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<PageDuration> dataList) {
+        dataList.forEach(pageDuration -> {
+            pageDuration.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketPageDuration(pageDuration);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/ProportionListener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Proportion;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class ProportionListener extends AnalysisEventListener<Proportion> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<Proportion> dataList = new ArrayList();
+
+    public ProportionListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(Proportion data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------访客来源分布----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Proportion> dataList) {
+        dataList.forEach(proportion -> {
+            proportion.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketProportion(proportion);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/ReadVolumeListener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.ReadVolume;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class ReadVolumeListener extends AnalysisEventListener<ReadVolume> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<ReadVolume> dataList = new ArrayList();
+
+    public ReadVolumeListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(ReadVolume data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------阅读量----------");
+        System.out.println("dataList======"+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<ReadVolume> dataList) {
+        dataList.forEach(readVolume -> {
+            readVolume.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketReadVolume(readVolume);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/RemarkListener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Remark;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class RemarkListener extends AnalysisEventListener<Remark> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<Remark> dataList = new ArrayList();
+
+    public RemarkListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(Remark data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------咨询数量----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Remark> dataList) {
+        dataList.forEach(remark -> {
+            remark.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketRemark(remark);
+        });
+    }
+}

+ 66 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/StageListener.java

@@ -0,0 +1,66 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Stage;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Slf4j
+public class StageListener extends AnalysisEventListener<Stage> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<Stage> dataList = new ArrayList();
+
+    public StageListener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(Stage data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------阶段描述----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Stage> dataList) {
+        dataList.forEach( stage -> {
+            log.info("dataList"+dataList.size());
+            stage.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketStage(stage);
+        });
+    }
+}

+ 71 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/SummaryListener.java

@@ -0,0 +1,71 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Summary;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+@Slf4j
+public class SummaryListener extends AnalysisEventListener<Summary> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private Map<String, String> seoImagePathList;
+
+    private final Integer SIZE = 3;
+
+    private final List<Summary> dataList = new ArrayList();
+
+    public SummaryListener(Integer marketReportId, CmMarketShopDao marketShopDao, Map<String, String> seoImagePathList) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+        this.seoImagePathList = seoImagePathList;
+    }
+
+    @Override
+    public void invoke(Summary data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------SEO汇总----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Summary> dataList) {
+        log.info("seoImagePathList===="+seoImagePathList);
+        dataList.forEach(summary -> {
+            summary.setMarketReportId(marketReportId);
+            summary.setSeoRanking(seoImagePathList.get(summary.getSeoRanking()));
+            marketShopDao.insertMarketSummary(summary);
+        });
+    }
+}

+ 63 - 0
src/main/java/com/caimei365/manager/service/caimei/listener/VisitsLisener.java

@@ -0,0 +1,63 @@
+package com.caimei365.manager.service.caimei.listener;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.Visits;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/11/23
+ */
+public class VisitsLisener extends AnalysisEventListener<Visits> {
+
+    private Integer marketReportId;
+
+    private CmMarketShopDao marketShopDao;
+
+    private final Integer SIZE = 3;
+
+    private final List<Visits> dataList = new ArrayList();
+
+    public VisitsLisener(Integer marketReportId, CmMarketShopDao marketShopDao) {
+        this.marketReportId = marketReportId;
+        this.marketShopDao = marketShopDao;
+    }
+
+    @Override
+    public void invoke(Visits data, AnalysisContext analysisContext) {
+        dataList.add(data);
+        if (dataList.size() >= SIZE) {
+            saveData(dataList);
+            dataList.clear();
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+        System.out.println("-----------访问量----------");
+        System.out.println("dataList======="+dataList);
+        saveData(dataList);
+    }
+
+    @Override
+    public boolean hasNext(AnalysisContext analysisContext) {
+        return true;
+    }
+
+    /**
+     * 保存数据
+     */
+    public void saveData(List<Visits> dataList) {
+        dataList.forEach(visits -> {
+            visits.setMarketReportId(marketReportId);
+            marketShopDao.insertMarketVisits(visits);
+        });
+    }
+}

+ 2 - 1
src/main/java/com/caimei365/manager/service/caimei/user/CmBehaviorRecordService.java

@@ -6,6 +6,7 @@ import com.caimei365.manager.entity.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmPageType;
 import com.caimei365.manager.entity.caimei.CmPageType;
 
 
 import java.util.List;
 import java.util.List;
+import java.util.Map;
 
 
 /**
 /**
  * Description
  * Description
@@ -50,7 +51,7 @@ public interface CmBehaviorRecordService {
      * @param pageSize
      * @param pageSize
      * @return
      * @return
      */
      */
-    ResponseJson<PaginationVo<CmBehaviorRecord>> recordList(CmBehaviorRecord cmBehaviorRecord,Integer pageNum, Integer pageSize);
+    ResponseJson<Map<String, Object>> recordList(CmBehaviorRecord cmBehaviorRecord, Integer pageNum, Integer pageSize);
 
 
     /**
     /**
      * 标签库数据
      * 标签库数据

+ 83 - 0
src/main/java/com/caimei365/manager/service/caimei/user/CmMarketShopService.java

@@ -0,0 +1,83 @@
+package com.caimei365.manager.service.caimei.user;
+
+import com.caimei365.manager.entity.PaginationVo;
+import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmShop;
+import com.caimei365.manager.entity.caimei.shopImport.CmMarketReport;
+import com.caimei365.manager.entity.caimei.shopImport.CmMarketShop;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/14
+ */
+public interface CmMarketShopService {
+
+    /**
+     * 上传供应商营销logo
+     * @param id
+     * @param logo
+     * @return
+     */
+    ResponseJson uploadShopLogo(Integer id, String logo);
+
+    /**
+     * 数据报表列表
+     * @param marketId
+     * @param reportName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmMarketReport>> getMarketReport(Integer marketId, String reportName, int pageNum, int pageSize);
+
+    /**
+     * 根据数据报表Id 查询报表数据
+     * @param id
+     * @return
+     */
+    ResponseJson<CmMarketReport> getMarketReportById(Integer id);
+
+    /**
+     * 启用数据报表
+     * @param id
+     * @return
+     */
+    ResponseJson updateMarketReportVisible(Integer id);
+
+    /**
+     * 删除数据报表
+     * @param id
+     * @return
+     */
+    ResponseJson updateMarketReport(Integer id);
+
+    /**
+     * 上传zip、rar文件到服务器并解压
+     * @param reportFile
+     * @return
+     */
+    ResponseJson saveMarketReport(MultipartFile reportFile) throws IOException;
+
+    /**
+     * 保存报表数据
+     * @param marketId
+     * @param reportDate
+     * @param reportName
+     * @param filePath
+     * @return
+     */
+    ResponseJson saveReport(Integer marketId, Integer id, String reportDate, String reportName, String filePath) throws IOException;
+
+    /**
+     * 报表数据预览
+     * @param id
+     * @return
+     */
+    ResponseJson<Map<String, Object>> preview(Integer id);
+}

+ 63 - 8
src/main/java/com/caimei365/manager/service/caimei/user/CustomerService.java

@@ -4,6 +4,9 @@ import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
+
+import java.util.List;
 
 
 /**
 /**
  * Description
  * Description
@@ -42,6 +45,51 @@ public interface CustomerService {
      */
      */
     ResponseJson renewCustomerShop(Integer id, Integer status);
     ResponseJson renewCustomerShop(Integer id, Integer status);
 
 
+    /**
+     * 潜客收集商品列表
+     * @param id
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShopProduct>> getShopProduct(Integer id, Integer productId, String productName, Integer status, int pageNum, int pageSize);
+
+    /**
+     * 商品列表
+     * @param shopId
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<Product>> getProductList(Integer shopId, Integer productId, String productName, int pageNum, int pageSize);
+
+    /**
+     * 保存潜客供应商统计商品
+     * @param statisticsId
+     * @param productIds
+     * @return
+     */
+    ResponseJson saveShopProduct(Integer statisticsId, String productIds);
+
+    /**
+     * 设置潜客商品统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    ResponseJson updateProductStatus(Integer id, Integer status);
+
+    /**
+     * 删除潜客供应商统计商品
+     * @param id
+     * @return
+     */
+    ResponseJson updateShopProduct(Integer id);
+
     /**
     /**
      * 游客统计
      * 游客统计
      * @param cmRoosInformation
      * @param cmRoosInformation
@@ -94,11 +142,11 @@ public interface CustomerService {
 
 
     /**
     /**
      * 添加文章统计
      * 添加文章统计
-     * @param shopId
+     * @param shopProductId
      * @param infoIds
      * @param infoIds
      * @return
      * @return
      */
      */
-    ResponseJson saveShopInfo(Integer shopId, String infoIds);
+    ResponseJson saveShopInfo(Integer shopProductId, String infoIds);
 
 
     /**
     /**
      * 设置统计状态
      * 设置统计状态
@@ -135,11 +183,11 @@ public interface CustomerService {
 
 
     /**
     /**
      * 添加搜索词统计
      * 添加搜索词统计
-     * @param shopId
+     * @param shopProductId
      * @param keyWordIds
      * @param keyWordIds
      * @return
      * @return
      */
      */
-    ResponseJson saveShopKeyword(Integer shopId, String keyWordIds);
+    ResponseJson saveShopKeyword(Integer shopProductId, String keyWordIds);
 
 
     /**
     /**
      * 设置统计状态
      * 设置统计状态
@@ -158,10 +206,10 @@ public interface CustomerService {
 
 
     /**
     /**
      * 弹框数据回显
      * 弹框数据回显
-     * @param shopId
+     * @param shopProductId
      * @return
      * @return
      */
      */
-    ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId);
+    ResponseJson<CmShopPopUp> getShopPopUp(Integer shopProductId);
 
 
     /**
     /**
      * 谈款数据保存
      * 谈款数据保存
@@ -216,6 +264,13 @@ public interface CustomerService {
      */
      */
     ResponseJson delShopAdvertisingImage(Integer id);
     ResponseJson delShopAdvertisingImage(Integer id);
 
 
+    /**
+     * 获取潜客供应商下统计商品
+     * @param shopId
+     * @return
+     */
+    ResponseJson<List<CmShopProduct>> getShopProductList(Integer shopId);
+
     /**
     /**
      * 供应商主页统计
      * 供应商主页统计
      * @param shopId
      * @param shopId
@@ -237,13 +292,13 @@ public interface CustomerService {
      * @param shopId
      * @param shopId
      * @return
      * @return
      */
      */
-    ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize);
+    ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, Integer productId, String startTime, String endTime, Integer pageNum, Integer pageSize);
 
 
     /**
     /**
      * 供应商搜索词统计
      * 供应商搜索词统计
      * @param shopId
      * @param shopId
      * @return
      * @return
      */
      */
-    ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize);
+    ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, Integer productId, String startTime, String endTime, Integer pageNum, Integer pageSize);
 
 
 }
 }

+ 39 - 2
src/main/java/com/caimei365/manager/service/caimei/user/impl/CmBehaviorRecordServiceImpl.java

@@ -7,6 +7,7 @@ import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmPageType;
 import com.caimei365.manager.entity.caimei.CmPageType;
+import com.caimei365.manager.entity.caimei.ReturnEntity;
 import com.caimei365.manager.service.caimei.user.CmBehaviorRecordService;
 import com.caimei365.manager.service.caimei.user.CmBehaviorRecordService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageHelper;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -18,6 +19,8 @@ import java.net.URLDecoder;
 import java.text.ParseException;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * Description
  * Description
@@ -85,8 +88,10 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
         cmBehaviorRecord.setBehaviorType(behaviorType);
         cmBehaviorRecord.setBehaviorType(behaviorType);
         PageHelper.startPage(pageNum, pageSize);
         PageHelper.startPage(pageNum, pageSize);
         if (cmBehaviorRecord.getTodayType() == 0) {
         if (cmBehaviorRecord.getTodayType() == 0) {
+            // 今日数据
             list = cmBehaviorRecordDao.findListToday(cmBehaviorRecord);
             list = cmBehaviorRecordDao.findListToday(cmBehaviorRecord);
         } else {
         } else {
+            // 过往数据
             list = cmBehaviorRecordDao.findList(cmBehaviorRecord);
             list = cmBehaviorRecordDao.findList(cmBehaviorRecord);
         }
         }
         // 总时长
         // 总时长
@@ -162,7 +167,8 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson<PaginationVo<CmBehaviorRecord>> recordList(CmBehaviorRecord cmBehaviorRecord, Integer pageNum, Integer pageSize) {
+    public ResponseJson<Map<String, Object>> recordList(CmBehaviorRecord cmBehaviorRecord, Integer pageNum, Integer pageSize) {
+        Map<String, Object> map = new HashMap<>();
         PageHelper.startPage(pageNum, pageSize);
         PageHelper.startPage(pageNum, pageSize);
         // 详情
         // 详情
         List<CmBehaviorRecord> recordList = cmBehaviorRecordDao.recordList(cmBehaviorRecord);
         List<CmBehaviorRecord> recordList = cmBehaviorRecordDao.recordList(cmBehaviorRecord);
@@ -170,6 +176,9 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
         List<CmBehaviorRecord> reginList = cmBehaviorRecordDao.selRegion(cmBehaviorRecord.getAccessDate());
         List<CmBehaviorRecord> reginList = cmBehaviorRecordDao.selRegion(cmBehaviorRecord.getAccessDate());
         // 供应商信息
         // 供应商信息
         List<CmBehaviorRecord> shopNameList = cmBehaviorRecordDao.behaviorShopNameList();
         List<CmBehaviorRecord> shopNameList = cmBehaviorRecordDao.behaviorShopNameList();
+        // 标签总结
+        List<ReturnEntity> label = new ArrayList<>();
+        AtomicReference<Integer> returnId = new AtomicReference<>(0);
         // 计算访问时长,填入信息
         // 计算访问时长,填入信息
         recordList.forEach(r -> {
         recordList.forEach(r -> {
             r.setProductImage(AppUtils.getImageURL("product", r.getProductImage(), 0, ""));
             r.setProductImage(AppUtils.getImageURL("product", r.getProductImage(), 0, ""));
@@ -216,9 +225,37 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
                 }
                 }
                 r.setRelevanceShop(shopName);
                 r.setRelevanceShop(shopName);
             }
             }
+            if ("6".equals(r.getPageType()) || "8".equals(r.getPageType()) || "9".equals(r.getPageType()) || "11".equals(r.getPageType())) {
+                if(StringUtils.isNotBlank(r.getPageLabel()) && StringUtils.isNotEmpty(r.getPageLabel()) && !label.contains(r.getPageLabel())) {
+                    ReturnEntity retuenEntity = new ReturnEntity();
+                    if (r.getPageLabel().contains(",")) {
+                        String[] split = r.getPageLabel().split(",");
+                        for (String str : split) {
+                            List<String> collect = label.stream().map(ReturnEntity::getValue).collect(Collectors.toList());
+                            if (StringUtils.isNotBlank(str) &&  !collect.contains(str)) {
+                                retuenEntity = new ReturnEntity();
+                                returnId.updateAndGet(v -> v + 1);
+                                retuenEntity.setId(returnId.get().toString());
+                                retuenEntity.setValue(str);
+                                label.add(retuenEntity);
+                            }
+                        }
+                    } else {
+                        List<String> collect = label.stream().map(ReturnEntity::getValue).collect(Collectors.toList());
+                        if (!collect.contains(r.getPageLabel())) {
+                            returnId.updateAndGet(v -> v + 1);
+                            retuenEntity.setId(returnId.get().toString());
+                            retuenEntity.setValue(r.getPageLabel());
+                            label.add(retuenEntity);
+                        }
+                    }
+                }
+            }
         });
         });
         PaginationVo<CmBehaviorRecord> pageData = new PaginationVo<>(recordList);
         PaginationVo<CmBehaviorRecord> pageData = new PaginationVo<>(recordList);
-        return ResponseJson.success(pageData);
+        map.put("page", pageData);
+        map.put("label", label);
+        return ResponseJson.success(map);
     }
     }
 
 
     /**
     /**

+ 684 - 0
src/main/java/com/caimei365/manager/service/caimei/user/impl/CmMarketShopServiceImpl.java

@@ -0,0 +1,684 @@
+package com.caimei365.manager.service.caimei.user.impl;
+
+import cn.hutool.core.util.ZipUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.caimei.utils.MathUtil;
+import com.caimei.utils.StringUtils;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.PaginationVo;
+import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmShop;
+import com.caimei365.manager.entity.caimei.ReturnData;
+import com.caimei365.manager.entity.caimei.ReturnEntity;
+import com.caimei365.manager.entity.caimei.shopImport.*;
+import com.caimei365.manager.service.caimei.listener.*;
+import com.caimei365.manager.service.caimei.user.CmMarketShopService;
+import com.caimei365.manager.utils.FileUtil;
+import com.caimei365.manager.utils.formDataUtils;
+import com.github.pagehelper.PageHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.IOUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/14
+ */
+@Slf4j
+@Service
+public class CmMarketShopServiceImpl implements CmMarketShopService {
+
+    private final static String ZIP_FILE = "zip";
+    private final static String RAR_FILE = "octet";
+
+    private final static String extract = "/mnt/newdatadrive/data/runtime/jar-instance/manager-api/extract";
+
+    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:dd");
+
+    @Resource private CmMarketShopDao marketShopDao;
+
+    @Resource private formDataUtils formDataUtils;
+
+    /**
+     * 上传供应商营销logo
+     *
+     * @param id
+     * @param logo
+     * @return
+     */
+    @Override
+    public ResponseJson uploadShopLogo(Integer id, String logo) {
+        marketShopDao.updateShopLogo(id, logo);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 数据报表列表
+     *
+     * @param marketId
+     * @param reportName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmMarketReport>> getMarketReport(Integer marketId, String reportName, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmMarketReport> marketReport = marketShopDao.getMarketReport(marketId, reportName);
+        /*if (null != marketReport && marketReport.size() > 0) {
+            marketReport.forEach(report -> {
+                try {
+                    if (StringUtils.isNotBlank(report.getReportTime())) {
+                        report.setReportTime(simpleDateFormat.format(simpleDateFormat.parse(report.getReportTime())));
+                    }
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+            });
+        }*/
+        PaginationVo<CmMarketReport> page = new PaginationVo<>(marketReport);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 根据数据报表Id 查询报表数据
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson<CmMarketReport> getMarketReportById(Integer id) {
+        CmMarketReport marketReportById = marketShopDao.getMarketReportById(id);
+        if (null != marketReportById) {
+            try {
+                if (StringUtils.isNotBlank(marketReportById.getReportTime())) {
+                    marketReportById.setReportTime(simpleDateFormat.format(simpleDateFormat.parse(marketReportById.getReportTime())));
+                }
+            } catch (ParseException e) {
+                e.printStackTrace();
+            }
+        }
+        return ResponseJson.success(marketReportById);
+    }
+
+    /**
+     * 启用数据报表
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson updateMarketReportVisible(Integer id) {
+        marketShopDao.updateMarketReportVisible(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除数据报表
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson updateMarketReport(Integer id) {
+        // 删除数据报表
+        marketShopDao.updateMarketReport(id);
+        // 删除数据报表具体数据
+        marketShopDao.updateMarketStage(id);
+        marketShopDao.updateMarketFunnelModel(id);
+        marketShopDao.updateMarketArticleReadVolume(id);
+        marketShopDao.updateMarketImpressions(id);
+        marketShopDao.updateMarketReadVolume(id);
+        marketShopDao.updateMarketSummary(id);
+        marketShopDao.updateMarketVisits(id);
+        marketShopDao.updateMarketProportion(id);
+        marketShopDao.updateMarketPageDuration(id);
+        marketShopDao.updateMarketAdvertHits(id);
+        marketShopDao.updateMarketRemark(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 上传zip、rar文件到服务器并解压
+     *
+     * @param reportFile
+     * @return
+     */
+    @Override
+    public ResponseJson saveMarketReport( MultipartFile reportFile) throws IOException {
+
+        boolean isZipPack = true;
+
+        //不存在则创建
+        File packFile = new File(extract);
+        packFile.delete();
+        if (!packFile.exists()) {
+            boolean mkdirs = packFile.mkdirs();
+        }
+
+        if (reportFile== null) {
+            return ResponseJson.error(-1, "请上传文件", null);
+        }
+        String contentType = reportFile.getContentType();
+        String filename = reportFile.getOriginalFilename();
+        log.info("contentType===="+contentType);
+        //将压缩包保存在指定路径
+        String packFilePath = extract + File.separator + filename;
+        if (contentType.contains(ZIP_FILE)) {
+            //zip解压缩处理
+        } else if (contentType.contains(RAR_FILE)) {
+            //rar解压缩处理
+            isZipPack = false;
+        } else {
+            return ResponseJson.error(-1, "上传的压缩包格式不正确,仅支持rar和zip压缩文件!", null);
+        }
+
+        File file = new File(packFilePath);
+
+        try {
+            reportFile.transferTo(file);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return ResponseJson.error(-1, "压缩文件到:" + extract + " 失败!", null);
+        }
+        if (isZipPack) {
+            //zip压缩包
+            FileUtil.unZip(packFilePath, extract);
+        } else {
+            //rar压缩包
+            FileUtil.unPackRar(file, filename, extract);
+        }
+        //获取压缩包名称
+        filename = filename.substring(0, filename.lastIndexOf("."));
+        log.info("filename===="+filename);
+        log.info("packFilePath===="+packFilePath);
+        if (file.exists()) {
+            file.delete();
+        }
+        String filePath = "";
+        if (isZipPack) {
+            filePath = extract + "/" + filename;
+        } else {
+            filePath = extract + "/" + filename;
+        }
+        return ResponseJson.success(filePath);
+    }
+
+    /**
+     * 保存报表数据
+     *
+     * @param marketId
+     * @param reportDate
+     * @param reportName
+     * @param filePath
+     * @return
+     */
+    @Override
+    public ResponseJson saveReport(Integer marketId, Integer id, String reportDate, String reportName, String filePath) throws IOException {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
+        try {
+            String reportTime = dateFormat.format(dateFormat.parse(reportDate));
+            File file = new File(filePath);
+            if (id == null) {
+                CmMarketReport marketReport = new CmMarketReport();
+                marketReport.setMarketId(marketId);
+                marketReport.setReportDate(reportTime);
+                marketReport.setReportName(reportName);
+                marketReport.setFileName(file.getName());
+                marketShopDao.insertMarketReport(marketReport);
+                // 读取文件,处理数据
+                readFile(marketReport.getId(), filePath);
+                file.delete();
+            } else {
+                // 删除数据报表具体数据
+                marketShopDao.updateMarketStage(id);
+                marketShopDao.updateMarketFunnelModel(id);
+                marketShopDao.updateMarketArticleReadVolume(id);
+                marketShopDao.updateMarketImpressions(id);
+                marketShopDao.updateMarketReadVolume(id);
+                marketShopDao.updateMarketSummary(id);
+                marketShopDao.updateMarketVisits(id);
+                marketShopDao.updateMarketProportion(id);
+                marketShopDao.updateMarketPageDuration(id);
+                marketShopDao.updateMarketAdvertHits(id);
+                marketShopDao.updateMarketRemark(id);
+                // 读取文件,处理数据
+                readFile(id, filePath);
+                file.delete();
+            }
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        File extractFile = new File(extract);
+        extractFile.delete();
+        Path path = Paths.get(extract);
+        try {
+            Files.walk(path)
+                    .sorted(Comparator.reverseOrder())
+                    .map(Path::toFile)
+                    .forEach(File::delete);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 报表数据预览
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson<Map<String, Object>> preview(Integer id) {
+        Map<String, Object> map = new HashMap<>();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
+        // name集合
+        ArrayList<String> name = new ArrayList<>();
+        // value 集合
+        ArrayList<Integer> value = new ArrayList<>();
+        // 备份(第二value)集合
+        ArrayList<Integer> backupsValues = new ArrayList<>();
+        // 唯一name集合
+        Set<String> set = new HashSet<>();
+        // 获取报表对应供应商数据
+        CmMarketShop shopInfo = marketShopDao.getShopInfoById(id);
+        // 获取阶段描述
+        List<Stage> summarize = new ArrayList<>();
+        List<Stage> summarize1 = new ArrayList<>();
+        List<Stage> summarize2 = new ArrayList<>();
+        List<Stage> marketStage = marketShopDao.getMarketStage(id);
+        if (null != marketStage && marketStage.size() > 0) {
+            for (Stage stage : marketStage) {
+                try {
+                    stage.setAddTime(dateFormat.format(dateFormat.parse(stage.getAddTime())));
+                    if ("1".equals(stage.getStage())) {
+                        summarize.add(stage);
+                    }
+                    if ("2".equals(stage.getStage())) {
+                        summarize1.add(stage);
+                    }
+                    if ("3".equals(stage.getStage())) {
+                        summarize2.add(stage);
+                    }
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        map.put("summarize", summarize);
+        map.put("summarize1", summarize1);
+        map.put("summarize2", summarize2);
+        // 获取漏斗模型数据
+        List<FunnelModel> marketFunnelModel = marketShopDao.getMarketFunnelModel(id);
+        int impressions = 0, hits = 0, visits = 0, consultation = 0, report = 0;
+        if (null != marketFunnelModel && marketFunnelModel.size() > 0) {
+            for (FunnelModel funnelModel : marketFunnelModel) {
+                impressions += funnelModel.getImpressions();
+                hits += funnelModel.getHits();
+                visits += funnelModel.getVisits();
+                consultation += funnelModel.getConsultation();
+                report += funnelModel.getReport();
+            }
+        }
+        try {
+            shopInfo.setChartTitle("【"+shopInfo.getName()+"】"+dateFormat.format(dateFormat.parse(shopInfo.getAddTime())) + "数据报表");
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        shopInfo.setImpressions(impressions);
+        shopInfo.setHits(hits);
+        shopInfo.setVisits(visits);
+        shopInfo.setConsultation(consultation);
+        shopInfo.setReport(report);
+        map.put("shopInfo", shopInfo);
+        // 获取推文数据
+        List<ArticleReadVolume> marketArticleReadVolume = marketShopDao.getMarketArticleReadVolume(id);
+        List<ArticleReadVolume> articleReadVolumeList = new ArrayList<>();
+        if (null != marketArticleReadVolume && marketArticleReadVolume.size() > 0) {
+            for (ArticleReadVolume articleReadVolume : marketArticleReadVolume) {
+                if (!set.contains(articleReadVolume.getTitle())) {
+                    set.add(articleReadVolume.getTitle());
+                    articleReadVolumeList.add(articleReadVolume);
+                } else {
+                    // 将有重复的推文数据 总阅读量  总展现量相加为一组数据
+                    for (ArticleReadVolume readVolume : articleReadVolumeList) {
+                        if (articleReadVolume.getTitle().equals(readVolume.getTitle())) {
+                            readVolume.setWechatNumber(MathUtil.sub(readVolume.getWechatNumber(), articleReadVolume.getWechatNumber()).intValue());
+                            readVolume.setTouchNumber(MathUtil.sub(readVolume.getTouchNumber(), articleReadVolume.getTouchNumber()).intValue());
+                        }
+                    }
+                }
+            }
+        }
+        map.put("volumeList", articleReadVolumeList);
+        // 公众号推文数据
+        ReturnData articleReturnData = new ReturnData();
+        if (null != articleReadVolumeList && articleReadVolumeList.size() > 0) {
+            name = new ArrayList<>(articleReadVolumeList.stream().map(ArticleReadVolume::getTitleReferred).collect(Collectors.toList()));
+            articleReturnData.setNames(name);
+            value = new ArrayList<>(articleReadVolumeList.stream().map(ArticleReadVolume::getWechatNumber).collect(Collectors.toList()));
+            articleReturnData.setValues(value);
+            backupsValues = new ArrayList<>(articleReadVolumeList.stream().map(ArticleReadVolume::getTouchNumber).collect(Collectors.toList()));
+            articleReturnData.setBackupsValues(backupsValues);
+        }
+        map.put("wechats", articleReturnData);
+        // 获取展现量数据
+        List<Impressions> marketImpressions = marketShopDao.getMarketImpressions(id);
+        int generalNumber = 0, microBlog = 0, redBookNumber = 0, otherNumber = 0;
+        if (null != marketImpressions && marketImpressions.size() > 0) {
+            for (Impressions imp : marketImpressions) {
+                generalNumber += imp.getGeneralNumber();
+                microBlog += imp.getMicroBlog();
+                redBookNumber += imp.getRedBookNumber();
+                otherNumber += imp.getOtherNumber();
+            }
+        }
+        ReturnData returnData = new ReturnData();
+        name.add("公众号");
+        name.add("微博");
+        name.add("小红书");
+        name.add("其它自媒体渠道");
+        returnData.setNames(name);
+        value.add(generalNumber);
+        value.add(microBlog);
+        value.add(redBookNumber);
+        value.add(otherNumber);
+        returnData.setValues(value);
+        map.put("intention", returnData);
+        // 获取点击量数据
+        name.clear();
+        value.clear();
+        List<ReadVolume> marketReadVolume = marketShopDao.getMarketReadVolume(id);
+        if (null != marketReadVolume && marketReadVolume.size() > 0) {
+            for (ReadVolume readVolume : marketReadVolume) {
+                generalNumber += readVolume.getGeneralNumber();
+                microBlog += readVolume.getMicroBlog();
+                redBookNumber += readVolume.getRedBookNumber();
+                otherNumber += readVolume.getOtherNumber();
+            }
+        }
+        ReturnData readVolumeReturnData = new ReturnData();
+        name.add("公众号");
+        name.add("微博");
+        name.add("小红书");
+        name.add("其它自媒体渠道");
+        returnData.setNames(name);
+        value.add(generalNumber);
+        value.add(microBlog);
+        value.add(redBookNumber);
+        value.add(otherNumber);
+        returnData.setValues(value);
+        map.put("allVisits", readVolumeReturnData);
+        // 获取SEO汇总数据
+        set.clear();
+        List<Summary> marketSummary = marketShopDao.getMarketSummary(id);
+        List<Summary> summaryList = new ArrayList<>();
+        List<ReturnData> returnDataList = new ArrayList<>();
+        if (null != marketSummary && marketSummary.size() > 0) {
+            for (Summary summary : marketSummary) {
+                if (!set.contains(summary.getKeyword())) {
+                    set.add(summary.getKeyword());
+                    summaryList.add(summary);
+                } else {
+                    for (Summary summary1 : summaryList) {
+                        if (summary.getKeyword().equals(summary1.getKeyword())) {
+                            summary1.setSearchVolume(MathUtil.sub(summary1.getSearchVolume(), summary.getSearchVolume()).intValue());
+                        }
+                    }
+                }
+            }
+        }
+        if (null != summaryList && summaryList.size() > 0) {
+            for (Summary summary : summaryList) {
+                ReturnData summaryReturnData = new ReturnData();
+                summaryReturnData.setName(summary.getKeyword());
+                summaryReturnData.setValue(summary.getSearchVolume());
+                summaryReturnData.setSeo(summary.getSeoRanking());
+                returnDataList.add(summaryReturnData);
+            }
+        }
+        map.put("keywordList", summaryList);
+        // 获取访问量数据
+        name.clear();
+        value.clear();
+        List<Visits> marketVisits = marketShopDao.getMarketVisits(id);
+        int clubNumber = 0, touristNumber = 0;
+        if (null != marketVisits && marketVisits.size() > 0) {
+            for (Visits vis : marketVisits) {
+                clubNumber += vis.getClubNumber();
+                touristNumber += vis.getTouristNumber();
+            }
+        }
+        ReturnData visitsReturnData = new ReturnData();
+        name.add("机构访问量");
+        name.add("游客访问量");
+        visitsReturnData.setNames(name);
+        value.add(clubNumber);
+        value.add(touristNumber);
+        visitsReturnData.setValues(value);
+        map.put("stationVisits", visitsReturnData);
+        // 获取访客来源分布数据
+        name.clear();
+        value.clear();
+        List<Proportion> marketProportion = marketShopDao.getMarketProportion(id);
+        int search = 0, general = 0, proMicroBlog = 0, directAccess = 0;
+        if (null != marketProportion && marketProportion.size() > 0) {
+            for (Proportion proportion : marketProportion) {
+                search += proportion.getSearch();
+                general += proportion.getGeneral();
+                proMicroBlog += proportion.getMicroBlog();
+                directAccess += proportion.getDirectAccess();
+            }
+        }
+        ReturnData proportionReturnData = new ReturnData();
+        name.add("搜索引擎");
+        name.add("微信平台");
+        name.add("微博");
+        name.add("直接访问");
+        proportionReturnData.setNames(name);
+        value.add(search);
+        value.add(general);
+        value.add(proMicroBlog);
+        value.add(directAccess);
+        proportionReturnData.setValues(value);
+        map.put("proportion", proportionReturnData);
+        // 获取页面平均访问时长数据
+        set.clear();
+        List<PageDuration> marketPageDuration = marketShopDao.getMarketPageDuration(id);
+        List<PageDuration> pageDurationList = new ArrayList<>();
+        if (null != marketPageDuration && marketPageDuration.size() > 0) {
+            for (PageDuration pageDuration : marketPageDuration) {
+                if (!set.contains(pageDuration.getPageLabel())) {
+                    set.add(pageDuration.getPageLabel());
+                    pageDurationList.add(pageDuration);
+                } else {
+                    for (PageDuration pageDuration1 : pageDurationList) {
+                        if (pageDuration.getPageLabel().equals(pageDuration1.getPageLabel())) {
+                            pageDuration1.setAccessDuration(MathUtil.sub(pageDuration1.getAccessDuration(), pageDuration.getAccessDuration()).intValue());
+                        }
+                    }
+                }
+            }
+        }
+        ReturnData pageDurationReturnData = new ReturnData();
+        name = new ArrayList<>(set);
+        pageDurationReturnData.setNames(name);
+        value = new ArrayList<>(pageDurationList.stream().map(PageDuration::getAccessDuration).collect(Collectors.toList()));
+        pageDurationReturnData.setValues(value);
+
+        map.put("visitTimes", pageDurationReturnData);
+        // 获取广告图点击量数据
+        List<AdvertHits> marketAdvertHits = marketShopDao.getMarketAdvertHits(id);
+        map.put("bannerList", marketAdvertHits);
+        // 获取咨询数量数据
+        name.clear();
+        value.clear();
+        List<Remark> marketRemark = marketShopDao.getMarketRemark(id);
+        if (null != marketRemark && marketRemark.size() > 0) {
+            for (Remark remark : marketRemark) {
+                try {
+                    name.add(dateFormat.format(dateFormat.parse(remark.getAddTime())));
+                    value.add(remark.getRemarkNumber());
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        ReturnData remarkReturnData = new ReturnData();
+        remarkReturnData.setNames(name);
+        remarkReturnData.setValues(value);
+        map.put("leadUserMonthly", remarkReturnData);
+        String accessDate = "";
+        try {
+            dateFormat.format(dateFormat.parse(shopInfo.getAddTime()));
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        // 供应商相关标签
+        List<String> shopKeyword = marketShopDao.getShopKeyword(shopInfo.getShopId());
+
+        Map<String, Integer> regionMap = new HashMap<>();
+        // 访问供应商用户对应身份
+        List<ReturnEntity> userIdentity = new ArrayList<>();
+        // 访问供应商用户对应机构类型
+        List<ReturnEntity> clubType = new ArrayList<>();
+        if (StringUtils.isNotBlank(accessDate) && StringUtils.isNotEmpty(accessDate)) {
+            // 访问供应商用户对于所在地区
+            List<String> region = marketShopDao.getRegion(accessDate, shopKeyword);
+            Set<String> province = new HashSet<>();
+            String com = "";
+            for (String str : region ) {
+                String trim = str.trim();
+                com = trim.substring(0, 2);
+                province.add(com);
+            }
+            for (String str : province) {
+                List<String> collect = region.stream().filter(pro -> pro.substring(0, 3).contains(str)).collect(Collectors.toList());
+                regionMap.put(str, collect.size());
+            }
+            userIdentity = marketShopDao.getUserIdentity(accessDate, shopKeyword);
+            clubType = marketShopDao.getClubType(accessDate, shopKeyword);
+        }
+        map.put("regionMap", regionMap);
+        map.put("userIdentity", userIdentity);
+        map.put("clubType", clubType);
+        return ResponseJson.success(map);
+    }
+
+    /**
+     * 读取文件夹数据————指定格式 (营销供应商)
+     * @param marketReportId
+     * @param filePath
+     * @throws IOException
+     */
+    private void readFile(Integer marketReportId, String filePath) throws IOException {
+        // SEO 图片集合
+        Map<String, String> seoImagePathList = new HashMap<>();
+        // 广告图点击量 首页图片集合
+        Map<String, String> advertImageHomeList = new HashMap<>();
+        // 广告图点击量 信息中心图片集合
+        Map<String, String> advertImageInfoList = new HashMap<>();
+        File file = new File(filePath);
+        if (file.exists() && file.isDirectory()) {
+            for (File fileSpecific: file.listFiles()) {
+                if (fileSpecific.getName().equals("SEO汇总图片") && fileSpecific.exists() && fileSpecific.isDirectory()) {
+                    for (File fileSpecificContain : fileSpecific.listFiles()) {
+                        if (fileSpecificContain.getName().contains("seo")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片名称需与 SEO 列表名称一致
+                            MultipartFile filex = FileUtil.fileToMultipartFileConverter(fileSpecificContain);
+                            String seoImagePath = formDataUtils.saveShopFile(filex);
+                            String name = fileSpecificContain.getName().substring(0, fileSpecificContain.getName().lastIndexOf("."));
+                            seoImagePathList.put(name, seoImagePath);
+                        }
+                    }
+                }
+                log.info("fileSpecific.getName()======"+fileSpecific.getName());
+                if (fileSpecific.getName().equals("advert广告图片") && fileSpecific.exists() && fileSpecific.isDirectory()) {
+                    for (File fileSpecificContain : fileSpecific.listFiles()) {
+                        log.info("fileSpecificContain.getName()======"+fileSpecificContain.getName());
+                        if (fileSpecificContain.getName().contains("首页")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片名称需与 广告图点击量 列表名称一致
+                            MultipartFile filex = FileUtil.fileToMultipartFileConverter(fileSpecificContain);
+                            String advertImagePath = formDataUtils.saveShopFile(filex);
+                            String name = fileSpecificContain.getName().substring(0, fileSpecificContain.getName().lastIndexOf("."));
+                            advertImageHomeList.put(name, advertImagePath);
+                        }
+                        if (fileSpecificContain.getName().contains("信息中心")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片名称需与 广告图点击量 列表名称一致
+                            MultipartFile filex = FileUtil.fileToMultipartFileConverter(fileSpecificContain);
+                            String advertImagePath = formDataUtils.saveShopFile(filex);
+                            String name = fileSpecificContain.getName().substring(0, fileSpecificContain.getName().lastIndexOf("."));
+                            advertImageInfoList.put(name, advertImagePath);
+                        }
+                    }
+                }
+            }
+            // 读取完图片文件后在读取数据文件 xlsx
+            for (File fileSpecific: file.listFiles()) {
+                if (fileSpecific.getName().endsWith(".xlsx") || fileSpecific.getName().endsWith(".xls")) {
+                    readExcel(marketReportId, fileSpecific, seoImagePathList, advertImageHomeList, advertImageInfoList);
+                }
+            }
+        }
+        file.delete();
+    }
+
+    /**
+     * 多sheet excel文件读取 -- 指定sheet名称  多sheet读取必须多次创建文件流
+     * @param marketReportId
+     * @param file
+     * @param seoImagePathList
+     * @param advertImageHomeList
+     * @param advertImageInfoList
+     * @throws IOException
+     */
+    private void readExcel(Integer marketReportId, File file, Map<String, String> seoImagePathList, Map<String, String> advertImageHomeList, Map<String, String> advertImageInfoList) throws IOException {
+        String excelType = "XLSX";
+        if (file.getName().endsWith(".xls")) {
+            excelType = "XLS";
+        }
+        MultipartFile multipartFile = FileUtil.fileToMultipartFileConverter(file);
+        InputStream inputStream = new BufferedInputStream(multipartFile.getInputStream());
+        InputStream is = inputStream;
+        EasyExcel.read(is, Stage.class, new StageListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("阶段描述").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, FunnelModel.class, new FunnelModelListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("漏斗模型数据").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, ArticleReadVolume.class, new ArticleReadVolumeListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("推文数据").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Impressions.class, new ImpressionsListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("展现量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, ReadVolume.class, new ReadVolumeListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("点击量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Summary.class, new SummaryListener(marketReportId, marketShopDao, seoImagePathList)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("SEO汇总").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Visits.class, new VisitsLisener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("访问量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Proportion.class, new ProportionListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("访客来源分布").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, PageDuration.class, new PageDurationListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("页面平均时长").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, AdvertHits.class, new AdvertHitsListener(marketReportId, marketShopDao, advertImageHomeList, advertImageInfoList)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("广告图点击量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Remark.class, new RemarkListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("咨询数量").doRead();
+    }
+
+}

+ 145 - 12
src/main/java/com/caimei365/manager/service/caimei/user/impl/CustomerServiceImpl.java

@@ -2,12 +2,15 @@ package com.caimei365.manager.service.caimei.user.impl;
 
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
+import com.caimei.utils.AppUtils;
+import com.caimei.utils.StringUtil;
 import com.caimei365.manager.config.security.JwtLoginFilter;
 import com.caimei365.manager.config.security.JwtLoginFilter;
 import com.caimei365.manager.dao.user.CustomerServiceDao;
 import com.caimei365.manager.dao.user.CustomerServiceDao;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.ResponseJson;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageHelper;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -106,6 +109,113 @@ public class CustomerServiceImpl implements CustomerService {
         return ResponseJson.success();
         return ResponseJson.success();
     }
     }
 
 
+    /**
+     * 潜客收集商品列表
+     *
+     * @param id
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShopProduct>> getShopProduct(Integer id, Integer productId, String productName, Integer status, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShopProduct> shopProductList = customerServiceDao.getShopProduct(id, productId, productName, status);
+        shopProductList.forEach(product -> {
+            if (StringUtil.isNotBlank(product.getProductImage())) {
+                product.setProductImage(AppUtils.getImageURL("product", product.getProductImage(), 0, "wwwServer"));
+                if (!product.getProductImage().contains("https")) {
+                    product.setProductImage("https://admin.caimei365.com/" + product.getProductImage());
+                }
+            }
+        });
+        PaginationVo<CmShopProduct> page = new PaginationVo<>(shopProductList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 商品列表
+     *
+     * @param shopId
+     * @param productId
+     * @param productName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<Product>> getProductList(Integer shopId, Integer productId, String productName, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        // 供应商商品
+        List<Product> productList = customerServiceDao.getProductList(shopId, productId, productName);
+        // 供应商被选中的商品Id集合
+        List<Integer> productIds = customerServiceDao.getProductIds(shopId);
+        productList.forEach(product -> {
+            if (StringUtil.isNotBlank(product.getMainImage())) {
+                product.setMainImage(AppUtils.getImageURL("product", product.getMainImage(), 0, "wwwServer"));
+                if (!product.getMainImage().contains("https")) {
+                    product.setMainImage("https://admin.caimei365.com/" + product.getMainImage());
+                }
+            }
+            if (productIds.contains(product.getProductId())) {
+                product.setFlag(false);
+            } else {
+                product.setFlag(true);
+            }
+        });
+        PaginationVo<Product> page = new PaginationVo<>(productList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 保存潜客供应商统计商品
+     *
+     * @param statisticsId
+     * @param productIds
+     * @return
+     */
+    @Override
+    public ResponseJson saveShopProduct(Integer statisticsId, String productIds) {
+        if (productIds.contains(",")) {
+            // 多商品
+            String[] split = productIds.split(",");
+            for (String productId : split) {
+                customerServiceDao.insertShopProduct(statisticsId, Integer.parseInt(productId));
+            }
+        } else {
+            // 单商品
+            customerServiceDao.insertShopProduct(statisticsId, Integer.parseInt(productIds));
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 设置潜客商品统计状态
+     *
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson updateProductStatus(Integer id, Integer status) {
+        customerServiceDao.updateProductStatus(id, status);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除潜客供应商统计商品
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson updateShopProduct(Integer id) {
+        customerServiceDao.updateShopProduct(id);
+        return ResponseJson.success();
+    }
+
     /**
     /**
      * 游客统计
      * 游客统计
      *
      *
@@ -242,7 +352,7 @@ public class CustomerServiceImpl implements CustomerService {
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson saveShopInfo(Integer shopId, String infoIds) {
+    public ResponseJson saveShopInfo(Integer shopProductId, String infoIds) {
         List<String> infoId = new ArrayList<>();
         List<String> infoId = new ArrayList<>();
         if (infoIds.contains(",")) {
         if (infoIds.contains(",")) {
             infoId = Arrays.asList(infoIds.split(","));
             infoId = Arrays.asList(infoIds.split(","));
@@ -251,7 +361,7 @@ public class CustomerServiceImpl implements CustomerService {
         }
         }
         for (String s : infoId) {
         for (String s : infoId) {
             CmShopInfo shopInfo = new CmShopInfo();
             CmShopInfo shopInfo = new CmShopInfo();
-            shopInfo.setShopId(shopId);
+            shopInfo.setShopProductId(shopProductId);
             shopInfo.setInfoId(Integer.parseInt(s));
             shopInfo.setInfoId(Integer.parseInt(s));
             shopInfo.setStatus(0);
             shopInfo.setStatus(0);
             shopInfo.setDelFlag(0);
             shopInfo.setDelFlag(0);
@@ -328,12 +438,12 @@ public class CustomerServiceImpl implements CustomerService {
     /**
     /**
      * 添加搜索词统计
      * 添加搜索词统计
      *
      *
-     * @param shopId
+     * @param shopProductId
      * @param keyWordIds
      * @param keyWordIds
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson saveShopKeyword(Integer shopId, String keyWordIds) {
+    public ResponseJson saveShopKeyword(Integer shopProductId, String keyWordIds) {
         List<String> keyWordId = new ArrayList<>();
         List<String> keyWordId = new ArrayList<>();
         if (keyWordIds.contains(",")) {
         if (keyWordIds.contains(",")) {
             keyWordId = Arrays.asList(keyWordIds.split(","));
             keyWordId = Arrays.asList(keyWordIds.split(","));
@@ -342,7 +452,7 @@ public class CustomerServiceImpl implements CustomerService {
         }
         }
         for (String s : keyWordId) {
         for (String s : keyWordId) {
             CmShopKeyword shopKeyword = new CmShopKeyword();
             CmShopKeyword shopKeyword = new CmShopKeyword();
-            shopKeyword.setShopId(shopId);
+            shopKeyword.setShopProductId(shopProductId);
             shopKeyword.setSearchId(Integer.parseInt(s));
             shopKeyword.setSearchId(Integer.parseInt(s));
             shopKeyword.setStatus(0);
             shopKeyword.setStatus(0);
             shopKeyword.setDelFlag(0);
             shopKeyword.setDelFlag(0);
@@ -379,12 +489,12 @@ public class CustomerServiceImpl implements CustomerService {
     /**
     /**
      * 弹框数据回显
      * 弹框数据回显
      *
      *
-     * @param shopId
+     * @param shopProductId
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId) {
-        return ResponseJson.success(customerServiceDao.getShopPopUp(shopId));
+    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopProductId) {
+        return ResponseJson.success(customerServiceDao.getShopPopUp(shopProductId));
     }
     }
 
 
     /**
     /**
@@ -504,6 +614,17 @@ public class CustomerServiceImpl implements CustomerService {
         return ResponseJson.success();
         return ResponseJson.success();
     }
     }
 
 
+    /**
+     * 获取潜客供应商下统计商品
+     *
+     * @param shopId
+     * @return
+     */
+    @Override
+    public ResponseJson<List<CmShopProduct>> getShopProductList(Integer shopId) {
+        return ResponseJson.success(customerServiceDao.getShopProductList(shopId));
+    }
+
     /**
     /**
      * 供应商主页统计
      * 供应商主页统计
      *
      *
@@ -551,11 +672,17 @@ public class CustomerServiceImpl implements CustomerService {
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, Integer productId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
         PageHelper.startPage(pageNum, pageSize);
         PageHelper.startPage(pageNum, pageSize);
-        List<CmPageShopInfo> pageShopInfo = customerServiceDao.getPageShopInfo(shopId, startTime, endTime);
+        List<CmPageShopInfo> pageShopInfo = customerServiceDao.getPageShopInfo(shopId, productId, startTime, endTime);
         pageShopInfo.forEach(shop -> {
         pageShopInfo.forEach(shop -> {
             shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
             shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+            if (StringUtil.isNotBlank(shop.getMainImage())) {
+                shop.setMainImage(AppUtils.getImageURL("product", shop.getMainImage(), 0, "wwwServer"));
+                if (!shop.getMainImage().contains("https")) {
+                    shop.setMainImage("https://admin.caimei365.com/" + shop.getMainImage());
+                }
+            }
         });
         });
         PaginationVo<CmPageShopInfo> page = new PaginationVo<>(pageShopInfo);
         PaginationVo<CmPageShopInfo> page = new PaginationVo<>(pageShopInfo);
         return ResponseJson.success(page);
         return ResponseJson.success(page);
@@ -570,11 +697,17 @@ public class CustomerServiceImpl implements CustomerService {
      * @return
      * @return
      */
      */
     @Override
     @Override
-    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, Integer productId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
         PageHelper.startPage(pageNum, pageSize);
         PageHelper.startPage(pageNum, pageSize);
-        List<CmPageShopKeyword> pageShopKeyword = customerServiceDao.getPageShopKeyword(shopId, startTime, endTime);
+        List<CmPageShopKeyword> pageShopKeyword = customerServiceDao.getPageShopKeyword(shopId, productId, startTime, endTime);
         pageShopKeyword.forEach(shop -> {
         pageShopKeyword.forEach(shop -> {
             shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
             shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+            if (StringUtil.isNotBlank(shop.getMainImage())) {
+                shop.setMainImage(AppUtils.getImageURL("product", shop.getMainImage(), 0, "wwwServer"));
+                if (!shop.getMainImage().contains("https")) {
+                    shop.setMainImage("https://admin.caimei365.com/" + shop.getMainImage());
+                }
+            }
         });
         });
         PaginationVo<CmPageShopKeyword> page = new PaginationVo<>(pageShopKeyword);
         PaginationVo<CmPageShopKeyword> page = new PaginationVo<>(pageShopKeyword);
         return ResponseJson.success(page);
         return ResponseJson.success(page);

+ 78 - 0
src/main/java/com/caimei365/manager/utils/ExtractCallback.java

@@ -0,0 +1,78 @@
+package com.caimei365.manager.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import net.sf.sevenzipjbinding.*;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/20
+ */
+@Slf4j
+public class ExtractCallback implements IArchiveExtractCallback {
+    private final IInArchive inArchive;
+    private final String extractPath;
+    public ExtractCallback(IInArchive inArchive, String extractPath) {
+        this.inArchive = inArchive;
+        if (!extractPath.endsWith("/") && !extractPath.endsWith("\\")) {
+            extractPath += File.separator;
+        }
+        this.extractPath = extractPath;
+    }
+
+    @Override
+    public void setTotal(long total) {
+
+    }
+
+    @Override
+    public void setCompleted(long complete) {
+
+    }
+
+    @Override
+    public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
+        return data -> {
+            String filePath = inArchive.getStringProperty(index, PropID.PATH);
+            FileOutputStream fos = null;
+            try {
+                File path = new File(extractPath + filePath);
+                if(!path.getParentFile().exists()){
+                    path.getParentFile().mkdirs();
+                }
+
+                if(!path.exists()){
+                    path.createNewFile();
+                }
+                fos = new FileOutputStream(path, true);
+                fos.write(data);
+            } catch (IOException e) {
+                log.info("IOException while extracting " + filePath);
+            } finally{
+                try {
+                    if(fos != null){
+                        fos.flush();
+                        fos.close();
+                    }
+                } catch (IOException e) {
+                    log.error("Could not close FileOutputStream", e);
+                }
+            }
+            return data.length;
+        };
+    }
+
+    @Override
+    public void prepareOperation(ExtractAskMode extractAskMode) {
+
+    }
+
+    @Override
+    public void setOperationResult(ExtractOperationResult extractOperationResult) {
+    }
+}

+ 130 - 0
src/main/java/com/caimei365/manager/utils/FileUtil.java

@@ -0,0 +1,130 @@
+package com.caimei365.manager.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import net.lingala.zip4j.core.ZipFile;
+import net.sf.sevenzipjbinding.ArchiveFormat;
+import net.sf.sevenzipjbinding.IInArchive;
+import net.sf.sevenzipjbinding.SevenZip;
+import net.sf.sevenzipjbinding.SevenZipException;
+import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Description
+ *
+ * @author : hzg
+ * @date : 2023/12/19
+ */
+@Slf4j
+public class FileUtil {
+
+    /**
+     * 将file 文件转为 MultipartFile 文件
+     * @param file
+     * @return
+     * @throws IOException
+     */
+    public static MultipartFile fileToMultipartFileConverter(File file) throws IOException {
+        DiskFileItem diskFileItem = new DiskFileItem("File", "application/octet-stream", true, file.getName(), (int) file.length(), file.getParentFile());
+        try(InputStream is = new FileInputStream(file)) {
+            diskFileItem.getOutputStream().write(IOUtils.toByteArray(is));
+        }
+        return new CommonsMultipartFile(diskFileItem);
+    }
+
+
+
+    /**
+     * zip文件解压
+     *
+     * @param destPath 解压文件路径
+     * @param zipFilePath  压缩文件路径
+     */
+    public static void unZip(String zipFilePath, String destPath) throws IOException {
+        File destDir = new File(destPath);
+        if (!destDir.exists()) {
+            destDir.mkdir();
+        }
+        ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath), Charset.forName("GBK"));
+        ZipEntry entry = zipIn.getNextEntry();
+        while (entry != null) {
+            String filePath = destPath + File.separator + entry.getName();
+            if (!entry.isDirectory()) {
+                File file = new File(filePath);
+                file.getParentFile().mkdirs();
+                try (FileOutputStream fos = new FileOutputStream(file)) {
+                    byte[] bytes = new byte[4096];
+                    int length;
+                    while ((length = zipIn.read(bytes)) != -1) {
+                        fos.write(bytes, 0, length);
+                    }
+                }
+            } else {
+                File dir = new File(filePath);
+                dir.mkdir();
+            }
+            zipIn.closeEntry();
+            entry = zipIn.getNextEntry();
+        }
+        zipIn.close();
+    }
+
+    /**
+     * zip文件解压
+     *
+     * @param destPath 解压文件路径
+     * @param zipFile  压缩文件
+     */
+    public static void unPackZip(File zipFile, String destPath) {
+        try {
+            ZipFile zip = new ZipFile(zipFile);
+            /*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
+            zip.setFileNameCharset("GBK");
+            log.info("begin unpack zip file....");
+            zip.extractAll(destPath);
+        } catch (Exception e) {
+            log.error("解压失败:", e.getMessage(), e);
+        }
+    }
+
+    /**
+     * rar文件解压
+     *
+     * @param rarFile  rar压缩包
+     * @param rarFile  解压保存路径下属名称
+     * @param destPath 解压保存路径
+     */
+    public static void unPackRar(File rarFile, String filename, String destPath) {
+        try {
+            // f -  压缩文件
+            RandomAccessFile randomAccessFile = new RandomAccessFile(rarFile.getAbsolutePath(), "r");
+            IInArchive archive = SevenZip.openInArchive(ArchiveFormat.RAR5,  new RandomAccessFileInStream(randomAccessFile));
+            // 解压文件路径
+            File zdir = new File(destPath);
+            if (!zdir.exists() || !zdir.isDirectory()) {
+                zdir.mkdir();
+            }
+
+            int[] in = new int[archive.getNumberOfItems()];
+            for(int i=0;i<in.length;i++){
+                in[i] = i;
+            }
+            archive.extract(in, false, new ExtractCallback(archive, zdir.getAbsolutePath()));
+            archive.close();
+            randomAccessFile.close();
+        } catch (FileNotFoundException | SevenZipException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 13 - 2
src/main/java/com/caimei365/manager/utils/formDataUtils.java

@@ -102,6 +102,17 @@ public class formDataUtils {
         return file1;
         return file1;
     }
     }
 
 
-
-
+    public String saveShopFile(MultipartFile file) throws IOException {
+        String originalFilename = file.getOriginalFilename();
+        String randomUUID = UUID.randomUUID().toString();
+        int index = originalFilename.lastIndexOf(".");
+        String exet = originalFilename.substring(index);
+        String filePath = "/mnt/newdatadrive/data/runtime/jar-instance/manager-api/tempImage/";
+        filePath += "\\" + randomUUID + exet;
+        file.transferTo(new File(filePath));
+        log.info(">>>>>>>>>>>>>>>>图片上传路径:" + filePath);
+        String file1 = client.uploadFile(filePath);
+        file1 = imageDomain + "/" + file1;
+        return file1;
+    }
 }
 }

+ 101 - 81
src/main/resources/mapper/CmBehaciorRecordDao.xml

@@ -13,7 +13,7 @@
         b.accessDate
         b.accessDate
     </sql>
     </sql>
 
 
-    <select id="getkeyword" resultType="com.caimei365.manager.entity.caimei.RetuenEntity">
+    <select id="getkeyword" resultType="com.caimei365.manager.entity.caimei.ReturnEntity">
         select
         select
             id,
             id,
             keyword as value
             keyword as value
@@ -39,160 +39,180 @@
 
 
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         SELECT
         SELECT
-        IP as ip,
-        userID as userId,
-        clubID as clubId,
-        lastAccessTime,
-        companyType,
-        corporateName,
-        contacts,
-        phoneNumber,
-        spName,
-        number as numbers,
-        consultName,
-        consultMobile,
-        productID,
-        accessTime,
-        accessDuration,
-        accessDate,
-        accessClient,
-        region,
-        label,
-        headUserId,
-        productArchiveId,
-        relevanceShop,
-        addTime
-        FROM cm_behavior_record_index
+        cbri.IP as ip,
+        cbri.userID as userId,
+        cbri.clubID as clubId,
+        cbri.lastAccessTime,
+        cbri.companyType,
+        cbri.corporateName,
+        cbri.contacts,
+        cbri.phoneNumber,
+        cbri.spName,
+        cbri.number as numbers,
+        cbri.consultName,
+        cbri.consultMobile,
+        cbri.productID,
+        cbri.accessTime,
+        cbri.accessDuration,
+        cbri.accessDate,
+        cbri.accessClient,
+        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
         <where>
         <where>
-            delFlag = 0
+            cbri.delFlag = 0
+            <if test="clubId != null">
+                AND cbri.clubId = #{clubId}
+            </if>
             <if test="ip != null and ip != ''">
             <if test="ip != null and ip != ''">
-                AND IP = #{ip}
+                AND cbri.IP = #{ip}
             </if>
             </if>
             <if test="corporateName != null and corporateName != ''">
             <if test="corporateName != null and corporateName != ''">
-                AND (corporateName like concat('%',#{corporateName},'%') or contacts like concat('%',#{corporateName},'%'))
+                AND (cbri.corporateName like concat('%',#{corporateName},'%') OR cbri.consultName LIKE concat('%',#{corporateName},'%') or cbri.contacts like concat('%',#{corporateName},'%'))
             </if>
             </if>
             <if test="companyType != null and companyType != ''">
             <if test="companyType != null and companyType != ''">
-                AND companyType = #{companyType}
+                AND cbri.companyType = #{companyType}
             </if>
             </if>
             <if test="accessClient != null and accessClient != ''">
             <if test="accessClient != null and accessClient != ''">
-                AND accessClient =#{accessClient}
+                AND cbri.accessClient =#{accessClient}
             </if>
             </if>
             <if test="contacts != null and contacts != ''">
             <if test="contacts != null and contacts != ''">
-                AND (corporateName like concat('%',#{contacts},'%') or contacts like concat('%',#{contacts},'%'))
+                AND (cbri.corporateName like concat('%',#{contacts},'%') or cbri.contacts like concat('%',#{contacts},'%'))
             </if>
             </if>
             <if test="phoneNumber != null and phoneNumber != ''">
             <if test="phoneNumber != null and phoneNumber != ''">
-                AND phoneNumber = #{phoneNumber}
+                AND cbri.phoneNumber = #{phoneNumber}
             </if>
             </if>
             <if test="spName != null and spName != ''">
             <if test="spName != null and spName != ''">
-                AND spName = #{spName}
+                AND cbri.spName = #{spName}
             </if>
             </if>
             <if test="headUserId != null and headUserId != ''">
             <if test="headUserId != null and headUserId != ''">
-                AND headUserId = #{headUserId}
+                AND cbri.headUserId = #{headUserId}
             </if>
             </if>
             <if test="productArchiveId != null and productArchiveId != ''">
             <if test="productArchiveId != null and productArchiveId != ''">
-                AND productArchiveId = #{productArchiveId}
+                AND cbri.productArchiveId = #{productArchiveId}
             </if>
             </if>
             <if test="relevanceShop != null and relevanceShop != ''">
             <if test="relevanceShop != null and relevanceShop != ''">
-                AND (relevanceShop like concat('%',#{relevanceShop},'%')
+                AND (cbri.relevanceShop like concat('%',#{relevanceShop},'%')
                     <if test="behaviorType == 2">
                     <if test="behaviorType == 2">
-                        or behaviorType = #{behaviorType}
+                        or cbri.behaviorType = #{behaviorType}
                     </if>
                     </if>
                     )
                     )
             </if>
             </if>
             <if test="labels != null and labels.size > 0">
             <if test="labels != null and labels.size > 0">
                 AND
                 AND
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
-                    label like concat('%',#{label},'%')
+                    cbri.label like concat('%',#{label},'%')
                 </foreach>
                 </foreach>
             </if>
             </if>
             <if test="pageLabels != null and pageLabels != ''">
             <if test="pageLabels != null and pageLabels != ''">
-                AND pageLabels like concat('%', #{pageLabels}, '%')
+                AND cbri.pageLabels like concat('%', #{pageLabels}, '%')
             </if>
             </if>
                 <if test="pageTypes != null and pageTypes != ''">
                 <if test="pageTypes != null and pageTypes != ''">
-                AND pageTypes like concat('%', #{pageTypes}, '%')
+                AND cbri.pageTypes like concat('%', #{pageTypes}, '%')
             </if>
             </if>
             <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
-                AND accessDate between #{startTime} and #{endTime}
+                AND cbri.accessDate between #{startTime} and #{endTime}
+            </if>
+            <if test="registerStartTime != null and registerStartTime != ''">
+                AND u.registerTime <![CDATA[ >= ]]> #{registerStartTime}
+            </if>
+            <if test="registerEndTime != null and registerEndTime != ''">
+                AND u.registerTime <![CDATA[ <= ]]> #{registerEndTime}
             </if>
             </if>
         </where>
         </where>
-        ORDER BY accessTime DESC
+        ORDER BY cbri.accessTime DESC
         <if test="exportType == 1">
         <if test="exportType == 1">
             limit 5000
             limit 5000
         </if>
         </if>
     </select>
     </select>
     <select id="findListToday" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
     <select id="findListToday" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         SELECT
         SELECT
-        IP as ip,
-        userID as userId,
-        clubID as clubId,
-        lastAccessTime,
-        companyType,
-        corporateName,
-        contacts,
-        phoneNumber,
-        spName,
-        number as numbers,
-        consultName,
-        consultMobile,
-        accessTime,
-        accessDuration,
-        accessDate,
-        accessClient,
-        region,
-        label,
-        relevanceShop,
-        headUserId,
-        productArchiveId,
-        addTime
-        FROM cm_behavior_record_today
+        cbrt.IP as ip,
+        cbrt.userID as userId,
+        cbrt.clubID as clubId,
+        cbrt.lastAccessTime,
+        cbrt.companyType,
+        cbrt.corporateName,
+        cbrt.contacts,
+        cbrt.phoneNumber,
+        cbrt.spName,
+        cbrt.number as numbers,
+        cbrt.consultName,
+        cbrt.consultMobile,
+        cbrt.accessTime,
+        cbrt.accessDuration,
+        cbrt.accessDate,
+        cbrt.accessClient,
+        cbrt.region,
+        cbrt.label,
+        cbrt.headUserId,
+        cbrt.productArchiveId,
+        cbrt.relevanceShop,
+        cbrt.addTime
+        FROM cm_behavior_record_today cbrt
+        left join user u on u.userId = cbrt.userId
         <where>
         <where>
+            <if test="clubId != null">
+                AND cbrt.clubId = #{clubId}
+            </if>
             <if test="ip != null and ip != ''">
             <if test="ip != null and ip != ''">
-                AND IP = #{ip}
+                AND cbrt.IP = #{ip}
             </if>
             </if>
             <if test="corporateName != null and corporateName != ''">
             <if test="corporateName != null and corporateName != ''">
-                AND (corporateName like concat('%',#{corporateName},'%') or contacts like concat('%',#{corporateName},'%'))
+                AND (cbrt.corporateName like concat('%',#{corporateName},'%') OR cbrt.consultName LIKE concat('%',#{corporateName},'%') or cbrt.contacts like concat('%',#{corporateName},'%'))
             </if>
             </if>
             <if test="companyType != null and companyType != ''">
             <if test="companyType != null and companyType != ''">
-                AND companyType = #{companyType}
+                AND cbrt.companyType = #{companyType}
             </if>
             </if>
             <if test="accessClient != null and accessClient != ''">
             <if test="accessClient != null and accessClient != ''">
-                AND accessClient =#{accessClient}
+                AND cbrt.accessClient =#{accessClient}
             </if>
             </if>
             <if test="contacts != null and contacts != ''">
             <if test="contacts != null and contacts != ''">
-                AND (corporateName like concat('%',#{contacts},'%') or contacts like concat('%',#{contacts},'%'))
+                AND (cbrt.corporateName like concat('%',#{contacts},'%') or cbrt.contacts like concat('%',#{contacts},'%'))
             </if>
             </if>
             <if test="phoneNumber != null and phoneNumber != ''">
             <if test="phoneNumber != null and phoneNumber != ''">
-                AND phoneNumber = #{phoneNumber}
+                AND cbrt.phoneNumber = #{phoneNumber}
             </if>
             </if>
             <if test="spName != null and spName != ''">
             <if test="spName != null and spName != ''">
-                AND spName = #{spName}
+                AND cbrt.spName = #{spName}
             </if>
             </if>
             <if test="headUserId != null and headUserId != ''">
             <if test="headUserId != null and headUserId != ''">
-                AND headUserId = #{headUserId}
+                AND cbrt.headUserId = #{headUserId}
             </if>
             </if>
             <if test="productArchiveId != null and productArchiveId != ''">
             <if test="productArchiveId != null and productArchiveId != ''">
-                AND productArchiveId = #{productArchiveId}
+                AND cbrt.productArchiveId = #{productArchiveId}
             </if>
             </if>
             <if test="relevanceShop != null and relevanceShop != ''">
             <if test="relevanceShop != null and relevanceShop != ''">
-                AND relevanceShop like concat('%',#{relevanceShop},'%')
+                AND cbrt.relevanceShop like concat('%',#{relevanceShop},'%')
             </if>
             </if>
             <if test="labels != null and labels.size > 0">
             <if test="labels != null and labels.size > 0">
                 AND
                 AND
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
-                    label like concat('%',#{label},'%')
+                    cbrt.label like concat('%',#{label},'%')
                 </foreach>
                 </foreach>
             </if>
             </if>
             <if test="pageLabels != null and pageLabels != ''">
             <if test="pageLabels != null and pageLabels != ''">
-                AND pageLabels like concat('%', #{pageLabels}, '%')
+                AND cbrt.pageLabels like concat('%', #{pageLabels}, '%')
             </if>
             </if>
             <if test="pageTypes != null and pageTypes != ''">
             <if test="pageTypes != null and pageTypes != ''">
-                AND pageTypes like concat('%', #{pageTypes}, '%')
+                AND cbrt.pageTypes like concat('%', #{pageTypes}, '%')
             </if>
             </if>
             <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
-                AND accessDate between #{startTime} and #{endTime}
+                AND cbrt.accessDate between #{startTime} and #{endTime}
+            </if>
+            <if test="registerStartTime != null and registerStartTime != ''">
+                AND u.registerTime <![CDATA[ >= ]]> #{registerStartTime}
+            </if>
+            <if test="registerEndTime != null and registerEndTime != ''">
+                AND u.registerTime <![CDATA[ <= ]]> #{registerEndTime}
             </if>
             </if>
         </where>
         </where>
-        ORDER BY accessTime DESC
+        ORDER BY cbrt.accessTime DESC
     </select>
     </select>
     <select id="selRegion" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
     <select id="selRegion" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         SELECT * FROM cm_behavior_record_ref where accessTime like concat('%',#{accessDate},'%')
         SELECT * FROM cm_behavior_record_ref where accessTime like concat('%',#{accessDate},'%')
@@ -228,7 +248,7 @@
         </where>
         </where>
         ORDER BY accessTime DESC
         ORDER BY accessTime DESC
     </select>
     </select>
-    <select id="searchList" resultType="com.caimei365.manager.entity.caimei.RetuenEntity">
+    <select id="searchList" resultType="com.caimei365.manager.entity.caimei.ReturnEntity">
         SELECT cusf.id , cusf.keyword AS VALUE
         SELECT cusf.id , cusf.keyword AS VALUE
         FROM cm_user_search_frequency cusf
         FROM cm_user_search_frequency cusf
          LEFT JOIN cm_shop_label csl ON csl.keywordId = cusf.id
          LEFT JOIN cm_shop_label csl ON csl.keywordId = cusf.id

+ 10 - 8
src/main/resources/mapper/KeyWordDao.xml

@@ -53,29 +53,31 @@
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
         SELECT cusf.id AS id, cusf.frequency, cusf.keyword as keyword, cusf.addTime, cusf.linkageStatus,
         SELECT cusf.id AS id, cusf.frequency, cusf.keyword as keyword, cusf.addTime, cusf.linkageStatus,
         cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch,
         cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch,
-        cusf.dynamicStatus, s.linkMan as name
-        ,IFNULL((select sum(c.pv) from cm_praise_statistics c where  c.delFlag = 0 and c.type = 6 and cusf.id = c.authorId  <if test="beginTime != null and beginTime !=''">AND c.createTime >= #{beginTime} </if><if test="endTime != null and endTime !=''">AND c.createTime <![CDATA[ <= ]]> #{endTime} </if>), 0) as pv
+        cusf.dynamicStatus, s.linkMan as name,
+        IFNULL(SUM(c.pv), 0) as pv
         FROM cm_user_search_frequency cusf
         FROM cm_user_search_frequency cusf
         left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
         left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
+        LEFT JOIN cm_praise_statistics c ON cusf.id = c.authorId
         WHERE cusf.delStatus = 1
         WHERE cusf.delStatus = 1
+        <if test="beginTime != null and beginTime !=''">
+          AND c.createTime >= #{beginTime}
+        </if>
+        <if test="endTime != null and endTime !=''">
+          AND c.createTime <![CDATA[ <= ]]> #{endTime}
+        </if>
 <!--        <if test="beginTime !=null and beginTime !=''">-->
 <!--        <if test="beginTime !=null and beginTime !=''">-->
 <!--            AND (cusf.searchTime BETWEEN #{beginTime} AND #{endTime} or cusf.searchTime IS NULL)-->
 <!--            AND (cusf.searchTime BETWEEN #{beginTime} AND #{endTime} or cusf.searchTime IS NULL)-->
 <!--        </if>-->
 <!--        </if>-->
         <if test="keyword !=null and keyword !=''">
         <if test="keyword !=null and keyword !=''">
             AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
             AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
         </if>
         </if>
-        <if test="labelStatus == 1">
-            AND cusf.dynamicStatus = 0
-        </if>
-        <if test="labelStatus == null">
-            AND (cusf.dynamicStatus not in (0, 1) or (cusf.dynamicStatus IS NULL))
-        </if>
         <if test="labelStatus !=null">
         <if test="labelStatus !=null">
             AND cusf.trueStatus = #{labelStatus}
             AND cusf.trueStatus = #{labelStatus}
         </if>
         </if>
         <if test="fromSearch != null">
         <if test="fromSearch != null">
             AND cusf.fromSearch = #{fromSearch}
             AND cusf.fromSearch = #{fromSearch}
         </if>
         </if>
+        GROUP BY cusf.id
         ORDER BY cusf.frequency DESC, cusf.searchTime DESC
         ORDER BY cusf.frequency DESC, cusf.searchTime DESC
     </select>
     </select>
 
 

+ 2 - 4
src/main/resources/mapper/svip/CmSvipHistoryDao.xml

@@ -354,12 +354,10 @@
     </select>
     </select>
     <select id="newCmShopGet" resultType="com.caimei365.manager.entity.caimei.svip.NewCmShop">
     <select id="newCmShopGet" resultType="com.caimei365.manager.entity.caimei.svip.NewCmShop">
         SELECT
         SELECT
-        <include refid="newCmShopColumns"/>,
-        copi.validFlag AS "validFlag",
+        <include refid="newCmShopColumns"/>
         FROM shop a
         FROM shop a
         <include refid="newCmShopJoins"/>
         <include refid="newCmShopJoins"/>
-        LEFT JOIN cm_organize_product_info copi ON copi.productId = p.productId
-        WHERE a.shopID = #{id} and copi.organizeId = 0
+        WHERE a.shopID = #{id}
     </select>
     </select>
     <select id="findRedemptionCodeNum" resultType="java.lang.Integer">
     <select id="findRedemptionCodeNum" resultType="java.lang.Integer">
         SELECT COUNT(id) FROM cm_coupon_redemption_code WHERE couponId = #{couponId}
         SELECT COUNT(id) FROM cm_coupon_redemption_code WHERE couponId = #{couponId}

+ 6 - 0
src/main/resources/mapper/user/CmClubRemarksDao.xml

@@ -91,6 +91,9 @@
         LEFT JOIN shop sh ON sh.shopID = p.shopID
         LEFT JOIN shop sh ON sh.shopID = p.shopID
         <where>
         <where>
             s.validFlag = 1 and s.serviceProviderID not in (1371, 1342)
             s.validFlag = 1 and s.serviceProviderID not in (1371, 1342)
+            <if test="clubId != null">
+                AND ccr.clubId = #{clubId}
+            </if>
             <if test="remarks != null and remarks !=''">
             <if test="remarks != null and remarks !=''">
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
             </if>
             </if>
@@ -152,6 +155,9 @@
         LEFT JOIN product p ON p.productID = ccr.productID
         LEFT JOIN product p ON p.productID = ccr.productID
         LEFT JOIN shop sh ON sh.shopID = p.shopID
         LEFT JOIN shop sh ON sh.shopID = p.shopID
         <where>
         <where>
+            <if test="clubId != null">
+                AND ccr.clubId = #{clubId}
+            </if>
             <if test="remarks != null and remarks !=''">
             <if test="remarks != null and remarks !=''">
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
             </if>
             </if>

+ 385 - 0
src/main/resources/mapper/user/CmMarketShopDao.xml

@@ -0,0 +1,385 @@
+<?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.user.CmMarketShopDao">
+
+    <update id="updateShopLogo">
+        update cm_shop_product
+        set logo = #{logo}
+        where id = #{id}
+    </update>
+
+    <select id="getMarketReport" resultType="com.caimei365.manager.entity.caimei.shopImport.CmMarketReport">
+        select
+        cmr.id,
+        cmr.marketId,
+        cmr.reportDate,
+        cmr.reportTime,
+        cmr.fileName,
+        cmr.reportName,
+        css.shopId,
+        cmr.visible,
+        cmr.addTime,
+        cmr.delFlag
+        FROM cm_market_report cmr
+            left join cm_shop_product csp on csp.id = cmr.marketId
+        LEFT JOIN cm_shop_statistics css ON css.id = csp.statisticsId
+        <where>
+            cmr.marketId = #{marketId} AND cmr.delFlag = 0
+            <if test="reportName != null and reportName != ''">
+                AND cmr.reportName LIKE concat('%', #{reportName}, '%')
+            </if>
+        </where>
+        order by cmr.addTime desc
+    </select>
+
+    <select id="getMarketReportById" resultType="com.caimei365.manager.entity.caimei.shopImport.CmMarketReport">
+        SELECT id,
+               marketId,
+               reportDate,
+               reportTime,
+               reportName,
+               fileName,
+               visible,
+               addTime,
+               delFlag
+        FROM cm_market_report
+        where id = #{id}
+          AND delFlag = 0
+    </select>
+
+    <update id="updateMarketReportVisible">
+        update cm_market_report
+        set visible = 1,
+            reportTime = now()
+        where id = #{id}
+    </update>
+
+    <update id="updateMarketReport">
+        update cm_market_report
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
+    <insert id="insertMarketReport" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
+        insert into cm_market_report (marketId, reportDate, reportTime, reportName, fileName, visible, addTime, delFlag)
+        values (#{marketId}, #{reportDate}, #{reportTime}, #{reportName}, #{fileName}, 2, now(), 0)
+    </insert>
+
+    <insert id="insertMarketStage">
+        insert into cm_market_stage (marketReportId, stage, theme, addTime, delFlag)
+        values (#{marketReportId}, #{stage}, #{theme}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketFunnelModel">
+        insert into cm_market_funnelModel (marketReportId, impressions, hits, visits, consultation, report, addTime,
+                                           delFlag)
+        values (#{marketReportId}, #{impressions}, #{hits}, #{visits}, #{consultation}, #{report}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketArticleReadVolume">
+        insert into cm_market_articleReadVolume (marketReportId, firstTime, title, link, titleReferred, type, keyword, channel,
+                                                 touchNumber, wechatNumber, addTime, delFlag)
+        values (#{marketReportId}, #{firstTime}, #{title}, #{link}, #{titleReferred}, #{type}, #{keyword}, #{channel}, #{touchNumber},
+                #{wechatNumber}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketImpressions">
+        insert into cm_market_impressions (marketReportId, generalNumber, microBlog, redBookNumber, otherNumber,
+                                           addTime, delFlag)
+        values (#{marketReportId}, #{generalNumber}, #{microBlog}, #{redBookNumber}, #{otherNumber}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketReadVolume">
+        insert into cm_market_readVolume (marketReportId, generalNumber, microBlog, redBookNumber, otherNumber, addTime,
+                                          delFlag)
+        values (#{marketReportId}, #{generalNumber}, #{microBlog}, #{redBookNumber}, #{otherNumber}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketSummary">
+        insert into cm_market_summary (marketReportId, keyword, seoRanking, searchVolume, addTime, delFlag)
+        values (#{marketReportId}, #{keyword}, #{seoRanking}, #{searchVolume}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketVisits">
+        insert into cm_market_visits (marketReportId, clubNumber, touristNumber, addTime, delFlag)
+        values (#{marketReportId}, #{clubNumber}, #{touristNumber}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketProportion">
+        insert into cm_market_proportion (marketReportId, search, general, microBlog, directAccess, addTime, delFlag)
+        values (#{marketReportId}, #{search}, #{general}, #{microBlog}, #{directAccess}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketPageDuration">
+        insert into cm_market_pageDuration (marketReportId, pageLabel, accessDuration, addTime, delFlag)
+        values (#{marketReportId}, #{pageLabel}, #{accessDuration}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketAdvertHits">
+        insert into cm_market_advertHits (marketReportId, position, home, infoCenter, hits, addTime, delFlag)
+        values (#{marketReportId}, #{position}, #{home}, #{infoCenter}, #{hits}, now(), 0)
+    </insert>
+
+    <insert id="insertMarketRemark">
+        insert into cm_market_remark (marketReportId, remarkNumber, addTime, delFlag)
+        values (#{marketReportId}, #{remarkNumber}, now(), 0)
+    </insert>
+
+    <insert id="updateMarketStage">
+        update cm_market_stage
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketFunnelModel">
+        update cm_market_funnelModel
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketArticleReadVolume">
+        update cm_market_articleReadVolume
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketImpressions">
+        update cm_market_impressions
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketReadVolume">
+        update cm_market_readVolume
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketSummary">
+        update cm_market_summary
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketVisits">
+        update cm_market_visits
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketProportion">
+        update cm_market_proportion
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketPageDuration">
+        update cm_market_pageDuration
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketAdvertHits">
+        update cm_market_advertHits
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <insert id="updateMarketRemark">
+        update cm_market_remark
+        set delFlag = 1
+        where marketReportId = #{marketReportId}
+    </insert>
+
+    <select id="getShopInfoById" resultType="com.caimei365.manager.entity.caimei.shopImport.CmMarketShop">
+        SELECT cmr.reportDate,
+               cmr.addTime,
+               s.shopId,
+               s.name,
+               s.linkMan,
+               s.contractMobile,
+               css.logo
+        FROM cm_market_report cmr
+                 LEFT JOIN cm_shop_statistics css ON css.id = cmr.marketId
+                 LEFT JOIN shop s ON s.shopId = css.shopId
+        WHERE cmr.delFlag = 0
+          and cmr.id = #{id}
+        limit 1
+    </select>
+
+    <select id="getMarketStage" resultType="com.caimei365.manager.entity.caimei.shopImport.Stage">
+        SELECT id,
+               stage,
+               theme,
+               addTime
+        FROM cm_market_stage
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketFunnelModel" resultType="com.caimei365.manager.entity.caimei.shopImport.FunnelModel">
+        SELECT id,
+               impressions,
+               hits,
+               visits,
+               consultation,
+               report
+        FROM cm_market_funnelModel
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketArticleReadVolume"
+            resultType="com.caimei365.manager.entity.caimei.shopImport.ArticleReadVolume">
+        SELECT id,
+               title,
+               link,
+               titleReferred,
+               type,
+               keyword,
+               channel,
+               touchNumber,
+               wechatNumber
+        FROM cm_market_articleReadVolume
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketImpressions" resultType="com.caimei365.manager.entity.caimei.shopImport.Impressions">
+        SELECT id,
+               generalNumber,
+               microBlog,
+               redBookNumber,
+               otherNumber
+        FROM cm_market_impressions
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketReadVolume" resultType="com.caimei365.manager.entity.caimei.shopImport.ReadVolume">
+        SELECT id,
+               generalNumber,
+               microBlog,
+               redBookNumber,
+               otherNumber
+        FROM cm_market_readVolume
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketSummary" resultType="com.caimei365.manager.entity.caimei.shopImport.Summary">
+        SELECT id,
+               keyword,
+               seoRanking,
+               searchVolume
+        FROM cm_market_summary
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketVisits" resultType="com.caimei365.manager.entity.caimei.shopImport.Visits">
+        SELECT id,
+               clubNumber,
+               touristNumber
+        FROM cm_market_visits
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketProportion" resultType="com.caimei365.manager.entity.caimei.shopImport.Proportion">
+        SELECT id,
+               search,
+               general,
+               microBlog,
+               directAccess
+        FROM cm_market_proportion
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketPageDuration" resultType="com.caimei365.manager.entity.caimei.shopImport.PageDuration">
+        SELECT id,
+               pageLabel,
+               accessDuration
+        FROM cm_market_pageDuration
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketAdvertHits" resultType="com.caimei365.manager.entity.caimei.shopImport.AdvertHits">
+        SELECT id,
+               POSITION,
+               home,
+               infoCenter,
+               hits
+        FROM cm_market_advertHits
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getMarketRemark" resultType="com.caimei365.manager.entity.caimei.shopImport.Remark">
+        SELECT id,
+               remarkNumber,
+               addTime
+        FROM cm_market_remark
+        WHERE marketReportId = #{marketReportId}
+    </select>
+
+    <select id="getShopKeyword" resultType="java.lang.String">
+        SELECT cusf.keyword
+        FROM cm_user_search_frequency cusf
+                 LEFT JOIN cm_shop_label csl ON csl.keywordId = cusf.id
+                 LEFT JOIN cm_shop_relevance csr ON csr.id = csl.relevanceId
+        where csr.shopId = #{shopId}
+    </select>
+
+    <select id="getRegion" resultType="java.lang.String">
+        SELECT region FROM cm_behavior_record_index
+        where accessDate = #{accessDate}
+        AND (
+        <foreach collection="labels" item="label" open="(" separator="or" close=")">
+            label LIKE concat('%', #{label}, '%')
+        </foreach>
+        )
+    </select>
+
+    <!--用户身份-->
+    <select id="getUserIdentity" resultType="com.caimei365.manager.entity.caimei.ReturnEntity">
+        SELECT
+            (CASE c.linkManIdentity
+                WHEN 1 THEN '老板'
+                WHEN 2 THEN '采购'
+                WHEN 3 THEN '运营'
+                WHEN 4 THEN '其他'
+            END) AS name,
+            COUNT(c.userId) as value
+        FROM cm_behavior_record_index cbri
+        LEFT JOIN club c ON c.userId = cbri.userId
+        LEFT JOIN USER u ON u.userId = cbri.userId
+        WHERE cbri.accessDate = #{accessDate}
+            AND cbri.userId != 0
+            AND u.userIdentity = 2
+            AND (
+                <foreach collection="labels" item="label" open="(" separator="or" close=")">
+                    cbri.label LIKE concat('%', #{label}, '%')
+                </foreach>
+            )
+        GROUP BY c.linkManIdentity
+    </select>
+
+
+    <!--机构类型-->
+    <select id="getClubType" resultType="com.caimei365.manager.entity.caimei.ReturnEntity">
+        SELECT
+            (CASE c.firstClubType
+                WHEN 1 THEN '医美'
+                WHEN 2 THEN '生美'
+                WHEN 3 THEN '项目公司'
+                WHEN 4 THEN '个人'
+                WHEN 5 THEN '其他'
+            END) AS name,
+            COUNT(c.userId) as value
+        FROM cm_behavior_record_index cbri
+        LEFT JOIN club c ON c.userId = cbri.userId
+        LEFT JOIN USER u ON u.userId = cbri.userId
+        WHERE cbri.accessDate = #{accessDate}
+            AND cbri.userId != 0
+            AND u.userIdentity = 2
+            AND (
+                <foreach collection="labels" item="label" open="(" separator="or" close=")">
+                    cbri.label LIKE concat('%', #{label}, '%')
+                </foreach>
+            )
+        GROUP BY c.firstClubType
+    </select>
+</mapper>

+ 122 - 13
src/main/resources/mapper/user/CustomerServiceDao.xml

@@ -6,11 +6,13 @@
         SELECT
         SELECT
             DISTINCT css.id as id,
             DISTINCT css.id as id,
                      css.shopID AS shopId,
                      css.shopID AS shopId,
+                     css.logo,
                      s.name as shopName,
                      s.name as shopName,
                      s.linkMan,
                      s.linkMan,
                      s.contractMobile AS mobile,
                      s.contractMobile AS mobile,
                      s.status AS shopStatus,
                      s.status AS shopStatus,
                      css.status,
                      css.status,
+                    (SELECT ADDTIME FROM cm_market_report WHERE marketId = css.id AND delFlag = 0 AND visible = 1 ORDER BY ADDTIME DESC LIMIT 1) AS recentlyTime,
                      css.addTime
                      css.addTime
         FROM cm_shop_statistics css
         FROM cm_shop_statistics css
                  LEFT JOIN shop s ON css.shopId = s.shopId
                  LEFT JOIN shop s ON css.shopId = s.shopId
@@ -52,10 +54,89 @@
         set status = #{status}
         set status = #{status}
         where id = #{id}
         where id = #{id}
     </update>
     </update>
+
+    <select id="getShopProduct" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopProduct">
+        SELECT
+            csp.id,
+            csp.statisticsId,
+            csp.productId,
+            csp.status,
+            csp.logo,
+            csp.addTime,
+            csp.delFlag,
+            css.shopId,
+            p.name AS productName,
+            p.mainImage AS productImage,
+            (SELECT ADDTIME FROM cm_market_report WHERE marketId = csp.id AND delFlag = 0 AND visible = 1 ORDER BY ADDTIME DESC LIMIT 1) AS recentlyTime
+        FROM cm_shop_product csp
+                 LEFT JOIN cm_shop_statistics css ON css.id = csp.statisticsId
+                 LEFT JOIN product p ON csp.productId = p.productId
+        <where>
+            csp.statisticsId = #{id} and csp.delFlag = 0
+            <if test="productId != null">
+                and csp.productId = #{productId}
+            </if>
+            <if test="productName != null and productName != ''">
+                and p.name like concat('%', #{productName},'%')
+            </if>
+            <if test="status != null">
+                and csp.status = #{status}
+            </if>
+        </where>
+        order by csp.addTime desc
+    </select>
+
+    <select id="getProductList" resultType="com.caimei365.manager.entity.caimei.product.Product">
+        SELECT
+            p.productId,
+            p.name as productName,
+            p.mainImage,
+            s.shopId,
+            s.name AS shopName
+        FROM product p
+                 LEFT JOIN cm_organize_product_info copi ON copi.productId = p.productId
+                 LEFT JOIN shop s ON s.shopId = p.shopId
+        <where>
+            copi.organizeId = 0 AND copi.validFlag = 2
+            and p.shopId = #{shopId}
+            <if test="productId != null">
+                and p.productId = #{productId}
+            </if>
+            <if test="productName != null and productName != ''">
+                and p.name like concat('%', #{productName},'%')
+            </if>
+        </where>
+    </select>
+
+    <select id="getProductIds" resultType="java.lang.Integer">
+        select
+            csp.productId
+        from cm_shop_product csp
+        left join cm_shop_statistics css on css.id = csp.statisticsId
+        where css.shopId = #{shopId} and csp.delFlag = 0
+    </select>
+
+    <insert id="insertShopProduct">
+        insert into cm_shop_product (statisticsId, productId, status, addTime, delFlag)
+        values (#{statisticsId}, #{productId}, 1, now(), 0)
+    </insert>
+
+    <update id="updateProductStatus">
+        update cm_shop_product
+        set status = #{status}
+        where id = #{id}
+    </update>
+
+    <update id="updateShopProduct">
+        update cm_shop_product
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
     <select id="getCmInformationList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmRoosInformation">
     <select id="getCmInformationList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmRoosInformation">
         SELECT cri.id,
         SELECT cri.id,
                cri.IP,
                cri.IP,
-               cri.shopId,
+               cri.shopProductId,
                cri.followUpStatus,
                cri.followUpStatus,
                cri.consultName,
                cri.consultName,
                cri.consultMobile,
                cri.consultMobile,
@@ -65,7 +146,7 @@
                cri.createTime
                cri.createTime
         FROM cm_roos_information cri
         FROM cm_roos_information cri
         <where>
         <where>
-          shopId = #{shopId}
+            shopProductId = #{shopProductId}
           AND consultName IS NOT NULL
           AND consultName IS NOT NULL
           AND consultMobile IS NOT NULL
           AND consultMobile IS NOT NULL
             <if test="consultName != null and consultName != ''">
             <if test="consultName != null and consultName != ''">
@@ -128,7 +209,7 @@
         FROM cm_shop_info csi
         FROM cm_shop_info csi
         LEFT JOIN info i ON i.id = csi.infoId
         LEFT JOIN info i ON i.id = csi.infoId
         <where>
         <where>
-            csi.shopId = #{shopId} and csi.delFlag = 0 and i.delFlag = 0
+            csi.shopProductId = #{shopProductId} and csi.delFlag = 0 and i.delFlag = 0
             <if test="infoId != null">
             <if test="infoId != null">
                 and csi.infoId = #{infoId}
                 and csi.infoId = #{infoId}
             </if>
             </if>
@@ -159,8 +240,8 @@
     </select>
     </select>
 
 
     <insert id="insertShopInfo">
     <insert id="insertShopInfo">
-        insert into cm_shop_info (shopId, infoId, status, addTime, delFlag)
-        values (#{shopId}, #{infoId}, #{status}, now(), #{delFlag})
+        insert into cm_shop_info (shopProductId, infoId, status, addTime, delFlag)
+        values (#{shopProductId}, #{infoId}, #{status}, now(), #{delFlag})
     </insert>
     </insert>
 
 
     <update id="updateShopInfoStatus">
     <update id="updateShopInfoStatus">
@@ -178,7 +259,7 @@
     <select id="getShopKeyword" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopKeyword">
     <select id="getShopKeyword" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopKeyword">
         SELECT
         SELECT
             csk.id,
             csk.id,
-            csk.shopId,
+            csk.shopProductId,
             cusf.keyword,
             cusf.keyword,
             cusf.frequency as number,
             cusf.frequency as number,
             cusf.searchTime,
             cusf.searchTime,
@@ -187,7 +268,7 @@
         FROM cm_shop_keyword csk
         FROM cm_shop_keyword csk
                  LEFT JOIN cm_user_search_frequency cusf ON cusf.id = csk.searchId
                  LEFT JOIN cm_user_search_frequency cusf ON cusf.id = csk.searchId
         <where>
         <where>
-            csk.shopId = #{shopId}
+            csk.shopProductId = #{shopProductId}
             and csk.delFlag = 0 and cusf.delStatus = 1
             and csk.delFlag = 0 and cusf.delStatus = 1
             <if test="keyword != null and keyword != ''">
             <if test="keyword != null and keyword != ''">
                 and cusf.keyword like concat('%',#{keyword},'%')
                 and cusf.keyword like concat('%',#{keyword},'%')
@@ -213,8 +294,8 @@
     </select>
     </select>
 
 
     <insert id="insertShopKeyword">
     <insert id="insertShopKeyword">
-        insert into cm_shop_keyword (shopId, searchId, status, addTime, delFlag)
-        values (#{shopId}, #{searchId}, #{status}, now(), #{delFlag})
+        insert into cm_shop_keyword (shopProductId, searchId, status, addTime, delFlag)
+        values (#{shopProductId}, #{searchId}, #{status}, now(), #{delFlag})
     </insert>
     </insert>
 
 
     <update id="updateShopKeywordStatus">
     <update id="updateShopKeywordStatus">
@@ -232,18 +313,18 @@
     <select id="getShopPopUp" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopPopUp">
     <select id="getShopPopUp" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopPopUp">
         select
         select
         id,
         id,
-        shopId,
+        shopProductId,
         image,
         image,
         guidingOne,
         guidingOne,
         guidingTwo,
         guidingTwo,
         addTime
         addTime
         from cm_shop_popUp
         from cm_shop_popUp
-        where shopId = #{shopId}
+        where shopProductId = #{shopProductId}
     </select>
     </select>
 
 
     <insert id="insertShopPopUp">
     <insert id="insertShopPopUp">
-        insert into cm_shop_popUp(shopId, image, guidingOne, guidingTwo, addTime)
-        values (#{shopId}, #{image}, #{guidingOne}, #{guidingTwo}, now())
+        insert into cm_shop_popUp(shopProductId, image, guidingOne, guidingTwo, addTime)
+        values (#{shopProductId}, #{image}, #{guidingOne}, #{guidingTwo}, now())
     </insert>
     </insert>
 
 
     <update id="updateShopPopUp">
     <update id="updateShopPopUp">
@@ -320,6 +401,14 @@
         where id = #{id}
         where id = #{id}
     </update>
     </update>
 
 
+    <select id="getShopProductList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopProduct">
+        select csp.productId, p.name as productName
+        from cm_shop_statistics css
+        left join cm_shop_product csp on csp.statisticsId = css.id
+        left join product p on p.productId = csp.productId
+        where css.shopId = #{shopId} and csp.delFlag = 0
+    </select>
+
     <select id="getPageShop" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShop">
     <select id="getPageShop" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShop">
         SELECT
         SELECT
             cps.id,
             cps.id,
@@ -371,15 +460,25 @@
             i.title,
             i.title,
             i.onlineStatus,
             i.onlineStatus,
             cpsi.link,
             cpsi.link,
+            p.productId,
+            p.name as productName,
+            p.mainImage,
             IFNULL(SUM(cpsi.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsi.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsi.accessDuration), 0) AS accessDuration,
             IFNULL(SUM(cpsi.accessDuration), 0) AS accessDuration,
             IFNULL((IFNULL(SUM(cpsi.accessDuration), 0) / IFNULL(SUM(cpsi.accessNumber), 0)), 0) AS averageDuration
             IFNULL((IFNULL(SUM(cpsi.accessDuration), 0) / IFNULL(SUM(cpsi.accessNumber), 0)), 0) AS averageDuration
         FROM cm_page_shop_info cpsi
         FROM cm_page_shop_info cpsi
         LEFT JOIN info i ON i.id = cpsi.infoId
         LEFT JOIN info i ON i.id = cpsi.infoId
+        LEFT JOIN cm_shop_info csi ON csi.infoId = cpsi.infoId
+        LEFT JOIN cm_shop_product csp ON csp.id = csi.shopProductId
+        LEFT JOIN cm_shop_statistics css ON css.id = csp.statisticsId
+        left join product p on p.productId = csp.productId
         WHERE cpsi.shopId = #{shopId}
         WHERE cpsi.shopId = #{shopId}
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             and cpsi.accessDate BETWEEN #{startTime} and #{endTime}
             and cpsi.accessDate BETWEEN #{startTime} and #{endTime}
         </if>
         </if>
+        <if test="productId != null">
+            and csp.productId = #{productId}
+        </if>
         group by cpsi.infoId
         group by cpsi.infoId
     </select>
     </select>
 
 
@@ -389,15 +488,25 @@
             cpsk.shopId,
             cpsk.shopId,
             cusf.keyword,
             cusf.keyword,
             cpsk.link,
             cpsk.link,
+            p.productId,
+            p.name as productName,
+            p.mainImage,
             IFNULL(SUM(cpsk.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsk.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsk.accessDuration), 0) AS accessDuration,
             IFNULL(SUM(cpsk.accessDuration), 0) AS accessDuration,
             IFNULL((IFNULL(SUM(cpsk.accessDuration), 0) / IFNULL(SUM(cpsk.accessNumber), 0)), 0) AS averageDuration
             IFNULL((IFNULL(SUM(cpsk.accessDuration), 0) / IFNULL(SUM(cpsk.accessNumber), 0)), 0) AS averageDuration
         FROM cm_page_shop_keyword cpsk
         FROM cm_page_shop_keyword cpsk
         LEFT JOIN cm_user_search_frequency cusf ON cusf.id = cpsk.searchId
         LEFT JOIN cm_user_search_frequency cusf ON cusf.id = cpsk.searchId
+        LEFT JOIN cm_shop_keyword csk ON csk.searchId = cpsk.searchId
+        LEFT JOIN cm_shop_product csp ON csp.id = csk.shopProductId
+        LEFT JOIN cm_shop_statistics css ON css.id = csp.statisticsId
+        left join product p on p.productId = csp.productId
         WHERE cpsk.shopId = #{shopId}
         WHERE cpsk.shopId = #{shopId}
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             and cpsk.accessDate BETWEEN #{startTime} and #{endTime}
             and cpsk.accessDate BETWEEN #{startTime} and #{endTime}
         </if>
         </if>
+        <if test="productId != null">
+            and csp.productId = #{productId}
+        </if>
         group by cpsk.searchId
         group by cpsk.searchId
     </select>
     </select>
 
 

+ 182 - 1
src/test/java/com/caimei365/manager/ManagerApplicationTests.java

@@ -1,13 +1,194 @@
+/*
 package com.caimei365.manager;
 package com.caimei365.manager;
 
 
+import cn.hutool.core.util.ZipUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.caimei365.manager.dao.user.CmMarketShopDao;
+import com.caimei365.manager.entity.caimei.shopImport.*;
+import com.caimei365.manager.service.caimei.listener.*;
+import com.caimei365.manager.utils.formDataUtils;
+import org.apache.commons.fileupload.disk.DiskFileItem;
+import org.apache.commons.io.IOUtils;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import javax.annotation.Resource;
+import java.io.*;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 
 @SpringBootTest
 @SpringBootTest
 class ManagerApplicationTests {
 class ManagerApplicationTests {
 
 
+    @Resource private formDataUtils formDataUtils;
+    @Resource private CmMarketShopDao marketShopDao;
+
     @Test
     @Test
-    void contextLoads() {
+    void contextLoads() throws Exception{
+        String filePath = "E:\\Users\\Desktop\\采美\\报表文件上传模板.zip";
+
+        String inputPath = "E:\\Users\\Desktop\\dest\\test.zip";
+        String outPath = "E:\\Users\\Desktop\\extract";
+
+        File inputFile = new File(inputPath);
+        if (!inputFile.exists() && !inputFile.isDirectory()) {
+            inputFile.mkdirs();
+        }
+        File outFile = new File(outPath);
+        if (!inputFile.exists() && !outFile.isDirectory()) {
+            outFile.mkdirs();
+        }
+        File zipFile = new File(filePath);
+        MultipartFile multipartFile = fileToMultipartFileConverter(zipFile);
+        try {
+            multipartFile.transferTo(inputFile);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        ZipUtil.unzip(inputFile, outFile);
+        System.out.println("inputFile======"+inputFile.getPath());
+
+    }
+
+    @Test
+    void test() throws IOException {
+        String fileDirectory = "E:\\Users\\Desktop\\采美\\报表文件上传模板";
+        // SEO 图片集合
+        List<String> seoImagePathList = new ArrayList<>();
+        // 广告图点击量 图片集合
+        List<String> advertImageHomeList = new ArrayList<>();
+        List<String> advertImageInfoList = new ArrayList<>();
+        File file = new File(fileDirectory);
+        if (file.exists() && file.isDirectory()) {
+            for (File fileSpecific: file.listFiles()) {
+                if (fileSpecific.getName().equals("SEO汇总图片") && fileSpecific.exists() && fileSpecific.isDirectory()) {
+                    for (File fileSpecificContain : fileSpecific.listFiles()) {
+                        if (fileSpecificContain.getName().contains("SEO汇总图")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片顺序需与 SEO 列表顺序一致
+                            MultipartFile filex = fileToMultipartFileConverter(fileSpecificContain);
+                            String seoImagePath = formDataUtils.saveShopFile(filex);
+                            seoImagePathList.add(seoImagePath);
+                        }
+                    }
+                }
+                if (fileSpecific.getName().equals("广告图片") && fileSpecific.exists() && fileSpecific.isDirectory()) {
+                    for (File fileSpecificContain : fileSpecific.listFiles()) {
+                        if (fileSpecificContain.getName().contains("首页")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片顺序需与 广告图点击量 列表顺序一致
+                            MultipartFile filex = fileToMultipartFileConverter(fileSpecificContain);
+                            String advertImagePath = formDataUtils.saveShopFile(filex);
+                            advertImageHomeList.add(advertImagePath);
+                        }
+                        if (fileSpecificContain.getName().contains("信息中心")) {
+                            // 上传图到服务器并获取图链接,存入数据库,图片顺序需与 广告图点击量 列表顺序一致
+                            MultipartFile filex = fileToMultipartFileConverter(fileSpecificContain);
+                            String advertImagePath = formDataUtils.saveShopFile(filex);
+                            advertImageInfoList.add(advertImagePath);
+                        }
+                    }
+                }
+                if (fileSpecific.getName().endsWith(".xlsx")) {
+                    updateFile(fileSpecific, seoImagePathList, advertImageHomeList, advertImageInfoList);
+                }
+            }
+        }
+        System.out.println("seoImagePathList====="+seoImagePathList);
+        System.out.println("advertImageHomeList====="+advertImageHomeList);
+        System.out.println("advertImageInfoList====="+advertImageInfoList);
+    }
+
+
+    void updateFile(File file, List<String> seoImagePathList, List<String> advertImageHomeList, List<String> advertImageInfoList) throws IOException {
+        String excelType = "XLSX";
+        if (file.getName().endsWith(".xls")) {
+            excelType = "XLS";
+        }
+        Integer marketReportId = 1;
+        MultipartFile multipartFile = fileToMultipartFileConverter(file);
+        InputStream inputStream = new BufferedInputStream(multipartFile.getInputStream());
+        InputStream is = inputStream;
+        EasyExcel.read(is, Stage.class, new StageListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("阶段描述").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, FunnelModel.class, new FunnelModelListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("漏斗模型数据").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, ArticleReadVolume.class, new ArticleReadVolumeListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("推文阅读量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Impressions.class, new ImpressionsListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("展现量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, ReadVolume.class, new ReadVolumeListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("点击量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Summary.class, new SummaryListener(marketReportId, marketShopDao, seoImagePathList)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("SEO汇总").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Visits.class, new VisitsLisener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("访问量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Proportion.class, new ProportionListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("访客来源分布").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, PageDuration.class, new PageDurationListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("页面平均时长").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, AdvertHits.class, new AdvertHitsListener(marketReportId, marketShopDao, advertImageHomeList, advertImageInfoList)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("广告图点击量").doRead();
+        is = new BufferedInputStream(multipartFile.getInputStream());
+        EasyExcel.read(is, Remark.class, new RemarkListener(marketReportId, marketShopDao)).excelType(ExcelTypeEnum.valueOf(excelType)).sheet("咨询数量").doRead();
+    }
+
+    MultipartFile fileToMultipartFileConverter(File file) throws IOException {
+        DiskFileItem diskFileItem = new DiskFileItem("File", "application/octet-stream", true, file.getName(), (int) file.length(), file.getParentFile());
+        try(InputStream is = new FileInputStream(file)) {
+            diskFileItem.getOutputStream().write(IOUtils.toByteArray(is));
+        }
+        return new CommonsMultipartFile(diskFileItem);
+    }
+
+    @Test
+    void testNumber() {
+        String zipFilePath = "E:\\Users\\Desktop\\dest\\test.zip";
+        String destDirectory = "E:\\Users\\Desktop\\extract";
+        try {
+            unzip(zipFilePath, destDirectory);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void unzip(String zipFilePath, String destDirectory) throws IOException {
+        File destDir = new File(destDirectory);
+        if (!destDir.exists()) {
+            destDir.mkdir();
+        }
+        ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
+        ZipEntry entry = zipIn.getNextEntry();
+        while (entry != null) {
+            String filePath = destDirectory + File.separator + entry.getName();
+            if (!entry.isDirectory()) {
+                extractFile(zipIn, filePath);
+            } else {
+                File dir = new File(filePath);
+                dir.mkdir();
+            }
+            zipIn.closeEntry();
+            entry = zipIn.getNextEntry();
+        }
+        zipIn.close();
+    }
+
+    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
+        File file = new File(filePath);
+        file.getParentFile().mkdirs();
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            byte[] bytes = new byte[4096];
+            int length;
+            while ((length = zipIn.read(bytes)) != -1) {
+                fos.write(bytes, 0, length);
+            }
+        }
     }
     }
 
 
 }
 }
+*/