浏览代码

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

# Conflicts:
#	src/main/resources/mapper/CmBehaciorRecordDao.xml
kaick 1 年之前
父节点
当前提交
6555fe95bd
共有 59 个文件被更改,包括 4279 次插入174 次删除
  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>
             <version>1.9.2</version>
         </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>
 
     <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.net.URLEncoder;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Description
@@ -96,9 +97,9 @@ public class CmBehaviorRecordApi {
      * @return 返回
      */
     @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);
     }
 

+ 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.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
@@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
+import java.util.List;
 
 /**
  * Description
@@ -87,6 +89,91 @@ public class CustomerApi {
         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
@@ -98,8 +185,8 @@ public class CustomerApi {
     public ResponseJson<PaginationVo<CmRoosInformation>> getCmInformationList(CmRoosInformation cmRoosInformation,
                                                                               @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                               @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);
     }
@@ -168,8 +255,8 @@ public class CustomerApi {
     public ResponseJson<PaginationVo<CmShopInfo>> getShopInfoList(CmShopInfo cmShopInfo,
                                                                   @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                   @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);
     }
@@ -191,19 +278,19 @@ public class CustomerApi {
 
     /**
      * 添加文章统计
-     * @param shopId
+     * @param shopProductId
      * @param infoIds
      * @return
      */
     @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) {
             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,
                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
                                                                      @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);
     }
@@ -269,19 +356,19 @@ public class CustomerApi {
 
     /**
      * 添加搜索词统计
-     * @param shopId
+     * @param shopProductId
      * @param keyWordIds
      * @return
      */
     @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) {
             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
      */
     @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")
     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()) {
             return ResponseJson.error(-1, "显示图不能为空", null);
@@ -437,6 +524,19 @@ public class CustomerApi {
         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
@@ -475,13 +575,13 @@ public class CustomerApi {
      * @return
      */
     @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 = "pageSize",defaultValue = "20") int pageSize) {
         if (null == shopId) {
             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
      */
     @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 = "pageSize",defaultValue = "20") int pageSize) {
         if (null == shopId) {
             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.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.Param;
 
@@ -21,7 +21,7 @@ public interface CmBehaviorRecordDao {
      * @param keyword
      * @return
      */
-    List<RetuenEntity> getkeyword(@Param("keyword") String keyword);
+    List<ReturnEntity> getkeyword(@Param("keyword") String keyword);
 
     /**
      * 页面标签
@@ -60,7 +60,7 @@ public interface CmBehaviorRecordDao {
      * 标签库
      * @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.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
@@ -48,6 +49,58 @@ public interface CustomerServiceDao {
      */
     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
@@ -169,10 +222,10 @@ public interface CustomerServiceDao {
 
     /**
      * 弹框数据回显
-     * @param shopId
+     * @param shopProductId
      * @return
      */
-    CmShopPopUp getShopPopUp(@Param("shopId") Integer shopId);
+    CmShopPopUp getShopPopUp(@Param("shopProductId") Integer shopProductId);
 
     /**
      * 插入弹框数据
@@ -252,13 +305,13 @@ public interface CustomerServiceDao {
      * @param shopId
      * @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
      * @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
     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
  */
 @Data
-public class RetuenEntity {
+public class ReturnEntity {
     /**
      * key
      */
     private String id;
+    /**
+     * 名称
+     */
+    private String name;
     /**
      * 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 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 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
      */
     private Integer shopId;
+    /**
+     * 营销商品id
+     */
+    private Integer shopProductId;
     /**
      * 跟进状态 0 已跟进 1 未跟进
      */

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

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

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

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

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

@@ -15,6 +15,10 @@ public class CmShopPopUp {
      * 供应商Id
      */
     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 不统计
      */
     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;
-
-    //子订单ID
+    /**
+     * 子订单ID
+     */
     private Integer shopOrderID;
-    //订单商品ID
+    /**
+     * 订单商品ID
+     */
     private Integer orderProductID;
-    //税率
+    /**
+     * 税率
+     */
     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 java.util.List;
+import java.util.Map;
 
 /**
  * Description
@@ -50,7 +51,7 @@ public interface CmBehaviorRecordService {
      * @param pageSize
      * @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.caimei.CmShop;
 import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
+
+import java.util.List;
 
 /**
  * Description
@@ -42,6 +45,51 @@ public interface CustomerService {
      */
     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
@@ -94,11 +142,11 @@ public interface CustomerService {
 
     /**
      * 添加文章统计
-     * @param shopId
+     * @param shopProductId
      * @param infoIds
      * @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
      * @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
      */
-    ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId);
+    ResponseJson<CmShopPopUp> getShopPopUp(Integer shopProductId);
 
     /**
      * 谈款数据保存
@@ -216,6 +264,13 @@ public interface CustomerService {
      */
     ResponseJson delShopAdvertisingImage(Integer id);
 
+    /**
+     * 获取潜客供应商下统计商品
+     * @param shopId
+     * @return
+     */
+    ResponseJson<List<CmShopProduct>> getShopProductList(Integer shopId);
+
     /**
      * 供应商主页统计
      * @param shopId
@@ -237,13 +292,13 @@ public interface CustomerService {
      * @param shopId
      * @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
      * @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.caimei.CmBehaviorRecord;
 import com.caimei365.manager.entity.caimei.CmPageType;
+import com.caimei365.manager.entity.caimei.ReturnEntity;
 import com.caimei365.manager.service.caimei.user.CmBehaviorRecordService;
 import com.github.pagehelper.PageHelper;
 import lombok.extern.slf4j.Slf4j;
@@ -18,6 +19,8 @@ import java.net.URLDecoder;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
 
 /**
  * Description
@@ -85,8 +88,10 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
         cmBehaviorRecord.setBehaviorType(behaviorType);
         PageHelper.startPage(pageNum, pageSize);
         if (cmBehaviorRecord.getTodayType() == 0) {
+            // 今日数据
             list = cmBehaviorRecordDao.findListToday(cmBehaviorRecord);
         } else {
+            // 过往数据
             list = cmBehaviorRecordDao.findList(cmBehaviorRecord);
         }
         // 总时长
@@ -162,7 +167,8 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
      * @return
      */
     @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);
         // 详情
         List<CmBehaviorRecord> recordList = cmBehaviorRecordDao.recordList(cmBehaviorRecord);
@@ -170,6 +176,9 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
         List<CmBehaviorRecord> reginList = cmBehaviorRecordDao.selRegion(cmBehaviorRecord.getAccessDate());
         // 供应商信息
         List<CmBehaviorRecord> shopNameList = cmBehaviorRecordDao.behaviorShopNameList();
+        // 标签总结
+        List<ReturnEntity> label = new ArrayList<>();
+        AtomicReference<Integer> returnId = new AtomicReference<>(0);
         // 计算访问时长,填入信息
         recordList.forEach(r -> {
             r.setProductImage(AppUtils.getImageURL("product", r.getProductImage(), 0, ""));
@@ -216,9 +225,37 @@ public class CmBehaviorRecordServiceImpl implements CmBehaviorRecordService {
                 }
                 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);
-        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.JSONObject;
+import com.caimei.utils.AppUtils;
+import com.caimei.utils.StringUtil;
 import com.caimei365.manager.config.security.JwtLoginFilter;
 import com.caimei365.manager.dao.user.CustomerServiceDao;
 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.cmUser.*;
+import com.caimei365.manager.entity.caimei.product.Product;
 import com.caimei365.manager.service.caimei.user.CustomerService;
 import com.github.pagehelper.PageHelper;
 import org.springframework.stereotype.Service;
@@ -106,6 +109,113 @@ public class CustomerServiceImpl implements CustomerService {
         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
      */
     @Override
-    public ResponseJson saveShopInfo(Integer shopId, String infoIds) {
+    public ResponseJson saveShopInfo(Integer shopProductId, String infoIds) {
         List<String> infoId = new ArrayList<>();
         if (infoIds.contains(",")) {
             infoId = Arrays.asList(infoIds.split(","));
@@ -251,7 +361,7 @@ public class CustomerServiceImpl implements CustomerService {
         }
         for (String s : infoId) {
             CmShopInfo shopInfo = new CmShopInfo();
-            shopInfo.setShopId(shopId);
+            shopInfo.setShopProductId(shopProductId);
             shopInfo.setInfoId(Integer.parseInt(s));
             shopInfo.setStatus(0);
             shopInfo.setDelFlag(0);
@@ -328,12 +438,12 @@ public class CustomerServiceImpl implements CustomerService {
     /**
      * 添加搜索词统计
      *
-     * @param shopId
+     * @param shopProductId
      * @param keyWordIds
      * @return
      */
     @Override
-    public ResponseJson saveShopKeyword(Integer shopId, String keyWordIds) {
+    public ResponseJson saveShopKeyword(Integer shopProductId, String keyWordIds) {
         List<String> keyWordId = new ArrayList<>();
         if (keyWordIds.contains(",")) {
             keyWordId = Arrays.asList(keyWordIds.split(","));
@@ -342,7 +452,7 @@ public class CustomerServiceImpl implements CustomerService {
         }
         for (String s : keyWordId) {
             CmShopKeyword shopKeyword = new CmShopKeyword();
-            shopKeyword.setShopId(shopId);
+            shopKeyword.setShopProductId(shopProductId);
             shopKeyword.setSearchId(Integer.parseInt(s));
             shopKeyword.setStatus(0);
             shopKeyword.setDelFlag(0);
@@ -379,12 +489,12 @@ public class CustomerServiceImpl implements CustomerService {
     /**
      * 弹框数据回显
      *
-     * @param shopId
+     * @param shopProductId
      * @return
      */
     @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();
     }
 
+    /**
+     * 获取潜客供应商下统计商品
+     *
+     * @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
      */
     @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);
-        List<CmPageShopInfo> pageShopInfo = customerServiceDao.getPageShopInfo(shopId, startTime, endTime);
+        List<CmPageShopInfo> pageShopInfo = customerServiceDao.getPageShopInfo(shopId, productId, startTime, endTime);
         pageShopInfo.forEach(shop -> {
             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);
         return ResponseJson.success(page);
@@ -570,11 +697,17 @@ public class CustomerServiceImpl implements CustomerService {
      * @return
      */
     @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);
-        List<CmPageShopKeyword> pageShopKeyword = customerServiceDao.getPageShopKeyword(shopId, startTime, endTime);
+        List<CmPageShopKeyword> pageShopKeyword = customerServiceDao.getPageShopKeyword(shopId, productId, startTime, endTime);
         pageShopKeyword.forEach(shop -> {
             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);
         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;
     }
 
-
-
+    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
     </sql>
 
-    <select id="getkeyword" resultType="com.caimei365.manager.entity.caimei.RetuenEntity">
+    <select id="getkeyword" resultType="com.caimei365.manager.entity.caimei.ReturnEntity">
         select
             id,
             keyword as value
@@ -39,160 +39,180 @@
 
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         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>
-            delFlag = 0
+            cbri.delFlag = 0
+            <if test="clubId != null">
+                AND cbri.clubId = #{clubId}
+            </if>
             <if test="ip != null and ip != ''">
-                AND IP = #{ip}
+                AND cbri.IP = #{ip}
             </if>
             <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 test="companyType != null and companyType != ''">
-                AND companyType = #{companyType}
+                AND cbri.companyType = #{companyType}
             </if>
             <if test="accessClient != null and accessClient != ''">
-                AND accessClient =#{accessClient}
+                AND cbri.accessClient =#{accessClient}
             </if>
             <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 test="phoneNumber != null and phoneNumber != ''">
-                AND phoneNumber = #{phoneNumber}
+                AND cbri.phoneNumber = #{phoneNumber}
             </if>
             <if test="spName != null and spName != ''">
-                AND spName = #{spName}
+                AND cbri.spName = #{spName}
             </if>
             <if test="headUserId != null and headUserId != ''">
-                AND headUserId = #{headUserId}
+                AND cbri.headUserId = #{headUserId}
             </if>
             <if test="productArchiveId != null and productArchiveId != ''">
-                AND productArchiveId = #{productArchiveId}
+                AND cbri.productArchiveId = #{productArchiveId}
             </if>
             <if test="relevanceShop != null and relevanceShop != ''">
-                AND (relevanceShop like concat('%',#{relevanceShop},'%')
+                AND (cbri.relevanceShop like concat('%',#{relevanceShop},'%')
                     <if test="behaviorType == 2">
-                        or behaviorType = #{behaviorType}
+                        or cbri.behaviorType = #{behaviorType}
                     </if>
                     )
             </if>
             <if test="labels != null and labels.size > 0">
                 AND
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
-                    label like concat('%',#{label},'%')
+                    cbri.label like concat('%',#{label},'%')
                 </foreach>
             </if>
             <if test="pageLabels != null and pageLabels != ''">
-                AND pageLabels like concat('%', #{pageLabels}, '%')
+                AND cbri.pageLabels like concat('%', #{pageLabels}, '%')
             </if>
                 <if test="pageTypes != null and pageTypes != ''">
-                AND pageTypes like concat('%', #{pageTypes}, '%')
+                AND cbri.pageTypes like concat('%', #{pageTypes}, '%')
             </if>
             <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>
         </where>
-        ORDER BY accessTime DESC
+        ORDER BY cbri.accessTime DESC
         <if test="exportType == 1">
             limit 5000
         </if>
     </select>
     <select id="findListToday" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         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>
+            <if test="clubId != null">
+                AND cbrt.clubId = #{clubId}
+            </if>
             <if test="ip != null and ip != ''">
-                AND IP = #{ip}
+                AND cbrt.IP = #{ip}
             </if>
             <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 test="companyType != null and companyType != ''">
-                AND companyType = #{companyType}
+                AND cbrt.companyType = #{companyType}
             </if>
             <if test="accessClient != null and accessClient != ''">
-                AND accessClient =#{accessClient}
+                AND cbrt.accessClient =#{accessClient}
             </if>
             <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 test="phoneNumber != null and phoneNumber != ''">
-                AND phoneNumber = #{phoneNumber}
+                AND cbrt.phoneNumber = #{phoneNumber}
             </if>
             <if test="spName != null and spName != ''">
-                AND spName = #{spName}
+                AND cbrt.spName = #{spName}
             </if>
             <if test="headUserId != null and headUserId != ''">
-                AND headUserId = #{headUserId}
+                AND cbrt.headUserId = #{headUserId}
             </if>
             <if test="productArchiveId != null and productArchiveId != ''">
-                AND productArchiveId = #{productArchiveId}
+                AND cbrt.productArchiveId = #{productArchiveId}
             </if>
             <if test="relevanceShop != null and relevanceShop != ''">
-                AND relevanceShop like concat('%',#{relevanceShop},'%')
+                AND cbrt.relevanceShop like concat('%',#{relevanceShop},'%')
             </if>
             <if test="labels != null and labels.size > 0">
                 AND
                 <foreach collection="labels" open="(" close=")" separator="or" item="label">
-                    label like concat('%',#{label},'%')
+                    cbrt.label like concat('%',#{label},'%')
                 </foreach>
             </if>
             <if test="pageLabels != null and pageLabels != ''">
-                AND pageLabels like concat('%', #{pageLabels}, '%')
+                AND cbrt.pageLabels like concat('%', #{pageLabels}, '%')
             </if>
             <if test="pageTypes != null and pageTypes != ''">
-                AND pageTypes like concat('%', #{pageTypes}, '%')
+                AND cbrt.pageTypes like concat('%', #{pageTypes}, '%')
             </if>
             <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>
         </where>
-        ORDER BY accessTime DESC
+        ORDER BY cbrt.accessTime DESC
     </select>
     <select id="selRegion" resultType="com.caimei365.manager.entity.caimei.CmBehaviorRecord">
         SELECT * FROM cm_behavior_record_ref where accessTime like concat('%',#{accessDate},'%')
@@ -228,7 +248,7 @@
         </where>
         ORDER BY accessTime DESC
     </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
         FROM cm_user_search_frequency cusf
          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 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.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
         left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
+        LEFT JOIN cm_praise_statistics c ON cusf.id = c.authorId
         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 !=''">-->
 <!--            AND (cusf.searchTime BETWEEN #{beginTime} AND #{endTime} or cusf.searchTime IS NULL)-->
 <!--        </if>-->
         <if test="keyword !=null and keyword !=''">
             AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
         </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">
             AND cusf.trueStatus = #{labelStatus}
         </if>
         <if test="fromSearch != null">
             AND cusf.fromSearch = #{fromSearch}
         </if>
+        GROUP BY cusf.id
         ORDER BY cusf.frequency DESC, cusf.searchTime DESC
     </select>
 

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

@@ -354,12 +354,10 @@
     </select>
     <select id="newCmShopGet" resultType="com.caimei365.manager.entity.caimei.svip.NewCmShop">
         SELECT
-        <include refid="newCmShopColumns"/>,
-        copi.validFlag AS "validFlag",
+        <include refid="newCmShopColumns"/>
         FROM shop a
         <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 id="findRedemptionCodeNum" resultType="java.lang.Integer">
         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
         <where>
             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 !=''">
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
             </if>
@@ -152,6 +155,9 @@
         LEFT JOIN product p ON p.productID = ccr.productID
         LEFT JOIN shop sh ON sh.shopID = p.shopID
         <where>
+            <if test="clubId != null">
+                AND ccr.clubId = #{clubId}
+            </if>
             <if test="remarks != null and remarks !=''">
                 AND ccr.remarks LIKE concat('%',#{remarks},'%')
             </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
             DISTINCT css.id as id,
                      css.shopID AS shopId,
+                     css.logo,
                      s.name as shopName,
                      s.linkMan,
                      s.contractMobile AS mobile,
                      s.status AS shopStatus,
                      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
         FROM cm_shop_statistics css
                  LEFT JOIN shop s ON css.shopId = s.shopId
@@ -52,10 +54,89 @@
         set status = #{status}
         where id = #{id}
     </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 cri.id,
                cri.IP,
-               cri.shopId,
+               cri.shopProductId,
                cri.followUpStatus,
                cri.consultName,
                cri.consultMobile,
@@ -65,7 +146,7 @@
                cri.createTime
         FROM cm_roos_information cri
         <where>
-          shopId = #{shopId}
+            shopProductId = #{shopProductId}
           AND consultName IS NOT NULL
           AND consultMobile IS NOT NULL
             <if test="consultName != null and consultName != ''">
@@ -128,7 +209,7 @@
         FROM cm_shop_info csi
         LEFT JOIN info i ON i.id = csi.infoId
         <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">
                 and csi.infoId = #{infoId}
             </if>
@@ -159,8 +240,8 @@
     </select>
 
     <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>
 
     <update id="updateShopInfoStatus">
@@ -178,7 +259,7 @@
     <select id="getShopKeyword" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopKeyword">
         SELECT
             csk.id,
-            csk.shopId,
+            csk.shopProductId,
             cusf.keyword,
             cusf.frequency as number,
             cusf.searchTime,
@@ -187,7 +268,7 @@
         FROM cm_shop_keyword csk
                  LEFT JOIN cm_user_search_frequency cusf ON cusf.id = csk.searchId
         <where>
-            csk.shopId = #{shopId}
+            csk.shopProductId = #{shopProductId}
             and csk.delFlag = 0 and cusf.delStatus = 1
             <if test="keyword != null and keyword != ''">
                 and cusf.keyword like concat('%',#{keyword},'%')
@@ -213,8 +294,8 @@
     </select>
 
     <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>
 
     <update id="updateShopKeywordStatus">
@@ -232,18 +313,18 @@
     <select id="getShopPopUp" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopPopUp">
         select
         id,
-        shopId,
+        shopProductId,
         image,
         guidingOne,
         guidingTwo,
         addTime
         from cm_shop_popUp
-        where shopId = #{shopId}
+        where shopProductId = #{shopProductId}
     </select>
 
     <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>
 
     <update id="updateShopPopUp">
@@ -320,6 +401,14 @@
         where id = #{id}
     </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
             cps.id,
@@ -371,15 +460,25 @@
             i.title,
             i.onlineStatus,
             cpsi.link,
+            p.productId,
+            p.name as productName,
+            p.mainImage,
             IFNULL(SUM(cpsi.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsi.accessDuration), 0) AS accessDuration,
             IFNULL((IFNULL(SUM(cpsi.accessDuration), 0) / IFNULL(SUM(cpsi.accessNumber), 0)), 0) AS averageDuration
         FROM cm_page_shop_info cpsi
         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}
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             and cpsi.accessDate BETWEEN #{startTime} and #{endTime}
         </if>
+        <if test="productId != null">
+            and csp.productId = #{productId}
+        </if>
         group by cpsi.infoId
     </select>
 
@@ -389,15 +488,25 @@
             cpsk.shopId,
             cusf.keyword,
             cpsk.link,
+            p.productId,
+            p.name as productName,
+            p.mainImage,
             IFNULL(SUM(cpsk.accessNumber), 0) AS accessNumber,
             IFNULL(SUM(cpsk.accessDuration), 0) AS accessDuration,
             IFNULL((IFNULL(SUM(cpsk.accessDuration), 0) / IFNULL(SUM(cpsk.accessNumber), 0)), 0) AS averageDuration
         FROM cm_page_shop_keyword cpsk
         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}
         <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
             and cpsk.accessDate BETWEEN #{startTime} and #{endTime}
         </if>
+        <if test="productId != null">
+            and csp.productId = #{productId}
+        </if>
         group by cpsk.searchId
     </select>
 

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

@@ -1,13 +1,194 @@
+/*
 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.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
 class ManagerApplicationTests {
 
+    @Resource private formDataUtils formDataUtils;
+    @Resource private CmMarketShopDao marketShopDao;
+
     @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);
+            }
+        }
     }
 
 }
+*/