Selaa lähdekoodia

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

# Conflicts:
#	src/main/java/com/caimei365/manager/dao/KeyWordDao.java
#	src/main/java/com/caimei365/manager/service/caimei/KeyWordService.java
#	src/main/resources/mapper/KeyWordDao.xml
kaick 1 vuosi sitten
vanhempi
commit
3c901d97b7
48 muutettua tiedostoa jossa 5896 lisäystä ja 22 poistoa
  1. 13 0
      pom.xml
  2. 44 0
      src/main/java/com/caimei365/manager/FastDFS/FastDFSClient.java
  3. 43 0
      src/main/java/com/caimei365/manager/config/CorsConfig.java
  4. 1 1
      src/main/java/com/caimei365/manager/config/security/SecurityConfig.java
  5. 101 1
      src/main/java/com/caimei365/manager/controller/caimei/keyword/KeyWordApi.java
  6. 242 0
      src/main/java/com/caimei365/manager/controller/caimei/user/CmClubRemarksApi.java
  7. 454 0
      src/main/java/com/caimei365/manager/controller/caimei/user/CustomerApi.java
  8. 75 0
      src/main/java/com/caimei365/manager/dao/KeyWordDao.java
  9. 185 0
      src/main/java/com/caimei365/manager/dao/user/CmClubRemarksDao.java
  10. 237 0
      src/main/java/com/caimei365/manager/dao/user/CustomerServiceDao.java
  11. 52 0
      src/main/java/com/caimei365/manager/entity/caimei/CmPriorKeyword.java
  12. 4 0
      src/main/java/com/caimei365/manager/entity/caimei/CmShop.java
  13. 17 1
      src/main/java/com/caimei365/manager/entity/caimei/KeyWord.java
  14. 225 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmClubRemarks.java
  15. 37 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmConsulttype.java
  16. 48 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShop.java
  17. 58 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopInfo.java
  18. 46 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopKeyword.java
  19. 58 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopProduct.java
  20. 77 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmReport.java
  21. 42 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmRoosInformation.java
  22. 38 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmSaleMan.java
  23. 57 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopAdvertisingImage.java
  24. 52 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopInfo.java
  25. 48 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopKeyword.java
  26. 34 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopPopUp.java
  27. 49 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmShopStatistics.java
  28. 68 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmUserSearchFrequency.java
  29. 148 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/Info.java
  30. 27 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/RemarksFileVo.java
  31. 49 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/ServiceProviderModel.java
  32. 169 0
      src/main/java/com/caimei365/manager/entity/caimei/cmUser/VisitRemarkVo.java
  33. 114 0
      src/main/java/com/caimei365/manager/service/caimei/CmOssArchiveService.java
  34. 62 0
      src/main/java/com/caimei365/manager/service/caimei/KeyWordService.java
  35. 157 0
      src/main/java/com/caimei365/manager/service/caimei/impl/KeyWordServiceImpl.java
  36. 141 0
      src/main/java/com/caimei365/manager/service/caimei/user/CmClubRemarksService.java
  37. 234 0
      src/main/java/com/caimei365/manager/service/caimei/user/CustomerService.java
  38. 463 0
      src/main/java/com/caimei365/manager/service/caimei/user/impl/CmClubRemarksServiceImpl.java
  39. 575 0
      src/main/java/com/caimei365/manager/service/caimei/user/impl/CustomerServiceImpl.java
  40. 11 10
      src/main/java/com/caimei365/manager/service/wechat/impl/WechatReplyServiceImpl.java
  41. 259 0
      src/main/java/com/caimei365/manager/utils/OSSUtils.java
  42. 63 0
      src/main/java/com/caimei365/manager/utils/formDataUtils.java
  43. 19 0
      src/main/resources/config/beta/application-beta.yml
  44. 19 0
      src/main/resources/config/dev/application-dev.yml
  45. 20 0
      src/main/resources/config/prod/application-prod.yml
  46. 117 9
      src/main/resources/mapper/KeyWordDao.xml
  47. 473 0
      src/main/resources/mapper/user/CmClubRemarksDao.xml
  48. 371 0
      src/main/resources/mapper/user/CustomerServiceDao.xml

+ 13 - 0
pom.xml

@@ -99,6 +99,19 @@
             <version>2.3</version>
         </dependency>
 
+        <!--dfs-->
+        <dependency>
+            <groupId>com.github.tobato</groupId>
+            <artifactId>fastdfs-client</artifactId>
+            <version>1.26.4</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>ch.qos.logback</groupId>
+                    <artifactId>logback-classic</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
         <!-- jxls end -->
         <dependency>
             <groupId>com.caimei</groupId>

+ 44 - 0
src/main/java/com/caimei365/manager/FastDFS/FastDFSClient.java

@@ -0,0 +1,44 @@
+package com.caimei365.manager.FastDFS;
+
+import com.github.tobato.fastdfs.domain.StorePath;
+import com.github.tobato.fastdfs.proto.storage.DownloadByteArray;
+import com.github.tobato.fastdfs.service.FastFileStorageClient;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.*;
+
+@Component
+public class FastDFSClient {
+    @Resource
+    private FastFileStorageClient storageClient;
+
+
+    // 文件上传
+    public String uploadFile(String path) throws FileNotFoundException {
+        File file = new File(path);
+        InputStream input = new FileInputStream(file);
+        long size = FileUtils.sizeOf(file);
+        String name = file.getName();
+        String fileName = name.substring(name.lastIndexOf("/") + 1);
+        StorePath storePath = storageClient.uploadFile(input, size, FilenameUtils.getExtension(fileName), null);
+        return storePath.getFullPath();
+    }
+
+    // 文件下载
+    public boolean downloadFile(String path, String downloadFilePath) throws IOException {
+        File file = new File(downloadFilePath);
+        FileOutputStream outputStream = null;
+        // fastdfs 文件读取
+        String filepath = path.substring(path.lastIndexOf("group1/") + 7);
+        DownloadByteArray callback = new DownloadByteArray();
+        byte[] content = storageClient.downloadFile("group1", filepath, callback);
+        // 数据写入指定文件夹中
+        outputStream = new FileOutputStream(file);
+        outputStream.write(content);
+        return true;
+    }
+
+}

+ 43 - 0
src/main/java/com/caimei365/manager/config/CorsConfig.java

@@ -0,0 +1,43 @@
+package com.caimei365.manager.config;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/21
+ */
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class CorsConfig implements Filter {
+
+
+    @Override
+    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
+        HttpServletResponse response = (HttpServletResponse) res;
+        HttpServletRequest request = (HttpServletRequest) req;
+        response.setHeader("Access-Control-Allow-Origin", "*"); // 允许的前端地址
+        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); // 允许的 HTTP 方法
+        response.setHeader("Access-Control-Allow-Headers", "*");  // 允许的请求头
+        response.setHeader("Access-Control-Max-Age", "3600");
+        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+            response.setStatus(HttpServletResponse.SC_OK);
+        } else {
+            chain.doFilter(req, res);
+        }
+    }
+}

+ 1 - 1
src/main/java/com/caimei365/manager/config/security/SecurityConfig.java

@@ -44,7 +44,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
     @Override
     public void configure(WebSecurity web) {
         // 需要放行的URL
-        web.ignoring().antMatchers("/register", "/hello");
+        web.ignoring().antMatchers("/register", "/hello","/formData/MultiPictareaddData");
     }
 
     /**

+ 101 - 1
src/main/java/com/caimei365/manager/controller/caimei/keyword/KeyWordApi.java

@@ -3,15 +3,19 @@ package com.caimei365.manager.controller.caimei.keyword;
 import com.alibaba.excel.EasyExcel;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmPriorKeyword;
 import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel;
 import com.caimei365.manager.service.caimei.KeyWordService;
 import com.caimei365.manager.service.caimei.listener.KeywordListener;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 
 
 /**
@@ -35,7 +39,7 @@ public class KeyWordApi {
      * beginTime  自定义时间查询起始时间
      * endTime    自定义时间查询终止时间
      * labelStatus  标签库状态 0未添加 1已添加 传1即是标签列表
-     * fromSearch 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入)
+     * fromSearch 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入 4:协销填写
      */
     @GetMapping("/keyword/list")
     public ResponseJson<PaginationVo<KeyWord>> getKeyWordList(String keyword, String beginTime, String endTime,
@@ -129,4 +133,100 @@ public class KeyWordApi {
     public ResponseJson delLabel(String id) {
         return keyWordService.deleteLabel(id);
     }
+
+    /**
+     * 协销列表
+     * @return
+     */
+    @GetMapping("/getServiceList")
+    public ResponseJson<List<ServiceProviderModel>> getServiceList() { return keyWordService.getServiceList(); }
+
+    /**
+     * 静态标签列表
+     * keyword 关键词
+     * beginTime  自定义时间查询起始时间
+     * endTime    自定义时间查询终止时间
+     * labelStatus  标签库状态 0未添加 1已添加 传1即是标签列表
+     * fromSearch 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入 4:协销填写)
+     */
+    @GetMapping("/statekeyword/list")
+    public ResponseJson<PaginationVo<KeyWord>> getStateKeyWordList(String keyword, String beginTime, String endTime,
+                                                                   Integer fromSearch,  Integer serviceProviderId,
+                                                              @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                              @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+        return keyWordService.getStateKeyWordList(keyword, fromSearch, beginTime, endTime, serviceProviderId, pageNum, pageSize);
+    }
+
+    /**
+     * 保存静态标签
+     * @param keyword
+     * @return
+     */
+    @GetMapping("/saveLabelByState")
+    public ResponseJson saveLabelByState(String keyword) {
+        if (StringUtils.isBlank(keyword)) {
+            return ResponseJson.error(-1, "标签不能为空", null);
+        }
+        return keyWordService.insertLabelByState(keyword);
+    }
+
+    /**
+     * 优先展示标签列表
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+     @GetMapping("/getPriorKeywordList")
+     public ResponseJson<PaginationVo<CmPriorKeyword>> getPriorKeywordList(String keyword, Integer fromSearch, Integer dynamicStatus,
+                                                                           @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                           @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+
+        return keyWordService.getPriorKeywordList(keyword, fromSearch, dynamicStatus, pageNum, pageSize);
+     }
+
+    /**
+     * 选择标签
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus 0 为动态标签 1 静态标签
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+     @GetMapping("/getPickKeyword")
+     public ResponseJson<PaginationVo<KeyWord>> getPickKeyword(String keyword, Integer fromSearch, Integer dynamicStatus,
+                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                      @RequestParam(value = "pageSize", defaultValue = "20") int pageSize) {
+
+         return keyWordService.getPickKeyword(keyword, fromSearch, dynamicStatus, pageNum, pageSize);
+     }
+
+    /**
+     * 保存优先展示标签
+     * @param searchIds
+     * @return
+     */
+     @GetMapping("/savePriorKeyword")
+     public ResponseJson savePriorKeyword(String searchIds) {
+        if (StringUtils.isBlank(searchIds)) {
+            return ResponseJson.error(-1, "需优先展示的标签不能为空", null);
+        }
+        return keyWordService.savePriorKeyword(searchIds);
+     }
+
+    /**
+     * 删除优先展示标签
+     * @param ids
+     * @return
+     */
+     @GetMapping("/delPriorKeyword")
+     public ResponseJson delPriorKeyword(String ids) {
+         if ( StringUtils.isBlank(ids)) {
+             return ResponseJson.error(-1, "Id不能为空", null);
+         }
+         return keyWordService.delPriorKeyword(ids);
+     }
 }

+ 242 - 0
src/main/java/com/caimei365/manager/controller/caimei/user/CmClubRemarksApi.java

@@ -0,0 +1,242 @@
+package com.caimei365.manager.controller.caimei.user;
+
+import com.caimei365.manager.config.security.ConstantKey;
+import com.caimei365.manager.config.security.JwtService;
+import com.caimei365.manager.config.security.SecurityConfig;
+import com.caimei365.manager.config.thinkgem.utils.Encodes;
+import com.caimei365.manager.entity.PaginationVo;
+import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.service.caimei.user.CmClubRemarksService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@RestController
+@RequestMapping("/user/remarks")
+public class CmClubRemarksApi {
+
+    @Autowired private CmClubRemarksService cmClubRemarksService;
+    @Resource private JwtService jwtService;
+
+    /**
+     * 咨询记录类别
+     * @return
+     */
+    @GetMapping("/getClassName")
+    public ResponseJson<List<CmConsulttype>> getClassName() {
+        return cmClubRemarksService.getClassName();
+    }
+
+    /**
+     * 获取当天协销咨询记录信息
+     * @return
+     */
+    @GetMapping("/getServiceList")
+    public ResponseJson<Map<String, Object>> getServiceList(String accessDate) {
+        return cmClubRemarksService.getServiceList(accessDate);
+    }
+
+    /**
+     * 已注册用户咨询记录
+     *
+     * @param cmClubRemarks
+     * @return
+     */
+    @GetMapping("/registList")
+    public ResponseJson<PaginationVo<CmClubRemarks>> registList(CmClubRemarks cmClubRemarks,
+                                                 @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                 @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        if (null == cmClubRemarks)  {
+            return ResponseJson.error(-1, "参数为空", null);
+        }
+        if (null == cmClubRemarks.getServiceProviderId())  {
+            return ResponseJson.error(-1, "协销Id为空", null);
+        }
+        if (null == cmClubRemarks.getTodayTime())  {
+            return ResponseJson.error(-1, "咨询记录时间为空", null);
+        }
+        return cmClubRemarksService.findRegistList(cmClubRemarks, pageNum, pageSize);
+    }
+
+    /**
+     * 资料备注文件下载
+     */
+    @GetMapping("/remarks/download")
+    public void downloadRemarks(String fileName, String ossName, HttpServletRequest request, HttpServletResponse response) throws IOException {
+
+        cmClubRemarksService.downloadRemarks(fileName, ossName, request, response);
+    }
+
+    /**
+     * 报备列表
+     * @param cmReport
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/ReportList")
+    public ResponseJson<PaginationVo<CmReport>> getReportList(CmReport cmReport,
+                                                              @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                              @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+
+        return cmClubRemarksService.getReportList(cmReport, pageNum, pageSize);
+    }
+
+    /**
+     * 报备列表查看详情
+     * @param cmClubRemarks
+     * @return
+     */
+    @GetMapping("/cmRegistReportList")
+    public ResponseJson<List<CmClubRemarks>> cmRegistReportList(CmClubRemarks cmClubRemarks) {
+        if (null == cmClubRemarks.getReportId()) {
+            return ResponseJson.error(-1, "报备记录Id不能为空", null);
+        }
+        return cmClubRemarksService.cmRegistReportList(cmClubRemarks);
+    }
+
+    /**
+     * 取消关联
+     * @param remarksId
+     * @param type
+     * @return
+     */
+    @GetMapping("/audit")
+    public ResponseJson audit(Integer remarksId, Integer type) {
+        if (null == remarksId) {
+            return ResponseJson.error(-1, "报备记录Id不能为空", null);
+        }
+        if (null == type) {
+            return ResponseJson.error(-1, "报备记录类型不能为空", null);
+        }
+        return cmClubRemarksService.audit(remarksId, type);
+    }
+
+    /**
+     * 删除报备列表
+     * @param reportId
+     * @return
+     */
+    @GetMapping("/deleteReport/{reportId}")
+    public ResponseJson deleteReport(@PathVariable("reportId") Integer reportId) {
+        if (null == reportId) {
+            return ResponseJson.error(-1, "报备记录Id不能为空", null);
+        }
+        return cmClubRemarksService.deleteReport(reportId);
+    }
+
+    /**
+     * 审核报备记录
+     * @param reportId
+     * @param auditText
+     * @param status
+     * @param request
+     * @return
+     */
+    @GetMapping("/reportCount")
+    public ResponseJson reportCount(Integer reportId, String auditText, Integer status, HttpServletRequest request) {
+        String token = request.getHeader(ConstantKey.TOKEN_NAME);
+        String userName = jwtService.getUsername(token);
+        return cmClubRemarksService.reportCount(reportId, userName, auditText, status);
+    }
+
+    /**
+     * 咨询记录类别
+     * @param cmConsulttype
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getConsultList")
+    public ResponseJson<PaginationVo<CmConsulttype>> getConsultList(CmConsulttype cmConsulttype,
+                                                                    @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                    @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        return cmClubRemarksService.getConsultList(cmConsulttype, pageNum, pageSize);
+    }
+
+    /**
+     * 保存咨询记录类别
+     * @param cmConsulttype
+     * @return
+     */
+    @PostMapping("/saveConsult")
+    public ResponseJson saveConsult(@RequestBody CmConsulttype cmConsulttype) {
+
+        return cmClubRemarksService.saveConsult(cmConsulttype);
+    }
+
+
+    /**
+     * 删除咨询记录类别
+     * @param id
+     * @return
+     */
+    @GetMapping("/deleteConsult/{id}")
+    public ResponseJson deleteConsult(@PathVariable("id") Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "咨询类别Id不能为空", null);
+        }
+        return cmClubRemarksService.deleteConsult(id);
+    }
+
+    /**
+     * 排序
+     * @param id
+     * @param sortNumber
+     * @return
+     */
+    @GetMapping("/sort")
+    public ResponseJson sort(Integer id, Integer sortNumber) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == sortNumber) {
+            return ResponseJson.error(-1, "排序不能为空", null);
+        }
+        return cmClubRemarksService.sort(id, sortNumber);
+    }
+
+    /**
+     * 未注册用户咨询记录
+     * @param visit
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/visitRemarkList")
+    public ResponseJson<PaginationVo<VisitRemarkVo>> visitRemarkList(VisitRemarkVo visit,
+                                                                     @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                     @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+
+        return cmClubRemarksService.visitRemarkList(visit, pageNum, pageSize);
+    }
+
+    /**
+     * 未注册用户数据详情
+     */
+    @GetMapping("/remarksList")
+    public ResponseJson<PaginationVo<CmClubRemarks>> remarksList(VisitRemarkVo visitRemarkVo,
+                              @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                              @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+
+        return cmClubRemarksService.remarksList(visitRemarkVo, pageNum, pageSize);
+    }
+
+}

+ 454 - 0
src/main/java/com/caimei365/manager/controller/caimei/user/CustomerApi.java

@@ -0,0 +1,454 @@
+package com.caimei365.manager.controller.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.cmUser.*;
+import com.caimei365.manager.service.caimei.user.CustomerService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+@RestController
+@RequestMapping("/user/customer")
+public class CustomerApi {
+
+    @Autowired private CustomerService customerService;
+
+    /**
+     * 潜客收集供应商列表
+     * @param cmShopStatistics
+     * @return
+     */
+    @GetMapping("/getCustomerShopList")
+    public ResponseJson<PaginationVo<CmShopStatistics>> getCustomerShopList(CmShopStatistics cmShopStatistics,
+                                                                    @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                    @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        return customerService.getCustomerShopList(cmShopStatistics, pageNum, pageSize);
+    }
+
+    /**
+     * 供应商列表
+     * @param shopName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getShopList")
+    public ResponseJson<PaginationVo<CmShop>> getShopList(String shopName,
+                                                          @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                          @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        return customerService.getShopLiat(shopName, pageNum, pageSize);
+    }
+
+    /**
+     * 添加统计供应商
+     * @param shopIds
+     * @return
+     */
+    @GetMapping("/saveCustomerShop")
+    public ResponseJson saveCustomerShop(String shopIds) {
+        if (null == shopIds) {
+            return ResponseJson.error(-1, "添加的供应商不能为空", null);
+        }
+        return customerService.saveCustomerShop(shopIds);
+    }
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    @GetMapping("/renewCustomerShop")
+    public ResponseJson renewCustomerShop(Integer id, Integer status) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == status) {
+            return ResponseJson.error(-1, "状态不能为空", null);
+        }
+        return customerService.renewCustomerShop(id, status);
+    }
+
+    /**
+     * 游客统计
+     * @param cmRoosInformation
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getCmInformationList")
+    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);
+        }
+        return customerService.getCmInformationList(cmRoosInformation, pageNum, pageSize);
+    }
+
+    /**
+     * 设置跟进状态
+     * @param id
+     * @param followUpStatus
+     * @return
+     */
+    @GetMapping("/renewFollowUpStatus")
+    public ResponseJson renewFollowUpStatus(Integer id, Integer followUpStatus) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == followUpStatus) {
+            return ResponseJson.error(-1, "状态不能为空", null);
+        }
+        return customerService.renewFollowUpStatus(id, followUpStatus);
+    }
+
+    /**
+     * 相关文章列表
+     * @param cmShopInfo
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getShopInfoList")
+    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);
+        }
+        return customerService.getShopInfoList(cmShopInfo, pageNum, pageSize);
+    }
+
+    /**
+     * 选择文章
+     * @param id
+     * @param title
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getInfoList")
+    public ResponseJson<PaginationVo<Info>> getInfoList(Integer id, String title,
+                                                        @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                        @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        return customerService.getInfoList(id, title, pageNum, pageSize);
+    }
+
+    /**
+     * 添加文章统计
+     * @param shopId
+     * @param infoIds
+     * @return
+     */
+    @GetMapping("/saveShopInfo")
+    public ResponseJson saveShopInfo(Integer shopId, String infoIds){
+        if (null == shopId) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        if (null == infoIds) {
+            return ResponseJson.error(-1, "选择文章不能为空", null);
+        }
+        return customerService.saveShopInfo(shopId, infoIds);
+    }
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    @GetMapping("/renewShopInfo")
+    public ResponseJson renewShopInfo(Integer id, Integer status) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == status) {
+            return ResponseJson.error(-1, "状态不能为空", null);
+        }
+        return customerService.renewShopInfo(id, status);
+    }
+
+    /**
+     * 删除统计文章
+     * @param id
+     * @return
+     */
+    @GetMapping("/delShopInfo/{id}")
+    public ResponseJson delShopInfo(@PathVariable("id") Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        return customerService.delShopInfo(id);
+    }
+
+    /**
+     * 相关搜索词统计列表
+     * @param cmShopKeyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getShopKeywordList")
+    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);
+        }
+        return customerService.getShopKeywordList(cmShopKeyword, pageNum, pageSize);
+    }
+
+    /**
+     * 选择搜索词
+     * @param keyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getSearchFrequencyList")
+    public ResponseJson<PaginationVo<CmUserSearchFrequency>> getSearchFrequencyList(String keyword,
+                                                        @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                        @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+        return customerService.getSearchFrequencyList(keyword, pageNum, pageSize);
+    }
+
+    /**
+     * 添加搜索词统计
+     * @param shopId
+     * @param keyWordIds
+     * @return
+     */
+    @GetMapping("/saveShopKeyword")
+    public ResponseJson saveShopKeyword(Integer shopId, String keyWordIds){
+        if (null == shopId) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        if (null == keyWordIds) {
+            return ResponseJson.error(-1, "选择搜索词不能为空", null);
+        }
+        return customerService.saveShopKeyword(shopId, keyWordIds);
+    }
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    @GetMapping("/renewShopKeyword")
+    public ResponseJson renewShopKeyword(Integer id, Integer status) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == status) {
+            return ResponseJson.error(-1, "状态不能为空", null);
+        }
+        return customerService.renewShopKeyword(id, status);
+    }
+
+    /**
+     * 删除统计搜索词
+     * @param id
+     * @return
+     */
+    @GetMapping("/delShopKeyword/{id}")
+    public ResponseJson delShopKeyword(@PathVariable("id") Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        return customerService.delShopKeyword(id);
+    }
+
+    /**
+     * 弹框信息回显
+     * @param shopId
+     * @return
+     */
+    @GetMapping("/getShopPopUp")
+    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId) {
+        if (null == shopId) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        return customerService.getShopPopUp(shopId);
+    }
+
+    /**
+     * 弹框信息保存
+     * @param cmShopPopUp
+     * @return
+     */
+    @PostMapping("/saveShopPopUp")
+    public ResponseJson saveShopPopUp(@RequestBody CmShopPopUp cmShopPopUp) {
+        if (null == cmShopPopUp.getShopId()) {
+            return ResponseJson.error(-1, "供应商Id不能为空", null);
+        }
+        if (null == cmShopPopUp.getImage()) {
+            return ResponseJson.error(-1, "显示图不能为空", null);
+        }
+        if (null == cmShopPopUp.getGuidingOne()) {
+            return ResponseJson.error(-1, "引导语不能为空", null);
+        }
+        if (null == cmShopPopUp.getGuidingTwo()) {
+            return ResponseJson.error(-1, "引导语不能为空", null);
+        }
+        return customerService.saveShopPopUp(cmShopPopUp);
+    }
+
+    /**
+     * 供应商广告列表
+     * @param cmShopAdvertisingImage
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @GetMapping("/getShopAdvertisingImage")
+    public ResponseJson<PaginationVo<CmShopAdvertisingImage>> getShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage,
+                                                                                      @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                                                                      @RequestParam(value = "pageSize",defaultValue = "20") int pageSize) {
+
+        return customerService.getShopAdvertisingImage(cmShopAdvertisingImage, pageNum, pageSize);
+    }
+
+    /**
+     * 供应商广告信息回显
+     * @param id
+     * @return
+     */
+    @GetMapping("/getShopAdvertisingImageById/{id}")
+    public ResponseJson<CmShopAdvertisingImage> getShopAdvertisingImageById(@PathVariable("id") Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "Id不能为空", null);
+        }
+        return customerService.getShopAdvertisingImageById(id);
+    }
+
+    /**
+     * 保存供应商广告信息
+     * @param cmShopAdvertisingImage
+     * @return
+     */
+    @PostMapping("/saveShopAdvertisingImage")
+    public ResponseJson saveShopAdvertisingImage(@RequestBody CmShopAdvertisingImage cmShopAdvertisingImage) {
+
+        return customerService.saveShopAdvertisingImage(cmShopAdvertisingImage);
+    }
+
+    /**
+     * 一键排序
+     * @param id
+     * @param sort
+     * @return
+     */
+    @GetMapping("/renewShopAdvertisingImageSort")
+    public ResponseJson renewShopAdvertisingImageSort(Integer id, Integer sort) {
+        if (null == id) {
+            return ResponseJson.error(-1, "排序数据id不能为空", null);
+        }
+        if (null == sort) {
+            return ResponseJson.error(-1, "排序指不能为空", null);
+        }
+        return customerService.renewShopAdvertisingImageSort(id, sort);
+    }
+
+    /**
+     * 修改上下架状态
+     * @param id
+     * @param status
+     * @return
+     */
+    @GetMapping("/renewShopAdvertisingImageStatus")
+    public ResponseJson renewShopAdvertisingImageStatus(Integer id, Integer status) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        if (null == status) {
+            return ResponseJson.error(-1, "状态不能为空", null);
+        }
+        return customerService.renewShopAdvertisingImageStatus(id, status);
+    }
+
+    /**
+     * 删除广告
+     * @param id
+     * @return
+     */
+    @GetMapping("/delShopAdvertisingImage/{id}")
+    public ResponseJson delShopAdvertisingImage(@PathVariable("id") Integer id) {
+        if (null == id) {
+            return ResponseJson.error(-1, "id不能为空", null);
+        }
+        return customerService.delShopAdvertisingImage(id);
+    }
+
+    /**
+     * 供应商主页统计
+     * @param shopId
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    @GetMapping("/getPageShop")
+    ResponseJson<PaginationVo<CmPageShop>> getPageShop(Integer shopId, 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.getPageShop(shopId, startTime, endTime, pageNum, pageSize);
+    }
+
+    /**
+     * 供应商商品统计
+     * @param shopId
+     * @return
+     */
+    @GetMapping("/getPageShopProduct")
+    public ResponseJson<PaginationVo<CmPageShopProduct>> getPageShopProduct(Integer shopId, 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.getPageShopProduct(shopId, startTime, endTime, pageNum, pageSize);
+    }
+
+    /**
+     * 供应商文章统计
+     * @param shopId
+     * @return
+     */
+    @GetMapping("/getPageShopInfo")
+    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, 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);
+    }
+
+    /**
+     * 供应商搜索词统计
+     * @param shopId
+     * @return
+     */
+    @GetMapping("/getPageShopKeyword")
+    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, 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);
+    }
+}

+ 75 - 0
src/main/java/com/caimei365/manager/dao/KeyWordDao.java

@@ -1,7 +1,10 @@
 package com.caimei365.manager.dao;
 
+import com.caimei365.manager.entity.caimei.CmPriorKeyword;
 import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 import java.util.Map;
@@ -30,4 +33,76 @@ public interface KeyWordDao {
     void updateDelFlag(String id);
 
     void updateCmUserSearchFrequency(KeyWord keyWord);
+
+    /**
+     * 协销列表
+     * @return
+     */
+    List<ServiceProviderModel> getServiceList();
+
+    /**
+     * 静态标签列表
+     * @param keyword
+     * @param fromSearch
+     * @param beginTime
+     * @param endTime
+     * @param serviceProviderId
+     * @return
+     */
+    List<KeyWord> getStateKeyWordList(String keyword, Integer fromSearch, String beginTime, String endTime, Integer serviceProviderId);
+
+    /**
+     * 插入静态标签
+     * @param keyword
+     */
+    void insertLabelByState(String keyword);
+
+    /**
+     * 优先展示标签
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus
+     * @return
+     */
+    List<CmPriorKeyword> getPriorKeywordList(String keyword, Integer fromSearch, Integer dynamicStatus);
+
+    /**
+     * 选择标签
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus 0 为动态标签 1 静态标签
+     * @return
+     */
+    List<KeyWord> getPickKeyword(String keyword, Integer fromSearch, Integer dynamicStatus);
+
+    /**
+     * 优先展示标签数量
+     * @return
+     */
+    Integer getPriorCount();
+
+    /**
+     * 标签是否已经是优先展示标签
+     * @param searchId
+     * @return
+     */
+    Integer getPrior(@Param("searchId") Integer searchId);
+
+    /**
+     * 插入优先展示标签
+     * @param searchId
+     */
+    void insertPriorKeyword(@Param("searchId") Integer searchId);
+
+    /**
+     * 删除状态更改
+     * @param id
+     */
+    void delPriorKeyword(@Param("id") Integer id);
+
+    /**
+     * 根据标签Id删除优先展示标签
+     * @param id
+     */
+    void delPriorKeywordById(@Param("id") Integer id);
 }

+ 185 - 0
src/main/java/com/caimei365/manager/dao/user/CmClubRemarksDao.java

@@ -0,0 +1,185 @@
+package com.caimei365.manager.dao.user;
+
+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;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Mapper
+public interface CmClubRemarksDao {
+    /**
+     * 协销数据
+     * @return
+     */
+    List<ServiceProviderModel> getServiceList();
+
+    /**
+     * 协销已注册用户数
+     * @param serviceProviderId
+     * @return
+     */
+    Integer getRegisteredNumber(@Param("serviceProviderId") Integer serviceProviderId,@Param("addTime") String addTime);
+
+    /**
+     * 协销未注册用户数
+     * @param serviceProviderId
+     * @return
+     */
+    Integer getUnregisteredNumber(@Param("serviceProviderId") Integer serviceProviderId, @Param("addTime") String addTime);
+
+    /**
+     * 咨询记录类别
+     * @return
+     */
+    List<CmConsulttype> getClassName();
+    /**
+     * 已注册用户咨询记录
+     * @param cmClubRemarks
+     * @return
+     */
+    List<CmClubRemarks> findRegistList(CmClubRemarks cmClubRemarks);
+
+    /**
+     * 根据商品Id 查询商品信息
+     * @param productId
+     * @return
+     */
+    List<Product> getProduct(@Param("productId") Integer productId);
+
+    /**
+     * 根据id查询报备记录
+     * @param reportId
+     * @return
+     */
+    List<CmReport> getReportById(@Param("reportId") Integer reportId);
+
+    /**
+     * 咨询类别
+     * @param id
+     * @return
+     */
+    String findClassName(String id);
+
+    /**
+     * 图片信息
+     * @param remarksId
+     * @return
+     */
+    List<String> getRemarksImageList(Integer remarksId);
+
+    /**
+     * 文件信息
+     * @param remarksId
+     * @return
+     */
+    List<RemarksFileVo> getRemarksFileList(Integer remarksId);
+
+    /**
+     * 报备列表
+     * @param cmReport
+     * @return
+     */
+    List<CmReport> getReportList(CmReport cmReport);
+
+    /**
+     * 已注册用户咨询记录数
+     * @param reportId
+     * @return
+     */
+    Integer clubRemarksConut(Integer reportId);
+
+    /**
+     * 未注册用户咨询记录数
+     * @param reportId
+     * @return
+     */
+    Integer visitorRemarksConut(Integer reportId);
+
+    /**
+     * 已注册咨询记录取消关联
+     * @param remarksId
+     */
+    void updateClubRemarks(Integer remarksId);
+
+    /**
+     * 未注册咨询记录取消关联
+     * @param remarksId
+     */
+    void updateVisitorRemarks(Integer remarksId);
+
+    /**
+     * 删除报备记录
+     * @param reportId
+     */
+    void deleteClubRemarks(Integer reportId);
+
+    /**
+     * 审核报备记录
+     * @param reportId
+     * @param auditName
+     * @param auditText
+     * @param status
+     */
+    void updateAuditRemarks(@Param("reportId") Integer reportId, @Param("auditName") String auditName, @Param("auditText") String auditText, @Param("status") Integer status);
+
+    /**
+     * 咨询记录类别
+     * @param cmConsulttype
+     * @return
+     */
+    List<CmConsulttype> getConsultList(CmConsulttype cmConsulttype);
+
+    /**
+     * 添加咨询记录类别
+     * @param cmConsulttype
+     */
+    void insertConsult(CmConsulttype cmConsulttype);
+
+    /**
+     * 修改咨询记录类别
+     * @param cmConsulttype
+     */
+    void updateConsult(CmConsulttype cmConsulttype);
+
+    /**
+     * 删除咨询记录类别
+     * @param id
+     */
+    void deleteConsult(@Param("id") Integer id);
+
+    /**
+     * 未注册咨询记录列表
+     * @param visitRemarkVo
+     * @return
+     */
+    List<VisitRemarkVo> getVisitRemarkList(VisitRemarkVo visitRemarkVo);
+
+    /**
+     * 未注册用户已同步数据详情
+     * @param visitRemarkVo
+     * @return
+     */
+    List<CmClubRemarks> getClubRemarksList(VisitRemarkVo visitRemarkVo);
+
+    /**
+     * 未注册用户图片信息
+     * @param remarksId
+     * @return
+     */
+    List<String> getVisitorImageList(Integer remarksId);
+
+    /**
+     * 未注册用户文件信息
+     * @param remarksId
+     * @return
+     */
+    List<RemarksFileVo> getVisitorFileList(Integer remarksId);
+}

+ 237 - 0
src/main/java/com/caimei365/manager/dao/user/CustomerServiceDao.java

@@ -0,0 +1,237 @@
+package com.caimei365.manager.dao.user;
+
+import com.caimei365.manager.entity.caimei.CmShop;
+import com.caimei365.manager.entity.caimei.cmUser.*;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+@Mapper
+public interface CustomerServiceDao {
+    /**
+     * 潜客供应商列表
+     * @param cmShopStatistics
+     * @return
+     */
+    List<CmShopStatistics> getCustomerShopList(CmShopStatistics cmShopStatistics);
+
+    /**
+     * 潜客供应商Id集合
+     * @return
+     */
+    List<Integer> getCustomerShopId();
+
+    /**
+     * 供应商列表
+     * @param shopName
+     * @return
+     */
+    List<CmShop> getShopList(@Param("shopName") String shopName, @Param("shopId") Integer shopId);
+
+    /**
+     * 添加供应商
+     * @param cmShopStatistics
+     */
+    void insertCustomerShop(CmShopStatistics cmShopStatistics);
+
+    /**
+     * 修改统计状态
+     * @param id
+     * @param status
+     */
+    void updateCustomerShop( @Param("id") Integer id, @Param("status") Integer status);
+
+    /**
+     * 游客统计列表
+     * @param cmRoosInformation
+     * @return
+     */
+    List<CmRoosInformation> getCmInformationList(CmRoosInformation cmRoosInformation);
+
+    /**
+     * 修改跟进状态
+     * @param id
+     * @param followUpStatus
+     */
+    void updateInformation(@Param("id") Integer id, @Param("followUpStatus") Integer followUpStatus);
+
+    /**
+     * 相关文章列表
+     * @param cmShopInfo
+     * @return
+     */
+    List<CmShopInfo> getShopInfoList(CmShopInfo cmShopInfo);
+
+    /**
+     * 已被选择文章集合
+     * @return
+     */
+    List<Integer> getShopInfoId();
+
+    /**
+     * 选择文章
+     * @param id
+     * @param title
+     * @return
+     */
+    List<Info> getInfoList(@Param("id")Integer id, @Param("title") String title);
+
+    /**
+     * 插入供应商相关文章统计
+     * @param cmShopInfo
+     */
+    void insertShopInfo(CmShopInfo cmShopInfo);
+
+    /**
+     * 修改统计状态
+     * @param id
+     * @param status
+     */
+    void updateShopInfoStatus(@Param("id") Integer id, @Param("status") Integer status);
+
+    /**
+     * 删除统计文章
+     * @param id
+     */
+    void delShopInfo(@Param("id") Integer id);
+
+    /**
+     * 相关搜索词统计列表
+     * @param cmShopKeyword
+     * @return
+     */
+    List<CmShopKeyword> getShopKeyword(CmShopKeyword cmShopKeyword);
+
+    /**
+     * 相关搜索词统计Id
+     * @return
+     */
+    List<Integer> getShopKeywordId();
+
+    /**
+     * 选择搜索词
+     * @param keyword
+     * @return
+     */
+    List<CmUserSearchFrequency> getSearchFrequencyList(@Param("keyword") String keyword);
+
+    /**
+     * 插入相关搜索词统计
+     * @param cmShopKeyword
+     */
+    void insertShopKeyword(CmShopKeyword cmShopKeyword);
+
+    /**
+     * 修改统计状态
+     * @param id
+     * @param status
+     */
+    void updateShopKeywordStatus(@Param("id") Integer id, @Param("status") Integer status);
+
+    /**
+     * 删除相关搜索词
+     * @param id
+     */
+    void delShopKeyword(@Param("id") Integer id);
+
+    /**
+     * 弹框数据回显
+     * @param shopId
+     * @return
+     */
+    CmShopPopUp getShopPopUp(@Param("shopId") Integer shopId);
+
+    /**
+     * 插入弹框数据
+     * @param cmShopPopUp
+     */
+    void insertShopPopUp(CmShopPopUp cmShopPopUp);
+
+    /**
+     * 修改弹框数据
+     * @param cmShopPopUp
+     */
+    void updateShopPopUp(CmShopPopUp cmShopPopUp);
+
+    /**
+     * 供应商广告列表
+     * @param cmShopAdvertisingImage
+     * @return
+     */
+    List<CmShopAdvertisingImage> getShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage);
+
+    /**
+     * 广告信息回显
+     * @return
+     */
+    CmShopAdvertisingImage getShopAdvertisingImageById(@Param("id") Integer id);
+
+    /**
+     * 插入广告信息
+     * @param cmShopAdvertisingImage
+     */
+    void insertShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage);
+
+    /**
+     * 编辑广告信息
+     * @param cmShopAdvertisingImage
+     */
+    void updateShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage);
+
+    /**
+     * 排序
+     * @param id
+     * @param sort
+     */
+    void updateShopAdvertisingImageSort(@Param("id") Integer id, @Param("sort") Integer sort);
+
+    /**
+     * 修改上下架状态
+     * @param id
+     * @param status
+     */
+    void updateShopAdvertisingImageStatus(@Param("id") Integer id, @Param("status") Integer status);
+
+    /**
+     * 删除广告
+     * @param id
+     */
+    void delShopAdvertisingImage(@Param("id") Integer id);
+
+    /**
+     * 供应商主页统计
+     * @param shopId
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    List<CmPageShop> getPageShop(@Param("shopId") Integer shopId, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+    /**
+     * 供应商商品统计
+     * @param shopId
+     * @return
+     */
+    List<CmPageShopProduct> getPageShopProduct(@Param("shopId") Integer shopId, @Param("startTime") String startTime, @Param("endTime") String endTime);
+
+    /**
+     * 供应商文章
+     * @param shopId
+     * @return
+     */
+    List<CmPageShopInfo> getPageShopInfo(@Param("shopId") Integer shopId, @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);
+}

+ 52 - 0
src/main/java/com/caimei365/manager/entity/caimei/CmPriorKeyword.java

@@ -0,0 +1,52 @@
+package com.caimei365.manager.entity.caimei;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/12
+ */
+@Data
+public class CmPriorKeyword {
+    /**
+     * id
+     */
+    private Integer id;
+    /**
+     * 标签Id
+     */
+    private Integer searchId;
+    /**
+     * 添加时间
+     */
+    private Date addTime;
+    /**
+     * 删除标记 0:为删除,1:已删除
+     */
+    private Integer delFlag;
+    /**
+     * 关键词
+     */
+    private String keyword;
+    /**
+     * 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入,4:协销填写)
+     */
+    private Integer fromSearch;
+    /**
+     * 协销Id 当 fromSearch 为 4的时候有值
+     */
+    private Integer serviceProviderId;
+    /**
+     * 协销名称
+     */
+    private String name;
+    /**
+     * 0:动态标签;1:静态标签
+     */
+    private Integer dynamicStatus;
+
+}

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

@@ -121,4 +121,8 @@ public class CmShop implements Serializable {
      * 如选择为医疗>>三类器械  则必须要上传资质
      */
     private String medicalPracticeLicenseImg1;
+    /**
+     * 是否支持选择
+     */
+    private Boolean flag;
 }

+ 17 - 1
src/main/java/com/caimei365/manager/entity/caimei/KeyWord.java

@@ -23,10 +23,22 @@ public class KeyWord implements Serializable {
     @ExcelProperty(value = "关键词", index = 0)
     private String keyword;
     /**
-     * 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入)
+     * 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入,4:协销填写
      */
     @ExcelIgnore
     private Integer fromSearch;
+    /**
+     * 协销Id 当 fromSearch 为 4的时候有值
+     */
+    private Integer serviceProviderId;
+    /**
+     * 协销名称
+     */
+    private String name;
+    /**
+     * 0:动态标签;1:静态标签
+     */
+    private Integer dynamicStatus;
     /**
      * 0:未加入关键词库;1:已加入关键词库
      */
@@ -60,4 +72,8 @@ public class KeyWord implements Serializable {
     @ExcelIgnore
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date searchTime;
+    /**
+     * shi发支持选择
+     */
+    private Boolean flag;
 }

+ 225 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmClubRemarks.java

@@ -0,0 +1,225 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import com.caimei365.manager.entity.caimei.product.Product;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Data
+public class CmClubRemarks {
+    /**
+     * 机构id
+     */
+    private Integer clubId;
+
+    /**
+     * 备注id
+     */
+    private Integer remarksId;
+
+    /**
+     * 协销姓名
+     */
+    private String spName;
+    /**
+     * 机构名称
+     */
+    private String clubName;
+    /**
+     * 总咨询类别
+     */
+    private List<CmConsulttype> consults;
+    /**
+     * 记录的咨询类别
+     */
+    private String consultType;
+
+    /**
+     * 手机号
+     */
+    private String contractMobile;
+    /**
+     * 咨询类别
+     */
+    private String consult;
+
+    /**
+     * 协销id
+     */
+    private Integer serviceProviderId;
+
+    /**
+     * 总小组
+     */
+    private List<CmSaleMan> teams;
+    /**
+     * 组长id/管理员id
+     */
+    private Integer leaderId;
+    /**
+     * 管理员姓名
+     */
+    private String leaderName;
+    /**
+     * 文字备注/关键词
+     */
+    private String remarks;
+    /**
+     * 1 已注册记录  2  未注册记录
+     */
+    private Integer type;
+    /**
+     * 添加时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date addTime;
+
+    private String todayTime;
+
+    private String startAddTime;
+
+
+    private String endAddTime;
+    /**
+     * 咨询人
+     */
+    private String questionMan;
+    /**
+     * 图片列表
+     */
+    private List<String> imageList;
+
+    /**
+     * 文件列表
+     */
+    private List<RemarksFileVo> fileList;
+    /**
+     * 时分 时间
+     */
+    private String divisionTime;
+
+    /**
+     * 机构类型
+     */
+    private String clubType;
+    /**
+     * 价格敏感度
+     */
+    private Integer pinceSensitve;
+    /**
+     * 意向程度
+     */
+    private Integer satisfied;
+    /**
+     * 跟进状态
+     */
+    private Integer followup;
+    /**
+     * 额外说明
+     */
+    private String extra;
+    /**
+     * 非持久化字段旧协销名
+     */
+    private String oldName;
+    /**
+     * 新分配机构状态 0.全部 1.是 2否,
+     */
+    private Integer newDeal;
+    /**
+     * 咨询商品Id
+     */
+    private Integer productId;
+    /**
+     * 咨询商品名称
+     */
+    private String productName;
+    /**
+     * 咨询商品主图
+     */
+    private String mainImage;
+    /**
+     * 商品信息
+     */
+    private List<Product> product;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * 关联报备商品主图
+     */
+    private String productMainImage;
+    /**
+     * //关联报备商品名称
+     */
+    private String proName;
+    /**
+     * 关联事由
+     */
+    private String reportText;
+
+    private String auditName;
+    /**
+     * 状态 1.已审核 2.待审核 3.审核未通过
+     */
+    private Integer reportStatus;
+    /**
+     * 审核时间
+     */
+    private String auditTime;
+    /**
+     * 报备记录id
+     */
+    private Integer reportId;
+
+    private List<CmReport> reports;
+
+    private Integer number;
+
+    private Integer numbers;
+    /**
+     * 是否注册 0 全部 1 未注册 2已注册
+     */
+    private Integer isRegister;
+    /**
+     * 沟通情况 0 已沟通 1联系不上
+     */
+    private Integer communicationSituation;
+    /**
+     * 沟通方式 0:电话,微信 1:电话 2:微信
+     */
+    private String communicationMethods;
+    /**
+     * 客户来源 0 公众号 1 小红书 2 微博 3 搜狐 4 其他
+     */
+    private Integer customerSource;
+    /**
+     * 客户性别 0 男 1 女
+     */
+    private Integer customerGender;
+    /**
+     * 客户年龄
+     */
+    private String customerAge;
+    /**
+     * 加群情况 0 以加群 1 未加群
+     */
+    private Integer groupAddition;
+    /**
+     * 动态标签
+     */
+    private String trendsKeyword;
+    /**
+     * 静态标签
+     */
+    private String stateKeyword;
+}

+ 37 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmConsulttype.java

@@ -0,0 +1,37 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Data
+public class CmConsulttype {
+
+    private Integer id;
+    /**
+     * 咨询类别名称
+     */
+    private String className;
+    /**
+     * 状态 1启用,2停用,默认1
+     */
+    private Integer status;
+    /**
+     * 咨询类别排序 正整数值大小排序
+     */
+    private Integer sortNumber;
+    /**
+     * 创建时间
+     */
+    private Date createdTime;
+    /**
+     * 删除标记 0未删除,1删除,默认0
+     */
+    private String delFlag;
+}

+ 48 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShop.java

@@ -0,0 +1,48 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmPageShop {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * 跳转链接
+     */
+    private String shopLink;
+    /**
+     * 访问次数
+     */
+    private Integer accessNumber;
+    /**
+     * 访问时长
+     */
+    private String accessDuration;
+    /**
+     * 平均访问时长
+     */
+    private Double averageDuration;
+    /**
+     * 平均访问时长 格式化
+     */
+    private String average;
+    /**
+     * 时间
+     */
+    private String accessDate;
+}

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

@@ -0,0 +1,58 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmPageShopInfo {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 文章Id
+     */
+    private Integer infoId;
+    /**
+     * 引导图
+     */
+    private String guidanceImage;
+    /**
+     * 文章标题
+     */
+    private String title;
+    /**
+     * 文章上线状态:1待上线,2已上线,3已下线
+     */
+    private Integer onlineStatus;
+    /**
+     * 链接
+     */
+    private String link;
+    /**
+     * 访问次数
+     */
+    private Integer accessNumber;
+    /**
+     * 访问时长
+     */
+    private String accessDuration;
+    /**
+     * 平均时长
+     */
+    private Double averageDuration;
+    /**
+     * 平均访问时长 格式化
+     */
+    private String average;
+    /**
+     * 时间
+     */
+    private String accessDate;
+}

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

@@ -0,0 +1,46 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmPageShopKeyword {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 搜索词
+     */
+    private String keyword;
+    /**
+     * 链接
+     */
+    private String link;
+    /**
+     * 访问次数
+     */
+    private Integer accessNumber;
+    /**
+     * 访问时长
+     */
+    private String accessDuration;
+    /**
+     * 平均访问时长
+     */
+    private Double averageDuration;
+    /**
+     * 平均访问时长 格式化
+     */
+    private String average;
+    /**
+     * 时间
+     */
+    private String accessDate;
+}

+ 58 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmPageShopProduct.java

@@ -0,0 +1,58 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmPageShopProduct {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+    /**
+     * 商品名称
+     */
+    private String productName;
+    /**
+     * 商品主图
+     */
+    private String mainImage;
+    /**
+     * 商品状态
+     */
+    private Integer validFlag;
+    /**
+     * 链接
+     */
+    private String link;
+    /**
+     * 访问次数
+     */
+    private Integer accessNumber;
+    /**
+     * 访问时长
+     */
+    private String accessDuration;
+    /**
+     * 平均访问时长
+     */
+    private Double averageDuration;
+    /**
+     * 平均访问时长 格式化
+     */
+    private String average;
+    /**
+     * 时间
+     */
+    private String accessDate;
+}

+ 77 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmReport.java

@@ -0,0 +1,77 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/11
+ */
+@Data
+public class CmReport {
+    private Integer reportId;
+    /**
+     * 咨询记录ID
+     */
+    private Integer remarksId;
+    /**
+     * 关联商品
+     */
+    private Integer productId;
+    /**
+     * 报备机构ID
+     */
+    private Integer clubId;
+    /**
+     * 未注册机构咨询ID
+     */
+    private Integer visitorId;
+    /**
+     * 报备人
+     */
+    private String reportName;
+    /**
+     * 报备事由
+     */
+    private String reportText;
+    /**
+     * 创建时间
+     */
+    private String addTime;
+    /**
+     * 状态 1.已审核 2.待审核 3.审核未通过
+     */
+    private Integer status;
+    /**
+     * 审核人
+     */
+    private String auditName;
+    /**
+     * 审核时间
+     */
+    private String auditTime;
+    /**
+     * 咨询商品名称
+     */
+    private String productName;
+    /**
+     * 咨询商品主图
+     */
+    private String mainImage;
+    /**
+     * 机构名称
+     */
+    private String clubName;
+
+    private String startAddTime;
+
+
+    private String endAddTime;
+    /**
+     * 新分配机构状态 0.否,1.是
+     */
+    private Integer newDeal;
+
+    private String auditText;
+}

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

@@ -0,0 +1,42 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+@Data
+public class CmRoosInformation {
+    private Integer id;
+    /**
+     * IP
+     */
+    private String IP;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 跟进状态 0 已跟进 1 未跟进
+     */
+    private Integer followUpStatus;
+    /**
+     * 咨询姓名
+     */
+    private String consultName;
+    /**
+     * 咨询手机号码
+     */
+    private String consultMobile;
+    /**
+     * 是否点击关闭弹框
+     */
+    private Integer isClick;
+    /**
+     * 创建时间
+     */
+    private String createTime;
+}

+ 38 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmSaleMan.java

@@ -0,0 +1,38 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Data
+public class CmSaleMan {
+    /**
+     * 协销组员
+     */
+    private List<ServiceProviderModel> groups;
+    /**
+     * 协销组长id
+     */
+    private Integer leaderId;
+    /**
+     * 协销组长姓名
+     */
+    private String leaderName;
+    /**
+     * 管理标记 1是,2不是
+     */
+    private String manager;
+    /**
+     * 小组创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+}

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

@@ -0,0 +1,57 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import com.caimei365.manager.entity.caimei.CmShop;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmShopAdvertisingImage {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * pc图片
+     */
+    private String pcImage;
+    /**
+     * 小程序图片
+     */
+    private String appImage;
+    /**
+     * 跳转链接
+     */
+    private String jumpLink;
+    /**
+     * 排序
+     */
+    private Integer sort;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 上下架状态 0 已上架 1 已下架
+     */
+    private Integer status;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+    /**
+     * 供应商信息
+     */
+    private List<CmShopStatistics> shops;
+}

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

@@ -0,0 +1,52 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmShopInfo {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 文章Id
+     */
+    private Integer infoId;
+    /**
+     * 引导图
+     */
+    private String guidanceImage;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 发布时间
+     */
+    private Date pubdate;
+    /**
+     * 发布时间格式化
+     */
+    private String pubdateString;
+    /**
+     * 统计状态 0 统计 1 不统计
+     */
+    private Integer status;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+}

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

@@ -0,0 +1,48 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmShopKeyword {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 搜索词Id
+     */
+    private Integer searchId;
+    /**
+     * 统计状态 0 统计 1 不统计
+     */
+    private Integer status;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+    /**
+     * 关键词
+     */
+    private String keyword;
+    /**
+     * 搜索次数
+     */
+    private String number;
+    /**
+     * 搜索时间
+     */
+    private String searchTime;
+}

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

@@ -0,0 +1,34 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmShopPopUp {
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 图片
+     */
+    private String image;
+    /**
+     * 引导语1
+     */
+    private String guidingOne;
+    /**
+     * 引导语2
+     */
+    private String guidingTwo;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+}

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

@@ -0,0 +1,49 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+@Data
+public class CmShopStatistics {
+    /**
+     * Id
+     */
+    private Integer id;
+    /**
+     * 供应商Id
+     */
+    private Integer shopId;
+    /**
+     * 供应商名称
+     */
+    private String shopName;
+    /**
+     * 联系人
+     */
+    private String linkMan;
+    /**
+     * 手机号
+     */
+    private String mobile;
+    /**
+     * 供应商状态 3待审核, 90已上线,91已下线,92审核不通过
+     */
+    private Integer shopStatus;
+    /**
+     * 统计状态 0 统计 1 不统计
+     */
+    private Integer status;
+    /**
+     * 添加时间
+     */
+    private String addTime;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+}

+ 68 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/CmUserSearchFrequency.java

@@ -0,0 +1,68 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class CmUserSearchFrequency {
+    private Integer id;
+    /**
+     * 标签库数据来源(1:手动添加;2:用户关键词统计;3:导入)
+     */
+    private Integer fromSearch;
+    /**
+     * 关键词
+     */
+    private String keyword;
+    /**
+     * 关键词出现次数
+     */
+    private Integer frequency;
+    /**
+     * 0:未加入关键词库;1:已加入关键词库
+     */
+    private Integer trueStatus;
+    /**
+     * 0:已删除;1未删除
+     */
+    private Integer delStatus;
+    /**
+     * 联动关键词出现次数
+     */
+    private Integer linkageFrequency;
+    /**
+     * 搜索时间
+     */
+    private String searchTime;
+    /**
+     * 推荐状态:0未推荐,1已推荐
+     */
+    private Integer recommendStatus;
+    /**
+     * 推荐时间
+     */
+    private Date recommendTime;
+    /**
+     * 推荐列表删除标记0未忽略1忽略
+     */
+    private Integer recommendFlag;
+    /**
+     * 添加到标签库的时间
+     */
+    private Date addTime;
+    /**
+     * 联动搜索状态:0未启用,1已启用
+     */
+    private Integer linkageStatus;
+    /**
+     * 是否支持选择
+     */
+    private Boolean flag;
+}

+ 148 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/Info.java

@@ -0,0 +1,148 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/6
+ */
+@Data
+public class Info {
+    private Integer id;
+    /**
+     * 信息分类
+     */
+    private Integer typeId;
+    /**
+     * 标题
+     */
+    private String title;
+    /**
+     * 信息标签
+     */
+    private String label;
+    /**
+     * 发布人
+     */
+    private String publisher;
+    /**
+     * 来源
+     */
+    private String source;
+    /**
+     * 文章发布来源:1采美365网,2供应商
+     */
+    private Integer publishSource;
+    /**
+     * 供应商id,publishSource为2时才有值
+     */
+    private Integer shopId;
+    /**
+     * 关键字
+     */
+    private String keyword;
+    /**
+     * 推荐语
+     */
+    private String recommendContent;
+    /**
+     * 信息内容
+     */
+    private String infoContent;
+    /**
+     * 引导图
+     */
+    private String guidanceImage;
+    /**
+     * 商城首页图
+     */
+    private String homePageImage;
+    /**
+     * 发布时间
+     */
+    private Date pubdate;
+    /**
+     * 发布时间 格式化
+     */
+    private String pubdateString;
+    /**
+     * 推荐状态 0停用 1启用
+     */
+    private String recommendStatus;
+    /**
+     * 推荐方式 0自动推荐 1手动推荐
+     */
+    private Integer autoStatus;
+    /**
+     * 启用/禁用状态
+     */
+    private String enabledStatus;
+    /**
+     * 基础点赞
+     */
+    private Integer basePraise;
+    /**
+     * 基础浏览量
+     */
+    private Integer basePv;
+    /**
+     * 优先级
+     */
+    private String priorityIndex;
+    /**
+     * 供应商文章审核状态:1待审核,2审核通过,3审核失败
+     */
+    private Integer auditStatus;
+    /**
+     * 文章上线状态:1待上线,2已上线,3已下线
+     */
+    private Integer onlineStatus;
+    /**
+     * 审核失败理由
+     */
+    private String failReason;
+    /**
+     * 创建人
+     */
+    private String createBy;
+    /**
+     * 创建时间
+     */
+    private Date createDate;
+    /**
+     * 创建时间格式化
+     */
+    private String createDateString;
+    /**
+     * 最后更新人
+     */
+    private String updateBy;
+    /**
+     * 最后更新时间
+     */
+    private Date updateDate;
+    /**
+     * 首页置顶位
+     */
+    private Integer topPosition;
+    /**
+     * 关联标签库ids
+     */
+    private String labelIds;
+    /**
+     * 关联标签库字符串
+     */
+    private String relatedLabels;
+    /**
+     * 删除标记:0未删除,1已删除
+     */
+    private Integer delFlag;
+    /**
+     * 是否支持选择
+     */
+    private Boolean flag;
+}

+ 27 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/RemarksFileVo.java

@@ -0,0 +1,27 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Data
+public class RemarksFileVo {
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * oss名称
+     */
+    private String ossName;
+
+    /**
+     * 文件链接
+     */
+    private String fileUrl;
+}

+ 49 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/ServiceProviderModel.java

@@ -0,0 +1,49 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import lombok.Data;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Data
+public class ServiceProviderModel {
+    /**
+     * 协销Id
+     */
+    private Integer serviceProviderId;
+    /**
+     * 协销名称
+     */
+    private String name;
+    /**
+     * 协销联系人名称
+     */
+    private String linkMan;
+    /**
+     * 协销用户Id
+     */
+    private Integer userId;
+    /**
+     * 协销组长Id
+     */
+    private Integer mainServiceProviderId;
+    /**
+     * 协销组长名称
+     */
+    private String mainName;
+    /**
+     * 已注册客户数
+     */
+    private Integer registeredNumber;
+    /**
+     * 未注册客户数
+     */
+    private Integer unregisteredNumber;
+    /**
+     * 协销小组编辑页面回显标记,后台取数据的时候给1
+     */
+    private Integer teamFlag;
+}

+ 169 - 0
src/main/java/com/caimei365/manager/entity/caimei/cmUser/VisitRemarkVo.java

@@ -0,0 +1,169 @@
+package com.caimei365.manager.entity.caimei.cmUser;
+
+import com.caimei365.manager.entity.caimei.product.Product;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/11
+ */
+@Data
+public class VisitRemarkVo {
+
+    /**
+     * 潜在用户备注id
+     */
+    private Integer remarksId;
+    /**
+     * 咨询人id
+     */
+    private String questionManId;
+
+    /**
+     * 协销id
+     */
+    private Integer serviceProviderId;
+    /**
+     * 协销姓名
+     */
+    private String serviceName;
+    /**
+     * 同步机构名称
+     */
+    private String clubName;
+    /**
+     * 同步 clubid
+     */
+    private Integer clubId;
+    /**
+     * 总咨询类别
+     */
+    private List<CmConsulttype> consults;
+    /**
+     * 记录的咨询类别
+     */
+    private String consultType;
+    /**
+     * 咨询类别
+     */
+    private String consult;
+    /**
+     * 总小组
+     */
+    private List<CmSaleMan> teams;
+    /**
+     * 组长id/管理员id
+     */
+    private Integer leaderId;
+    /**
+     * 管理员姓名
+     */
+    private String leaderName;
+
+    private String startAddTime;
+
+    private String endAddTime;
+    /**
+     * 备注/关键词
+     */
+    private String remarks;
+    /**
+     * 添加时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date addTime;
+    /**
+     * 咨询人名字
+     */
+    private String questionMan;
+    /**
+     * 同步时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date concactTime;
+
+    /**
+     * 图片列表
+     */
+    private List<String> imageList;
+
+    /**
+     * 文件列表
+     */
+    private List<RemarksFileVo> fileList;
+
+    /**
+     * 是否同步 1已同步2未同步
+     */
+    private String concat;
+
+    /**
+     * cm_visitor_remarks协销列表
+     */
+    private List<ServiceProviderModel> serverList;
+
+    /**
+     * 机构类型
+     */
+    private String clubType;
+    /**
+     * 价格敏感度
+     */
+    private String pinceSensitve;
+    /**
+     * 意向程度
+     */
+    private String satisfied;
+    /**
+     * 跟进状态
+     */
+    private String followup;
+    /**
+     * 额外说明
+     */
+    private String extra;
+
+    /**
+     * 非持久化字段旧协销名
+     */
+    private String oldName;
+    /**
+     * 商品Id
+     */
+    private Integer productId;
+
+    /**
+     * 商品信息
+     */
+    private List<Product> product;
+    private String productName; //咨询商品名称
+
+    private String mainImage;//咨询商品主图
+
+    private String shopName;//供应商名称
+
+    private String productMainImage;//关联报备商品主图
+
+    private String proName;//关联报备商品名称
+
+    private String reportText;//关联事由
+
+    private String auditName;
+
+    private Integer reportStatus;//状态 1.已审核 2.待审核 3.审核未通过
+
+    private String auditTime;//审核时间
+
+    /**
+     * 报备记录id
+     */
+    private Integer reportId;
+
+    private List<CmReport> reports;
+}

+ 114 - 0
src/main/java/com/caimei365/manager/service/caimei/CmOssArchiveService.java

@@ -0,0 +1,114 @@
+package com.caimei365.manager.service.caimei;
+
+import com.caimei365.manager.utils.OSSUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/18
+ */
+@Service
+@Slf4j
+public class CmOssArchiveService {
+
+    @Resource private OSSUtils ossUtils;
+
+    public void download(HttpServletRequest request, HttpServletResponse response, String fileName) throws IOException {
+        File file = new File("./" + fileName);
+        //  文件存在才下载
+        if (file.exists()) {
+            OutputStream out = null;
+            FileInputStream in = null;
+            try {
+                // 1.读取要下载的内容
+                in = new FileInputStream(file);
+
+                // 2. 告诉浏览器下载的方式以及一些设置
+                // 解决文件名乱码问题,获取浏览器类型,转换对应文件名编码格式,IE要求文件名必须是utf-8, firefo要求是iso-8859-1编码
+                String agent = request.getHeader("user-agent");
+                if (agent.contains("FireFox")) {
+                    fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");
+                } else {
+                    fileName = URLEncoder.encode(fileName, "UTF-8");
+                }
+                // 设置下载文件的mineType,告诉浏览器下载文件类型
+                String mineType = request.getServletContext().getMimeType(fileName);
+                response.setContentType(mineType);
+                // 设置一个响应头,无论是否被浏览器解析,都下载
+                response.setHeader("Content-disposition", "attachment; filename=" + fileName);
+                // 将要下载的文件内容通过输出流写到浏览器
+                out = response.getOutputStream();
+                int len = 0;
+                byte[] buffer = new byte[1024];
+                while ((len = in.read(buffer)) > 0) {
+                    out.write(buffer, 0, len);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            } finally {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+                file.delete();
+            }
+        }
+    }
+
+    public Map<String, Object> fileUpload(MultipartFile multipartFile) {
+        Map<String, Object> map = new HashMap<>();
+        String fileAllName = multipartFile.getOriginalFilename();
+        String fileType = fileAllName.substring(fileAllName.lastIndexOf(".") + 1);
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = uuid + "." + fileType;
+        String contentType = ossUtils.getContentType(fileAllName);
+        try {
+            //保存本地
+            File file = ossUtils.ossUpload(multipartFile);
+            log.info("默认路径>>>" + file.getAbsolutePath());
+            //上传oss
+            String url = ossUtils.ossUpload(filePath, file, contentType);
+            //删除本地文件
+            ossUtils.deleteFile(file);
+            map.put("success", true);
+            map.put("msg", "操作成功");
+            map.put("url", url);
+            map.put("fileName", fileAllName);
+            map.put("ossName", filePath);
+        } catch (Exception e) {
+            e.printStackTrace();
+            map.put("success", false);
+            map.put("msg", "操作失败");
+            log.info("上传异常!!!");
+        }
+        return map;
+    }
+
+    public void fileDownload(String ossName, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
+        ossUtils.downFile(ossName, fileName);
+        download(request, response, fileName);
+    }
+
+    public void deleteOssFile(String ossName) {
+        //删除oss服务器上的文件
+        ossUtils.deleteSingleFile(ossName);
+    }
+}

+ 62 - 0
src/main/java/com/caimei365/manager/service/caimei/KeyWordService.java

@@ -2,7 +2,9 @@ package com.caimei365.manager.service.caimei;
 
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmPriorKeyword;
 import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel;
 
 import java.util.List;
 
@@ -24,4 +26,64 @@ public interface KeyWordService {
 
     ResponseJson deleteLabel(String id);
 
+    /**
+     * 协销列表
+     * @return
+     */
+    ResponseJson<List<ServiceProviderModel>> getServiceList();
+
+    /**
+     * 静态标签列表
+     * @param keyword
+     * @param fromSearch
+     * @param beginTime
+     * @param endTime
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<KeyWord>> getStateKeyWordList(String keyword, Integer fromSearch, String beginTime, String endTime, Integer serviceProviderId, int pageNum, int pageSize);
+
+    /**
+     * 插入静态标签
+     * @param keyword
+     * @return
+     */
+    ResponseJson insertLabelByState(String keyword);
+
+    /**
+     * 优先展示标签列表
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmPriorKeyword>> getPriorKeywordList(String keyword, Integer fromSearch, Integer dynamicStatus, int pageNum, int pageSize);
+
+    /**
+     * 选择标签
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus 0 为动态标签 1 静态标签
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<KeyWord>> getPickKeyword(String keyword, Integer fromSearch, Integer dynamicStatus, int pageNum, int pageSize);
+    /**
+     * 保存优先展示标签
+     * @param searchIds
+     * @return
+     */
+    ResponseJson savePriorKeyword(String searchIds);
+
+    /**
+     * 删除优先展示标签
+     * @param ids
+     * @return
+     */
+    ResponseJson delPriorKeyword(String ids);
+
 }

+ 157 - 0
src/main/java/com/caimei365/manager/service/caimei/impl/KeyWordServiceImpl.java

@@ -5,7 +5,9 @@ import com.caimei.utils.StringUtils;
 import com.caimei365.manager.dao.KeyWordDao;
 import com.caimei365.manager.entity.PaginationVo;
 import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.CmPriorKeyword;
 import com.caimei365.manager.entity.caimei.KeyWord;
+import com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel;
 import com.caimei365.manager.entity.caimei.enums.KeyWordEnum;
 import com.caimei365.manager.service.caimei.KeyWordService;
 import com.github.pagehelper.PageHelper;
@@ -14,8 +16,11 @@ import org.springframework.stereotype.Service;
 
 
 import javax.annotation.Resource;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * @author zzj
@@ -150,10 +155,162 @@ public class KeyWordServiceImpl implements KeyWordService {
             String[] split = id.split(",");
             for (String s : split) {
                 keyWordDao.updateDelFlag(s);
+                keyWordDao.delPriorKeywordById(Integer.parseInt(s));
             }
         } else {
             keyWordDao.updateDelFlag(id);
         }
         return ResponseJson.success();
     }
+
+    /**
+     * 协销列表
+     *
+     * @return
+     */
+    @Override
+    public ResponseJson<List<ServiceProviderModel>> getServiceList() {
+        return ResponseJson.success(keyWordDao.getServiceList());
+    }
+
+    /**
+     * 静态标签列表
+     * @param keyword
+     * @param fromSearch
+     * @param beginTime
+     * @param endTime
+     * @param serviceProviderId
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<KeyWord>> getStateKeyWordList(String keyword, Integer fromSearch, String beginTime, String endTime, Integer serviceProviderId, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<KeyWord> keyWords = keyWordDao.getStateKeyWordList(keyword, fromSearch, beginTime, endTime, serviceProviderId);
+        PaginationVo<KeyWord> pageData = new PaginationVo<>(keyWords);
+        return ResponseJson.success(pageData);
+    }
+
+    /**
+     * 插入静态标签
+     *
+     * @param keyword
+     * @return
+     */
+    @Override
+    public ResponseJson insertLabelByState(String keyword) {
+        Integer keywordExist = keyWordDao.findKeywordExist(keyword);
+        if (null == keywordExist) {
+            keyWordDao.insertLabelByState(keyword);
+            return ResponseJson.success();
+        } else {
+            return ResponseJson.success("关键词已存在");
+        }
+    }
+
+    /**
+     * 优先展示标签列表
+     *
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmPriorKeyword>> getPriorKeywordList(String keyword, Integer fromSearch, Integer dynamicStatus, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmPriorKeyword> priorKeywordList = keyWordDao.getPriorKeywordList(keyword, fromSearch, dynamicStatus);
+
+        PaginationVo<CmPriorKeyword> page = new PaginationVo<>(priorKeywordList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 选择标签
+     *
+     * @param keyword
+     * @param fromSearch
+     * @param dynamicStatus 0 为动态标签 1 静态标签
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<KeyWord>> getPickKeyword(String keyword, Integer fromSearch, Integer dynamicStatus, int pageNum, int pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<KeyWord> priorKeywordList = keyWordDao.getPickKeyword(keyword, fromSearch, dynamicStatus);
+        List<CmPriorKeyword> keywordList = keyWordDao.getPriorKeywordList("",null,null);
+        List<Integer> searchIds = new ArrayList<>();
+        if (null != keywordList && keywordList.size()>0) {
+            searchIds = keywordList.stream().map(CmPriorKeyword::getSearchId).collect(Collectors.toList());
+        }
+        for (KeyWord key : priorKeywordList) {
+            if (searchIds.contains(key.getId())) {
+                key.setFlag(false);
+            } else {
+                key.setFlag(true);
+            }
+        }
+        PaginationVo<KeyWord> page = new PaginationVo<>(priorKeywordList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 保存优先展示标签
+     *
+     * @param searchIds
+     * @return
+     */
+    @Override
+    public ResponseJson savePriorKeyword(String searchIds) {
+        List<Integer> searchIdList = new ArrayList<>();
+        if (searchIds.contains(",")) {
+            String[] split = searchIds.split(",");
+            for (String s : split) {
+                searchIdList.add(Integer.parseInt(s));
+            }
+        } else {
+            searchIdList.add(Integer.parseInt(searchIds));
+        }
+        Integer count = keyWordDao.getPriorCount();
+        if (count > 50) {
+            return ResponseJson.error(-1, "只支持展示50个标签,请删减再添加。", null);
+        }
+        if ((count + searchIdList.size()) > 50) {
+            int num = (count + searchIdList.size()) - 50;
+            return ResponseJson.error(-1, "只支持展示50个标签,已超出"+ num +"(个),请删减再添加。", null);
+        }
+        // 保存优先展示标签
+        for (Integer id : searchIdList) {
+            Integer prior = keyWordDao.getPrior(id);
+            if (null == prior) {
+                keyWordDao.insertPriorKeyword(id);
+            } else {
+                return ResponseJson.success("关键词已存在");
+            }
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除优先展示标签
+     *
+     * @param ids
+     * @return
+     */
+    @Override
+    public ResponseJson delPriorKeyword(String ids) {
+        if (ids.contains(",")) {
+            String[] split = ids.split(",");
+            for (String id : split) {
+                keyWordDao.delPriorKeyword(Integer.parseInt(id));
+            }
+        } else {
+            keyWordDao.delPriorKeyword(Integer.parseInt(ids));
+        }
+        return ResponseJson.success();
+    }
 }

+ 141 - 0
src/main/java/com/caimei365/manager/service/caimei/user/CmClubRemarksService.java

@@ -0,0 +1,141 @@
+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.cmUser.CmClubRemarks;
+import com.caimei365.manager.entity.caimei.cmUser.CmConsulttype;
+import com.caimei365.manager.entity.caimei.cmUser.CmReport;
+import com.caimei365.manager.entity.caimei.cmUser.VisitRemarkVo;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+public interface CmClubRemarksService {
+    /**
+     * 咨询记录类别
+     * @return
+     */
+    ResponseJson<List<CmConsulttype>> getClassName();
+    /**
+     * 获取当天协销咨询记录信息
+     * @param time
+     * @return
+     */
+    ResponseJson<Map<String, Object>> getServiceList(String time);
+    /**
+     * 已注册用户咨询记录
+     * @param cmClubRemarks
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmClubRemarks>> findRegistList(CmClubRemarks cmClubRemarks, Integer pageNum, Integer pageSize);
+
+    /**
+     * 文件下载
+     * @param fileName
+     * @param ossName
+     * @param request
+     * @param response
+     * @return
+     */
+    void downloadRemarks(String fileName, String ossName, HttpServletRequest request, HttpServletResponse response)  throws IOException;
+    /**
+     * 报备列表
+     * @param cmReport
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmReport>> getReportList(CmReport cmReport, Integer pageNum, Integer pageSize);
+
+    /**
+     * 报备列表查看详情
+     * @param cmClubRemarks
+     * @return
+     */
+    ResponseJson<List<CmClubRemarks>> cmRegistReportList(CmClubRemarks cmClubRemarks);
+
+    /**
+     * 取消关联
+     * @param remarksId
+     * @param type
+     * @return
+     */
+    ResponseJson audit(Integer remarksId, Integer type);
+    /**
+     * 删除报备列表
+     * @param reportId
+     * @return
+     */
+    ResponseJson deleteReport(Integer reportId);
+
+    /**
+     * 审核
+     * @param reportId
+     * @param auditName
+     * @param auditText
+     * @param status
+     * @return
+     */
+    ResponseJson reportCount(Integer reportId, String auditName, String auditText, Integer status);
+
+    /**
+     * 咨询记录类别
+     * @param cmConsulttype
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmConsulttype>> getConsultList(CmConsulttype cmConsulttype, Integer pageNum, Integer pageSize);
+
+    /**
+     * 保存咨询记录类别
+     * @param cmConsulttype
+     * @return
+     */
+    ResponseJson saveConsult(CmConsulttype cmConsulttype);
+
+
+    /**
+     * 删除咨询记录类别
+     * @param id
+     * @return
+     */
+    ResponseJson deleteConsult(Integer id);
+
+    /**
+     * 排序
+     * @param sortNumber
+     * @return
+     */
+    ResponseJson sort(Integer id, Integer sortNumber);
+
+    /**
+     * 未注册用户咨询记录
+     * @param visit
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<VisitRemarkVo>> visitRemarkList(VisitRemarkVo visit, Integer pageNum, Integer pageSize);
+
+    /**
+     * 未注册用户数据详情
+     * @param visitRemarkVo
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmClubRemarks>> remarksList(VisitRemarkVo visitRemarkVo, Integer pageNum, Integer pageSize);
+
+}

+ 234 - 0
src/main/java/com/caimei365/manager/service/caimei/user/CustomerService.java

@@ -0,0 +1,234 @@
+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.cmUser.*;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+public interface CustomerService {
+    /**
+     * 潜客供应商列表
+     * @param cmShopStatistics
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShopStatistics>> getCustomerShopList(CmShopStatistics cmShopStatistics, Integer pageNum, Integer pageSize);
+
+    /**
+     * 供应商列表
+     * @param shopName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShop>> getShopLiat(String shopName, Integer pageNum, Integer pageSize);
+
+    /**
+     * 添加统计供应商
+     * @return
+     */
+    ResponseJson saveCustomerShop(String shopIds);
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    ResponseJson renewCustomerShop(Integer id, Integer status);
+
+    /**
+     * 游客统计
+     * @param cmRoosInformation
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmRoosInformation>> getCmInformationList(CmRoosInformation cmRoosInformation, Integer pageNum, Integer pageSize);
+
+    /**
+     * 设置跟进状态
+     * @param id
+     * @param followUpStatus
+     * @return
+     */
+    ResponseJson renewFollowUpStatus(Integer id, Integer followUpStatus);
+
+    /**
+     * 相关文章列表
+     * @param cmShopInfo
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShopInfo>> getShopInfoList(CmShopInfo cmShopInfo, Integer pageNum, Integer pageSize);
+
+    /**
+     * 选择文章
+     * @param id
+     * @param title
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<Info>> getInfoList(Integer id, String title, Integer pageNum, Integer pageSize);
+
+    /**
+     * 添加文章统计
+     * @param shopId
+     * @param infoIds
+     * @return
+     */
+    ResponseJson saveShopInfo(Integer shopId, String infoIds);
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    ResponseJson renewShopInfo(Integer id, Integer status);
+
+    /**
+     * 删除统计文章
+     * @param id
+     * @return
+     */
+    ResponseJson delShopInfo(Integer id);
+
+    /**
+     * 相关搜索词列表
+     * @param cmShopKeyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShopKeyword>> getShopKeywordList(CmShopKeyword cmShopKeyword, Integer pageNum, Integer pageSize);
+
+    /**
+     * 选择关键词
+     * @param keyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmUserSearchFrequency>> getSearchFrequencyList(String keyword, Integer pageNum, Integer pageSize);
+
+    /**
+     * 添加搜索词统计
+     * @param shopId
+     * @param keyWordIds
+     * @return
+     */
+    ResponseJson saveShopKeyword(Integer shopId, String keyWordIds);
+
+    /**
+     * 设置统计状态
+     * @param id
+     * @param status
+     * @return
+     */
+    ResponseJson renewShopKeyword(Integer id, Integer status);
+
+    /**
+     * 删除统计搜索词
+     * @param id
+     * @return
+     */
+    ResponseJson delShopKeyword(Integer id);
+
+    /**
+     * 弹框数据回显
+     * @param shopId
+     * @return
+     */
+    ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId);
+
+    /**
+     * 谈款数据保存
+     * @param cmShopPopUp
+     * @return
+     */
+    ResponseJson saveShopPopUp(CmShopPopUp cmShopPopUp);
+
+    /**
+     * 供应商广告列表
+     * @param cmShopAdvertisingImage
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    ResponseJson<PaginationVo<CmShopAdvertisingImage>> getShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage, Integer pageNum, Integer pageSize);
+
+    /**
+     * 供应商广告信息回显
+     * @param id
+     * @return
+     */
+    ResponseJson<CmShopAdvertisingImage> getShopAdvertisingImageById(Integer id);
+
+    /**
+     * 保存供应商广告信息
+     * @param cmShopAdvertisingImage
+     * @return
+     */
+    ResponseJson saveShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage);
+
+    /**
+     * 一键排序
+     * @param id
+     * @param sort
+     * @return
+     */
+    ResponseJson renewShopAdvertisingImageSort(Integer id, Integer sort);
+
+    /**
+     * 修改上下架状态
+     * @param id
+     * @param status
+     * @return
+     */
+    ResponseJson renewShopAdvertisingImageStatus(Integer id, Integer status);
+
+    /**
+     * 删除广告
+     * @param id
+     * @return
+     */
+    ResponseJson delShopAdvertisingImage(Integer id);
+
+    /**
+     * 供应商主页统计
+     * @param shopId
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    ResponseJson<PaginationVo<CmPageShop>> getPageShop(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize);
+
+    /**
+     * 供应商商品统计
+     * @param shopId
+     * @return
+     */
+    ResponseJson<PaginationVo<CmPageShopProduct>> getPageShopProduct(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize);
+
+    /**
+     * 供应商文章
+     * @param shopId
+     * @return
+     */
+    ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, 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);
+}

+ 463 - 0
src/main/java/com/caimei365/manager/service/caimei/user/impl/CmClubRemarksServiceImpl.java

@@ -0,0 +1,463 @@
+package com.caimei365.manager.service.caimei.user.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei.utils.AppUtils;
+import com.caimei.utils.MathUtil;
+import com.caimei365.manager.dao.user.CmClubRemarksDao;
+import com.caimei365.manager.entity.PaginationVo;
+import com.caimei365.manager.entity.ResponseJson;
+import com.caimei365.manager.entity.caimei.cmUser.*;
+import com.caimei365.manager.service.caimei.CmOssArchiveService;
+import com.caimei365.manager.service.caimei.user.CmClubRemarksService;
+import com.caimei365.manager.utils.OSSUtils;
+import com.github.pagehelper.PageHelper;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/7
+ */
+@Slf4j
+@Service
+public class CmClubRemarksServiceImpl implements CmClubRemarksService {
+
+    @Resource private CmClubRemarksDao cmClubRemarksDao;
+    @Resource private CmOssArchiveService cmOssArchiveService;
+    @Resource private OSSUtils ossUtils;
+
+    /**
+     * 咨询记录类别
+     * @return
+     */
+    @Override
+    public ResponseJson<List<CmConsulttype>> getClassName() {
+        List<CmConsulttype> className = cmClubRemarksDao.getClassName();
+        return ResponseJson.success(className);
+    }
+
+    /**
+     * 获取当天协销咨询记录信息
+     * @param time
+     * @return
+     */
+    @Override
+    public ResponseJson<Map<String, Object>> getServiceList(String time) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        if (StringUtils.isBlank(time)) {
+            time = dateFormat.format(new Date());
+        }
+        // 协销数据
+        List<ServiceProviderModel> serviceList = cmClubRemarksDao.getServiceList();
+        AtomicInteger registeredNumber = new AtomicInteger(0);
+        AtomicInteger unRegisteredNumber = new AtomicInteger(0);
+        for (ServiceProviderModel s : serviceList){
+            // 已注册用户咨询记录
+            s.setRegisteredNumber(cmClubRemarksDao.getRegisteredNumber(s.getServiceProviderId(), time));
+            // 未注册用户咨询记录
+            s.setUnregisteredNumber(cmClubRemarksDao.getUnregisteredNumber(s.getServiceProviderId(), time));
+            registeredNumber.set(MathUtil.add(registeredNumber.get(), s.getRegisteredNumber()).intValue());
+            unRegisteredNumber.set(MathUtil.add(unRegisteredNumber.get(), s.getUnregisteredNumber()).intValue());
+        }
+        Map<String, Object> map = new HashMap<>();
+        map.put("serviceList", serviceList);
+        map.put("registeredNumber", registeredNumber);
+        map.put("unRegisteredNumber", unRegisteredNumber);
+        map.put("number", MathUtil.add(registeredNumber, unRegisteredNumber).intValue());
+        return ResponseJson.success(map);
+    }
+
+    /**
+     * 已注册用户咨询记录
+     *
+     * @param cmClubRemarks
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmClubRemarks>> findRegistList(CmClubRemarks cmClubRemarks, Integer pageNum, Integer pageSize) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm");
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmClubRemarks> remarksList = cmClubRemarksDao.findRegistList(cmClubRemarks);
+        remarksList.forEach(remarks -> {
+            if (StringUtils.isNotBlank(remarks.getConsult())) {
+                StringBuilder cons = new StringBuilder();
+                if (remarks.getConsult().contains(",")) {
+                    String[] split = remarks.getConsult().split(",");
+                    for (String string : split) {
+                        cons.append(cmClubRemarksDao.findClassName(string)).append(",");
+                    }
+                    cons = new StringBuilder(cons.substring(0, cons.length() - 1));
+                } else {
+                    cons = new StringBuilder(cmClubRemarksDao.findClassName(remarks.getConsult()));
+                }
+                remarks.setConsultType(cons.toString());
+            }
+            List<String> remarkList = new ArrayList<>();
+            // 合并标签
+            if (StringUtils.isNotBlank(remarks.getRemarks())) {
+                if (remarks.getRemarks().contains(",")) {
+                    String[] split = remarks.getRemarks().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getRemarks());
+                }
+            }
+            if (StringUtils.isNotBlank(remarks.getTrendsKeyword())) {
+                if (remarks.getTrendsKeyword().contains(",")) {
+                    String[] split = remarks.getTrendsKeyword().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getTrendsKeyword());
+                }
+            }
+            if (StringUtils.isNotBlank(remarks.getStateKeyword())) {
+                if (remarks.getStateKeyword().contains(",")) {
+                    String[] split = remarks.getStateKeyword().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getStateKeyword());
+                }
+            }
+            remarks.setRemarks(StringUtils.strip(remarkList.toString(), "[]"));
+            List<String> imageList = null;
+            List<RemarksFileVo> fileList = null;
+            if (1 == remarks.getType()) {
+                // 已注册用户
+                imageList = cmClubRemarksDao.getRemarksImageList(remarks.getRemarksId());
+                fileList = cmClubRemarksDao.getRemarksFileList(remarks.getRemarksId());
+            } else {
+                // 未注册用户
+                imageList = cmClubRemarksDao.getVisitorImageList(remarks.getRemarksId());
+                fileList = cmClubRemarksDao.getVisitorFileList(remarks.getRemarksId());
+            }
+            fileList.forEach(f -> f.setFileUrl(ossUtils.getOssUrl(f.getOssName())));
+            if (StringUtils.isNotBlank(remarks.getMainImage())) {
+                remarks.setMainImage(AppUtils.getImageURL("product", remarks.getMainImage(), 0, ""));
+            }
+            remarks.setImageList(imageList);
+            remarks.setFileList(fileList);
+            // 咨询商品信息
+            if (null != remarks.getProductId()) {
+                remarks.setProduct(cmClubRemarksDao.getProduct(remarks.getProductId()));
+            }
+            // 报备记录
+            if (null != remarks.getReportId()) {
+                remarks.setReports(cmClubRemarksDao.getReportById(remarks.getReportId()));
+            }
+            // 处理时间
+            if (null != remarks.getAddTime()) {
+                remarks.setDivisionTime(dateFormat.format(remarks.getAddTime()));
+            }
+        });
+        PaginationVo<CmClubRemarks> page = new PaginationVo<>(remarksList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 文件下载
+     *
+     * @param fileName
+     * @param ossName
+     * @param request
+     * @param response
+     * @return
+     */
+    @Override
+    public void downloadRemarks(String fileName, String ossName, HttpServletRequest request, HttpServletResponse response)  throws IOException {
+
+        log.info("fileName==="+fileName+"===ossName==="+ossName);
+        ossUtils.downFile(ossName, fileName);
+        cmOssArchiveService.download(request, response, fileName);
+    }
+
+    /**
+     * 报备列表
+     *
+     * @param cmReport
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmReport>> getReportList(CmReport cmReport, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmReport> list = cmClubRemarksDao.getReportList(cmReport);
+        PaginationVo<CmReport> page = new PaginationVo<>(list);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 报备列表查看详情
+     *
+     * @param cmClubRemarks
+     * @return
+     */
+    @Override
+    public ResponseJson<List<CmClubRemarks>> cmRegistReportList(CmClubRemarks cmClubRemarks) {
+        List<CmClubRemarks> registList = cmClubRemarksDao.findRegistList(cmClubRemarks);
+        registList.forEach(remarks -> {
+            if (StringUtils.isNotBlank(remarks.getConsult())) {
+                StringBuilder cons = new StringBuilder();
+                if (remarks.getConsult().contains(",")) {
+                    String[] split = remarks.getConsult().split(",");
+                    for (String string : split) {
+                        cons.append(cmClubRemarksDao.findClassName(string)).append(",");
+                    }
+                    cons = new StringBuilder(cons.substring(0, cons.length() - 1));
+                } else {
+                    cons = new StringBuilder(cmClubRemarksDao.findClassName(remarks.getConsult()));
+                }
+                remarks.setConsultType(cons.toString());
+            }
+            List<String> imageList = cmClubRemarksDao.getRemarksImageList(remarks.getRemarksId());
+            List<RemarksFileVo> fileList = cmClubRemarksDao.getRemarksFileList(remarks.getRemarksId());
+            fileList.forEach(f -> f.setFileUrl(ossUtils.getOssUrl(f.getOssName())));
+            if (StringUtils.isNotBlank(remarks.getMainImage())) {
+                remarks.setMainImage(AppUtils.getImageURL("product", remarks.getMainImage(), 0, ""));
+            }
+            remarks.setImageList(imageList);
+            remarks.setFileList(fileList);
+            // 咨询商品信息
+            if (null != remarks.getProductId()) {
+                remarks.setProduct(cmClubRemarksDao.getProduct(remarks.getProductId()));
+            }
+            // 报备记录
+            if (null != remarks.getReportId()) {
+                remarks.setReports(cmClubRemarksDao.getReportById(remarks.getReportId()));
+            }
+        });
+        return ResponseJson.success(registList);
+    }
+
+    /**
+     * 取消关联
+     *
+     * @param remarksId
+     * @param type
+     * @return
+     */
+    @Override
+    public ResponseJson audit(Integer remarksId, Integer type) {
+        if (type == 1) {
+            cmClubRemarksDao.updateClubRemarks(remarksId);
+        } else {
+            cmClubRemarksDao.updateVisitorRemarks(remarksId);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除报备列表
+     *
+     * @param reportId
+     * @return
+     */
+    @Override
+    public ResponseJson deleteReport(Integer reportId) {
+        // 已注册咨询记录数
+        Integer clubCount = cmClubRemarksDao.clubRemarksConut(reportId);
+        // 未注册咨询记录数
+        Integer visitorCount = cmClubRemarksDao.visitorRemarksConut(reportId);
+        if (MathUtil.add(clubCount, visitorCount).intValue() > 0) {
+            return ResponseJson.error(-1, "请将该报备关联的全部咨询记录取消关联后再删除", null);
+        } else {
+            cmClubRemarksDao.deleteClubRemarks(reportId);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 审核
+     *
+     * @param reportId
+     * @param auditName
+     * @param auditText
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson reportCount(Integer reportId, String auditName, String auditText, Integer status) {
+        // 已注册咨询记录数
+        Integer clubCount = cmClubRemarksDao.clubRemarksConut(reportId);
+        // 未注册咨询记录数
+        Integer visitorCount = cmClubRemarksDao.visitorRemarksConut(reportId);
+        if (MathUtil.add(clubCount, visitorCount).intValue() > 0) {
+            cmClubRemarksDao.updateAuditRemarks(reportId, auditName, auditText, status);
+        } else {
+            return ResponseJson.error(-1, "该报备未关联任何咨询记录,无需审核。", null);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 咨询记录类别
+     *
+     * @param cmConsulttype
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmConsulttype>> getConsultList(CmConsulttype cmConsulttype, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmConsulttype> consultList = cmClubRemarksDao.getConsultList(cmConsulttype);
+        PaginationVo<CmConsulttype> page = new PaginationVo<>(consultList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 保存咨询记录类别
+     *
+     * @param cmConsulttype
+     * @return
+     */
+    @Override
+    public ResponseJson saveConsult(CmConsulttype cmConsulttype) {
+        if (null == cmConsulttype.getId()) {
+            // 添加
+            cmClubRemarksDao.insertConsult(cmConsulttype);
+        } else {
+            // 修改
+            cmClubRemarksDao.updateConsult(cmConsulttype);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除咨询记录类别
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson deleteConsult(Integer id) {
+        cmClubRemarksDao.deleteConsult(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 排序
+     *
+     * @param sortNumber
+     * @return
+     */
+    @Override
+    public ResponseJson sort(Integer id, Integer sortNumber) {
+        CmConsulttype cmConsulttype = new CmConsulttype();
+        cmConsulttype.setId(id);
+        cmConsulttype.setSortNumber(sortNumber);
+        cmClubRemarksDao.updateConsult(cmConsulttype);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 未注册用户咨询记录
+     *
+     * @param visit
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<VisitRemarkVo>> visitRemarkList(VisitRemarkVo visit, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<VisitRemarkVo> visitRemarkList = cmClubRemarksDao.getVisitRemarkList(visit);
+        PaginationVo<VisitRemarkVo> page = new PaginationVo<>(visitRemarkList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 未注册用户数据详情
+     *
+     * @param visitRemarkVo
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmClubRemarks>> remarksList(VisitRemarkVo visitRemarkVo, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmClubRemarks> remarksList = cmClubRemarksDao.getClubRemarksList(visitRemarkVo);
+        remarksList.forEach(remarks -> {
+            if (StringUtils.isNotBlank(remarks.getConsult())) {
+                StringBuilder cons = new StringBuilder();
+                if (remarks.getConsult().contains(",")) {
+                    String[] split = remarks.getConsult().split(",");
+                    for (String string : split) {
+                        cons.append(cmClubRemarksDao.findClassName(string)).append(",");
+                    }
+                    cons = new StringBuilder(cons.substring(0, cons.length() - 1));
+                } else {
+                    cons = new StringBuilder(cmClubRemarksDao.findClassName(remarks.getConsult()));
+                }
+                remarks.setConsultType(cons.toString());
+            }
+            List<String> imageList = null;
+            List<RemarksFileVo> fileList = null;
+            List<String> remarkList = new ArrayList<>();
+            // 合并标签
+            if (StringUtils.isNotBlank(remarks.getRemarks())) {
+                if (remarks.getRemarks().contains(",")) {
+                    String[] split = remarks.getRemarks().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getRemarks());
+                }
+            }
+            if (StringUtils.isNotBlank(remarks.getTrendsKeyword())) {
+                if (remarks.getTrendsKeyword().contains(",")) {
+                    String[] split = remarks.getTrendsKeyword().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getTrendsKeyword());
+                }
+            }
+            if (StringUtils.isNotBlank(remarks.getStateKeyword())) {
+                if (remarks.getStateKeyword().contains(",")) {
+                    String[] split = remarks.getStateKeyword().split(",");
+                    remarkList.addAll(Arrays.asList(split));
+                } else {
+                    remarkList.add(remarks.getStateKeyword());
+                }
+            }
+            remarks.setRemarks(StringUtils.strip(remarkList.toString(), "[]"));
+            if (1 == remarks.getType()) {
+                // 已注册用户
+                imageList = cmClubRemarksDao.getRemarksImageList(remarks.getRemarksId());
+                fileList = cmClubRemarksDao.getRemarksFileList(remarks.getRemarksId());
+            } else {
+                // 未注册用户
+                imageList = cmClubRemarksDao.getVisitorImageList(remarks.getRemarksId());
+                fileList = cmClubRemarksDao.getVisitorFileList(remarks.getRemarksId());
+            }
+            fileList.forEach(f -> f.setFileUrl(ossUtils.getOssUrl(f.getOssName())));
+            remarks.setImageList(imageList);
+            remarks.setFileList(fileList);
+            // 咨询商品信息
+            if (null != remarks.getProductId()) {
+                remarks.setProduct(cmClubRemarksDao.getProduct(remarks.getProductId()));
+            }
+            // 报备记录
+            if (null != remarks.getReportId()) {
+                remarks.setReports(cmClubRemarksDao.getReportById(remarks.getReportId()));
+            }
+        });
+        PaginationVo<CmClubRemarks> page = new PaginationVo<>(remarksList);
+        return ResponseJson.success(page);
+    }
+
+}

+ 575 - 0
src/main/java/com/caimei365/manager/service/caimei/user/impl/CustomerServiceImpl.java

@@ -0,0 +1,575 @@
+package com.caimei365.manager.service.caimei.user.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+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.service.caimei.user.CustomerService;
+import com.github.pagehelper.PageHelper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Description
+ *
+ * @author : Charles
+ * @date : 2023/9/5
+ */
+@Service
+public class CustomerServiceImpl implements CustomerService {
+
+    @Resource private CustomerServiceDao customerServiceDao;
+
+    /**
+     * 潜客供应商列表
+     * @param cmShopStatistics
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShopStatistics>> getCustomerShopList(CmShopStatistics cmShopStatistics, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShopStatistics> customerShopList = customerServiceDao.getCustomerShopList(cmShopStatistics);
+        PaginationVo<CmShopStatistics> page = new PaginationVo<>(customerShopList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 供应商列表
+     * @param shopName
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShop>> getShopLiat(String shopName, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShop> shopList = customerServiceDao.getShopList(shopName, null);
+        // 是否支持选择
+        List<Integer> customerShopId = customerServiceDao.getCustomerShopId();
+        shopList.forEach( s -> {
+            if (customerShopId.contains(s.getShopId())) {
+                s.setFlag(false);
+            } else {
+                s.setFlag(true);
+            }
+        });
+        PaginationVo<CmShop> page = new PaginationVo<>(shopList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 添加统计供应商
+     *
+     * @param shopIds
+     * @return
+     */
+    @Override
+    public ResponseJson saveCustomerShop(String shopIds) {
+        List<String> shopId = new ArrayList<>();
+        if (shopIds.contains(",")) {
+            shopId = Arrays.asList(shopIds.split(","));
+        } else {
+            shopId.add(shopIds);
+        }
+        for (String s : shopId) {
+            CmShopStatistics statistics = new CmShopStatistics();
+            statistics.setShopId(Integer.parseInt(s));
+            statistics.setStatus(0);
+            statistics.setDelFlag(0);
+            customerServiceDao.insertCustomerShop(statistics);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 设置统计状态
+     *
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson renewCustomerShop(Integer id, Integer status) {
+        customerServiceDao.updateCustomerShop(id, status);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 游客统计
+     *
+     * @param cmRoosInformation
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmRoosInformation>> getCmInformationList(CmRoosInformation cmRoosInformation, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmRoosInformation> cmInformationList = customerServiceDao.getCmInformationList(cmRoosInformation);
+        PaginationVo<CmRoosInformation> page = new PaginationVo<>(cmInformationList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 设置跟进状态
+     *
+     * @param id
+     * @param followUpStatus
+     * @return
+     */
+    @Override
+    public ResponseJson renewFollowUpStatus(Integer id, Integer followUpStatus) {
+        customerServiceDao.updateInformation(id, followUpStatus);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 相关文章列表
+     *
+     * @param cmShopInfo
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShopInfo>> getShopInfoList(CmShopInfo cmShopInfo, Integer pageNum, Integer pageSize) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShopInfo> shopInfoList = customerServiceDao.getShopInfoList(cmShopInfo);
+        for (CmShopInfo shopInfo : shopInfoList) {
+            if (null != shopInfo.getPubdate()) {
+                shopInfo.setPubdateString(dateFormat.format(shopInfo.getPubdate()));
+            }
+        }
+        PaginationVo<CmShopInfo> page = new PaginationVo<>(shopInfoList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 选择文章
+     *
+     * @param id
+     * @param title
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<Info>> getInfoList(Integer id, String title, Integer pageNum, Integer pageSize) {
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        PageHelper.startPage(pageNum, pageSize);
+        List<Info> infoList = customerServiceDao.getInfoList(id, title);
+        List<Integer> shopInfoId = customerServiceDao.getShopInfoId();
+        infoList.forEach( i -> {
+            if (shopInfoId.contains(i.getId())) {
+                i.setFlag(false);
+            } else {
+                i.setFlag(true);
+            }
+
+            if (null != i.getCreateDate()) {
+                i.setCreateDateString(dateFormat.format(i.getCreateDate()));
+            }
+            if (null != i.getPubdate()) {
+                i.setPubdateString(dateFormat.format(i.getPubdate()));
+            }
+
+        });
+        PaginationVo<Info> page = new PaginationVo<>(infoList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 添加文章统计
+     *
+     * @param shopId
+     * @param infoIds
+     * @return
+     */
+    @Override
+    public ResponseJson saveShopInfo(Integer shopId, String infoIds) {
+        List<String> infoId = new ArrayList<>();
+        if (infoIds.contains(",")) {
+            infoId = Arrays.asList(infoIds.split(","));
+        } else {
+            infoId.add(infoIds);
+        }
+        for (String s : infoId) {
+            CmShopInfo shopInfo = new CmShopInfo();
+            shopInfo.setShopId(shopId);
+            shopInfo.setInfoId(Integer.parseInt(s));
+            shopInfo.setStatus(0);
+            shopInfo.setDelFlag(0);
+            customerServiceDao.insertShopInfo(shopInfo);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 设置统计状态
+     *
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson renewShopInfo(Integer id, Integer status) {
+        customerServiceDao.updateShopInfoStatus(id, status);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除统计文章
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson delShopInfo(Integer id) {
+        customerServiceDao.delShopInfo(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 相关搜索词列表
+     *
+     * @param cmShopKeyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShopKeyword>> getShopKeywordList(CmShopKeyword cmShopKeyword, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShopKeyword> shopKeyword = customerServiceDao.getShopKeyword(cmShopKeyword);
+        PaginationVo<CmShopKeyword> page = new PaginationVo<>(shopKeyword);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 选择搜索词
+     *
+     * @param keyword
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmUserSearchFrequency>> getSearchFrequencyList(String keyword, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmUserSearchFrequency> searchFrequencyList = customerServiceDao.getSearchFrequencyList(keyword);
+        List<Integer> shopKeywordId = customerServiceDao.getShopKeywordId();
+        searchFrequencyList.forEach( s -> {
+            if (shopKeywordId.contains(s.getId())) {
+                s.setFlag(false);
+            } else {
+                s.setFlag(true);
+            }
+        });
+        PaginationVo<CmUserSearchFrequency> page = new PaginationVo<>(searchFrequencyList);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 添加搜索词统计
+     *
+     * @param shopId
+     * @param keyWordIds
+     * @return
+     */
+    @Override
+    public ResponseJson saveShopKeyword(Integer shopId, String keyWordIds) {
+        List<String> keyWordId = new ArrayList<>();
+        if (keyWordIds.contains(",")) {
+            keyWordId = Arrays.asList(keyWordIds.split(","));
+        } else {
+            keyWordId.add(keyWordIds);
+        }
+        for (String s : keyWordId) {
+            CmShopKeyword shopKeyword = new CmShopKeyword();
+            shopKeyword.setShopId(shopId);
+            shopKeyword.setSearchId(Integer.parseInt(s));
+            shopKeyword.setStatus(0);
+            shopKeyword.setDelFlag(0);
+            customerServiceDao.insertShopKeyword(shopKeyword);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 设置统计状态
+     *
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson renewShopKeyword(Integer id, Integer status) {
+        customerServiceDao.updateShopKeywordStatus(id, status);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除统计搜索词
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson delShopKeyword(Integer id) {
+        customerServiceDao.delShopKeyword(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 弹框数据回显
+     *
+     * @param shopId
+     * @return
+     */
+    @Override
+    public ResponseJson<CmShopPopUp> getShopPopUp(Integer shopId) {
+        return ResponseJson.success(customerServiceDao.getShopPopUp(shopId));
+    }
+
+    /**
+     * 弹框数据保存
+     *
+     * @param cmShopPopUp
+     * @return
+     */
+    @Override
+    public ResponseJson saveShopPopUp(CmShopPopUp cmShopPopUp) {
+        if (null == cmShopPopUp.getId()) {
+            // 新增
+            customerServiceDao.insertShopPopUp(cmShopPopUp);
+        } else {
+            // 修改
+            customerServiceDao.updateShopPopUp(cmShopPopUp);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 供应商广告列表
+     *
+     * @param cmShopAdvertisingImage
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmShopAdvertisingImage>> getShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmShopAdvertisingImage> shopAdvertisingImage = customerServiceDao.getShopAdvertisingImage(cmShopAdvertisingImage);
+        PaginationVo<CmShopAdvertisingImage> page = new PaginationVo<>(shopAdvertisingImage);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 供应商广告信息回显
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson<CmShopAdvertisingImage> getShopAdvertisingImageById(Integer id) {
+        CmShopAdvertisingImage shopAdvertisingImage = customerServiceDao.getShopAdvertisingImageById(id);
+        // 设置供应商信息
+        List<CmShop> shopList = customerServiceDao.getShopList("",shopAdvertisingImage.getShopId());
+        List<CmShopStatistics> shops = new ArrayList<>();
+        CmShop shop = shopList.stream().filter(s -> s.getShopId().equals(shopAdvertisingImage.getShopId())).collect(Collectors.toList()).get(0);
+        // 回显设置
+        CmShopStatistics cmShopStatistics = new CmShopStatistics();
+        cmShopStatistics.setShopId(shop.getShopId());
+        cmShopStatistics.setShopName(shop.getName());
+        cmShopStatistics.setLinkMan(shop.getLinkMan());
+        cmShopStatistics.setMobile(shop.getContractMobile());
+        cmShopStatistics.setStatus(shop.getStatus());
+        shops.add(cmShopStatistics);
+        shopAdvertisingImage.setShops(shops);
+        return ResponseJson.success(shopAdvertisingImage);
+    }
+
+    /**
+     * 保存供应商广告信息
+     *
+     * @param cmShopAdvertisingImage
+     * @return
+     */
+    @Override
+    public ResponseJson saveShopAdvertisingImage(CmShopAdvertisingImage cmShopAdvertisingImage) {
+        if (null == cmShopAdvertisingImage.getId()) {
+            cmShopAdvertisingImage.setSort(0);
+            cmShopAdvertisingImage.setDelFlag(0);
+            // 插入
+            customerServiceDao.insertShopAdvertisingImage(cmShopAdvertisingImage);
+        } else {
+            // 修改
+            customerServiceDao.updateShopAdvertisingImage(cmShopAdvertisingImage);
+        }
+        return ResponseJson.success();
+    }
+
+    /**
+     * 一键排序
+     *
+     * @param id
+     * @param sort
+     * @return
+     */
+    @Override
+    public ResponseJson renewShopAdvertisingImageSort(Integer id, Integer sort) {
+        customerServiceDao.updateShopAdvertisingImageSort(id, sort);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 修改上下架状态
+     *
+     * @param id
+     * @param status
+     * @return
+     */
+    @Override
+    public ResponseJson renewShopAdvertisingImageStatus(Integer id, Integer status) {
+        customerServiceDao.updateShopAdvertisingImageStatus(id, status);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 删除广告
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public ResponseJson delShopAdvertisingImage(Integer id) {
+        customerServiceDao.delShopAdvertisingImage(id);
+        return ResponseJson.success();
+    }
+
+    /**
+     * 供应商主页统计
+     *
+     * @param shopId
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmPageShop>> getPageShop(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmPageShop> pageShop = customerServiceDao.getPageShop(shopId, startTime, endTime);
+        pageShop.forEach(shop -> {
+            shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+        });
+        PaginationVo<CmPageShop> page = new PaginationVo<>(pageShop);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 供应商商品统计
+     *
+     * @param shopId
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmPageShopProduct>> getPageShopProduct(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmPageShopProduct> pageShopProduct = customerServiceDao.getPageShopProduct(shopId, startTime, endTime);
+        pageShopProduct.forEach(shop -> {
+            shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+        });
+        PaginationVo<CmPageShopProduct> page = new PaginationVo<>(pageShopProduct);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 供应商文章
+     *
+     * @param shopId
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmPageShopInfo>> getPageShopInfo(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmPageShopInfo> pageShopInfo = customerServiceDao.getPageShopInfo(shopId, startTime, endTime);
+        pageShopInfo.forEach(shop -> {
+            shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+        });
+        PaginationVo<CmPageShopInfo> page = new PaginationVo<>(pageShopInfo);
+        return ResponseJson.success(page);
+    }
+
+    /**
+     * 供应商搜索词统计
+     *
+     * @param shopId
+     * @param pageNum
+     * @param pageSize
+     * @return
+     */
+    @Override
+    public ResponseJson<PaginationVo<CmPageShopKeyword>> getPageShopKeyword(Integer shopId, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+        PageHelper.startPage(pageNum, pageSize);
+        List<CmPageShopKeyword> pageShopKeyword = customerServiceDao.getPageShopKeyword(shopId, startTime, endTime);
+        pageShopKeyword.forEach(shop -> {
+            shop.setAverage(calculationTime(shop.getAverageDuration().toString()));
+        });
+        PaginationVo<CmPageShopKeyword> page = new PaginationVo<>(pageShopKeyword);
+        return ResponseJson.success(page);
+    }
+
+
+    /**
+     * 时间计算
+     * @param recordTime
+     * @return
+     */
+    public String calculationTime(String recordTime){
+        double doc = Double.parseDouble(recordTime);
+        int num = (int)doc;
+        //小时
+        int HH = 0;
+        // 分钟
+        int mm = 0;
+        //秒
+        int ss = 0;
+        int item = num / 1000;
+        if ((item / 60) >0) {
+            mm = item / 60;
+            ss = item % 60;
+        } else {
+            ss = item;
+        }
+        if ((mm / 60) >0) {
+            HH = mm / 60;
+            mm = mm % 60;
+        }
+        String  str= HH+":"+mm+":"+ss;
+        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
+        Date parse = null;
+        try {
+            parse = dateFormat.parse(str);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return dateFormat.format(parse);
+    }
+}

+ 11 - 10
src/main/java/com/caimei365/manager/service/wechat/impl/WechatReplyServiceImpl.java

@@ -38,12 +38,12 @@ public class WechatReplyServiceImpl implements WechatReplyService {
     /**
      * 获取回复配置列表
      *
-     * @param type 类型: 1采美,2呵呵商城
-     * @param title 回复素材标题
-     * @param responseType   事件类型
-     * @param msgType   回复类型
-     * @param pageNum  页码
-     * @param pageSize 每页大小
+     * @param type         类型: 1采美,2呵呵商城
+     * @param title        回复素材标题
+     * @param responseType 事件类型
+     * @param msgType      回复类型
+     * @param pageNum      页码
+     * @param pageSize     每页大小
      */
     @Override
     public ResponseJson<PaginationVo<WechatReply>> getReplyList(Integer type, String title, String responseType, String msgType, int pageNum, int pageSize) {
@@ -79,18 +79,19 @@ public class WechatReplyServiceImpl implements WechatReplyService {
         if (null == dbReply) {
             return ResponseJson.error("当前回复配置异常!", null);
         }
-        if (StringUtils.hasLength(reply.getMsgType())){
+        if (StringUtils.hasLength(reply.getMsgType())) {
             dbReply.setMsgType(reply.getMsgType());
         }
-        if (StringUtils.hasLength(reply.getResponseType())){
+        if (StringUtils.hasLength(reply.getResponseType())) {
             dbReply.setResponseType(reply.getResponseType());
         }
-        if (StringUtils.hasLength(reply.getKeyword())){
+        if (StringUtils.hasLength(reply.getKeyword())) {
             dbReply.setKeyword(reply.getKeyword());
         }
-        if (StringUtils.hasLength(reply.getTitle())){
+        if (StringUtils.hasLength(reply.getTitle())) {
             dbReply.setTitle(reply.getTitle());
         }
+        dbReply.setRelateId(reply.getRelateId());
         Integer userId = systemDao.getUserIdByUsername(username);
         dbReply.setUserId(userId);
         // 更新

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

@@ -0,0 +1,259 @@
+package com.caimei365.manager.utils;
+
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.GetObjectRequest;
+import com.aliyun.oss.model.ObjectMetadata;
+import com.aliyun.oss.model.UploadFileRequest;
+import com.caimei365.manager.config.thinkgem.Global;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+@Component
+public class OSSUtils {
+
+    @Resource private Environment environment;
+
+    private String endpoint; // = "https://oss-cn-shenzhen.aliyuncs.com";
+    private String accessKeyId; // = "LTAI4GBL3o4YkWnbKYgf2Xia";
+    private String accessKeySecret;//  = "dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK";
+    private String privateBucket; // = "caimei-oss";
+    private String config; // = Global.getConfig("cm.config");
+
+    public void setValue() {
+        endpoint = environment.getProperty("aliyun.endpoint");
+        accessKeyId = environment.getProperty("aliyun.accessKeyId");
+        accessKeySecret = environment.getProperty("aliyun.accessKeySecret");
+        privateBucket = environment.getProperty("aliyun.bucketName");
+        config = environment.getProperty("cm.config");
+    }
+
+    public  String ossUpload(String fileName, File file, String contentType) {
+        setValue();
+        String url = null;
+        try {
+            if ("product".equals(config)) {
+                fileName = "prod/" + fileName;
+            } else {
+                fileName = config + "/" + fileName;
+            }
+            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+            ObjectMetadata meta = new ObjectMetadata();
+            meta.setContentType(contentType);
+            UploadFileRequest uploadFileRequest = new UploadFileRequest(privateBucket, fileName);
+            // 指定上传的本地文件。
+            uploadFileRequest.setUploadFile(file.toString());
+            // 指定上传并发线程数,默认为1。
+            uploadFileRequest.setTaskNum(10);
+            // 指定上传的分片大小,范围为100KB~5GB,默认为文件大小/10000。
+            uploadFileRequest.setPartSize(1024 * 1024);
+            // 开启断点续传,默认关闭。
+            uploadFileRequest.setEnableCheckpoint(true);
+            uploadFileRequest.setCheckpointFile(file.getAbsolutePath() + "uploadFile.ucp");
+            // 文件的元数据。
+            uploadFileRequest.setObjectMetadata(meta);
+            // 设置上传成功回调,参数为Callback类型。
+            //uploadFileRequest.setCallback("<yourCallbackEvent>");
+            // 断点续传上传。
+            ossClient.uploadFile(uploadFileRequest);
+            Date expiration = new Date(new Date().getTime() + 3600L * 1000);
+            url = ossClient.generatePresignedUrl(privateBucket, fileName, expiration).toString();
+            // 关闭OSSClient。
+            ossClient.shutdown();
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return url;
+    }
+
+
+    /**
+     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
+     */
+    public String getContentType(String fileName) {
+        setValue();
+        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
+        if (".bmp".equalsIgnoreCase(fileExtension)) {
+            return "image/bmp";
+        }
+        if (".gif".equalsIgnoreCase(fileExtension)) {
+            return "image/gif";
+        }
+        if (".jpeg".equalsIgnoreCase(fileExtension)) {
+            return "image/jpeg";
+        }
+        if (".jpg".equalsIgnoreCase(fileExtension)) {
+            return "image/jpg";
+        }
+        if (".png".equalsIgnoreCase(fileExtension)) {
+            return "image/png";
+        }
+        if (".html".equalsIgnoreCase(fileExtension)) {
+            return "text/html";
+        }
+        if (".txt".equalsIgnoreCase(fileExtension)) {
+            return "text/plain";
+        }
+        if (".vsd".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.visio";
+        }
+        if (".ppt".equalsIgnoreCase(fileExtension)  ) {
+            return "application/vnd.ms-powerpoint";
+        }
+        if (".pptx".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
+        }
+        if (".doc".equalsIgnoreCase(fileExtension)) {
+            return "application/msword";
+        }
+        if ("docx".equalsIgnoreCase(fileExtension)) {
+            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
+        }
+        if (".xml".equalsIgnoreCase(fileExtension)) {
+            return "text/xml";
+        }
+        if (".mp4".equalsIgnoreCase(fileExtension)) {
+            return "video/mp4";
+        }
+        if (".mp3".equalsIgnoreCase(fileExtension)) {
+            return "audio/mp3";
+        }
+        if (".pdf".equalsIgnoreCase(fileExtension)) {
+            return "application/pdf";
+        }
+        return "text/html";
+    }
+
+    public void deleteFile(File... files) {
+        setValue();
+        for (File file : files) {
+            //logger.info("File:[{}]",file.getAbsolutePath());
+            if (file.exists()) {
+                file.delete();
+            }
+        }
+    }
+
+    public File ossUpload(MultipartFile file) throws IOException {
+        setValue();
+        // 获取文件名
+        String fileName = file.getOriginalFilename();
+        // 获取文件后缀
+        String prefix = fileName.substring(fileName.lastIndexOf("."));
+        // 用uuid作为文件名,防止生成的临时文件重复
+        File excelFile = File.createTempFile(UUID.randomUUID().toString(), prefix);
+        // MultipartFile to File
+        file.transferTo(excelFile);
+        //程序结束时,删除临时文件
+        return excelFile;
+    }
+
+    /**
+     * 授权生成签名URL临时访问
+     *
+     * @param fileName 文件名称
+     */
+    public String getOssUrl(String fileName) {
+        setValue();
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 设置URL过期时间为1个小时
+        Date expiration = new Date(new Date().getTime() + 3600L * 1000);
+        if ("product".equals(config)) {
+            fileName = "prod/" + fileName;
+        } else {
+            fileName = config + "/" + fileName;
+        }
+        String url = ossClient.generatePresignedUrl(privateBucket, fileName, expiration).toString();
+        // 关闭OSSClient。
+        ossClient.shutdown();
+        return url;
+    }
+
+    /**
+     * 生成商品资料库链接
+     * @param ossName
+     * @param uploadTime
+     * @return
+     */
+    public String generateProductArchiveUrl(String ossName, Date uploadTime) {
+        setValue();
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 设置URL过期时间为1个小时
+        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000);
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        try {
+            Date dateOne = format.parse("2021-06-01 00:00:00");
+            Date dateTwo = format.parse("2021-09-17 18:00:00");
+            String active = "product".equals(config) ? "prod" : config;
+            if (uploadTime != null && uploadTime.compareTo(dateOne) > 0 && uploadTime.compareTo(dateTwo) < 0) {
+                ossName = active + "/" + ossName;
+            } else if (uploadTime != null && uploadTime.compareTo(dateTwo) > 0) {
+                ossName = active + "/archiveFile/" + ossName;
+            }
+        } catch (ParseException e) {
+        }
+        String url = ossClient.generatePresignedUrl(privateBucket, ossName, expiration).toString();
+        ossClient.shutdown();
+        return url;
+    }
+
+    /**
+     * oss单个文件删除
+     *
+     * @param fileName 文件名称或文件夹名称
+     */
+    public void deleteSingleFile(String fileName) {
+        setValue();
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 删除文件。如需删除文件夹,请将ObjectName设置为对应的文件夹名称。
+        // 如果文件夹非空,则需要将文件夹下的所有object删除后才能删除该文件夹。
+        try {
+            //之前的文件没有放进文件夹
+            ossClient.deleteObject(privateBucket, fileName);
+        } catch (Exception e) {
+            if ("product".equals(config)) {
+                fileName = "prod/" + fileName;
+            } else {
+                fileName = config + "/" + fileName;
+            }
+            ossClient.deleteObject(privateBucket, fileName);
+        }
+        // 关闭OSSClient。
+        ossClient.shutdown();
+    }
+
+    /**
+     * oss单个文件下载
+     */
+    public void downFile(String ossName, String fileName) {
+        setValue();
+        // 创建OSSClient实例。
+        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
+        // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。
+        try {
+            //之前的文件没有放进文件夹
+            ossClient.getObject(new GetObjectRequest(privateBucket, ossName), new File("./" + fileName));
+        } catch (Exception e) {
+            if ("product".equals(config)) {
+                ossName = "prod/" + ossName;
+            } else {
+                ossName = config + "/" + ossName;
+            }
+            ossClient.getObject(new GetObjectRequest(privateBucket, ossName), new File("./" + fileName));
+        }
+        // 关闭OSSClient。
+        ossClient.shutdown();
+    }
+
+}

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

@@ -0,0 +1,63 @@
+package com.caimei365.manager.utils;
+
+import lombok.extern.slf4j.Slf4j;
+import com.caimei365.manager.FastDFS.FastDFSClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@Controller
+@RequestMapping("formData")
+@Slf4j
+public class formDataUtils {
+    @Resource
+    private FastDFSClient client;
+    @Value("${caimei.imageDomain}")
+    private String imageDomain;
+
+    @ResponseBody
+    @RequestMapping("/MultiPictareaddData")
+    public Map<String, Object> MultiPictareaddData(MultipartFile[] file, HttpServletRequest request) throws IOException {
+        Map<String, Object> map = new HashMap<String, Object>();
+        String saveFile = null;
+        if (file != null && file.length > 0) {
+            for (int i = 0; i < file.length; i++) {
+                MultipartFile filex = file[i];
+                // 保存文件
+                saveFile = saveFile(request, filex);
+                saveFile = imageDomain + "/" + saveFile;
+            }
+            map.put("data", saveFile);
+            map.put("msg", "上传成功");
+            log.info(">>>>>>>>>>>>>>>>图片上传成功:" + saveFile);
+        } else {
+            map.put("msg", "上传失败");
+            log.info(">>>>>>>>>>>>>>>>图片上传失败:");
+        }
+        return map;
+    }
+
+    private String saveFile(HttpServletRequest request, 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);
+        return file1;
+    }
+}

+ 19 - 0
src/main/resources/config/beta/application-beta.yml

@@ -48,6 +48,15 @@ caimei:
   coreDomain: https://core-b.caimei365.com
   imageDomain: https://img-b.caimei365.com
 
+cm:
+  config: beta
+
+aliyun:
+  accessKeyId: LTAI4GBL3o4YkWnbKYgf2Xia
+  accessKeySecret: dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK
+  bucketName: caimei-oss
+  endpoint: https://oss-cn-shenzhen.aliyuncs.com
+
 # 微信公众号
 wechat:
   apiUrl: https://api.weixin.qq.com
@@ -64,3 +73,13 @@ wechat:
     id: gh_123456
     appid: wx123456
     secret: abc123456
+
+#DFS配置
+fdfs:
+  so-timeout: 5000 #上传的超时时间
+  connect-timeout: 2000 #连接超时时间
+  thumb-image:             #缩略图生成参数
+    width: 150
+    height: 150
+  tracker-list:            #TrackerList参数,支持多个
+    - 172.31.165.28:22122

+ 19 - 0
src/main/resources/config/dev/application-dev.yml

@@ -48,6 +48,15 @@ caimei:
   coreDomain: https://core-b.caimei365.com
   imageDomain: https://img-b.caimei365.com
 
+cm:
+  config: dev
+
+aliyun:
+  accessKeyId: LTAI4GBL3o4YkWnbKYgf2Xia
+  accessKeySecret: dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK
+  bucketName: caimei-oss
+  endpoint: https://oss-cn-shenzhen.aliyuncs.com
+
 # 微信公众号
 wechat:
   apiUrl: https://api.weixin.qq.com
@@ -64,3 +73,13 @@ wechat:
     id: gh_123456
     appid: wx123456
     secret: abc123456
+
+#DFS配置
+fdfs:
+  so-timeout: 5000 #上传的超时时间
+  connect-timeout: 2000 #连接超时时间
+  thumb-image:             #缩略图生成参数
+    width: 150
+    height: 150
+  tracker-list:            #TrackerList参数,支持多个
+    - 192.168.2.100:22122

+ 20 - 0
src/main/resources/config/prod/application-prod.yml

@@ -50,6 +50,15 @@ caimei:
   coreDomain: https://core.caimei365.com
   imageDomain: https://img.caimei365.com
 
+cm:
+  config: product
+
+aliyun:
+  accessKeyId: LTAI4GBL3o4YkWnbKYgf2Xia
+  accessKeySecret: dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK
+  bucketName: caimei-oss
+  endpoint: https://oss-cn-shenzhen.aliyuncs.com
+
 # 微信公众号
 wechat:
   apiUrl: https://api.weixin.qq.com
@@ -66,3 +75,14 @@ wechat:
     id: gh_7de98a37fb6a
     appid: wxea43a0f9ebce9e66
     secret: 1c3cd60908e72dd280840bee9e15f7f6
+
+
+#DFS配置
+fdfs:
+  so-timeout: 5000 #上传的超时时间
+  connect-timeout: 2000 #连接超时时间
+  thumb-image:             #缩略图生成参数
+    width: 150
+    height: 150
+  tracker-list:            #TrackerList参数,支持多个
+    - 172.31.165.24:22122

+ 117 - 9
src/main/resources/mapper/KeyWordDao.xml

@@ -2,13 +2,13 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.caimei365.manager.dao.KeyWordDao">
     <insert id="insertLabel">
-        insert into cm_user_search_frequency(fromSearch, keyword, frequency, trueStatus, addTime)
-        values (1, #{keyword}, 0, 1, now())
+        insert into cm_user_search_frequency(fromSearch, keyword, frequency, dynamicStatus, trueStatus, addTime)
+        values (1, #{keyword}, 0, 0, 1, now())
     </insert>
 
     <insert id="insertLabelByExcel">
-        insert into cm_user_search_frequency(fromSearch, keyword, frequency, trueStatus, addTime)
-        values (3, #{keyword}, 0, 1, now())
+        insert into cm_user_search_frequency(fromSearch, keyword, frequency, trueStatus, dynamicStatus, addTime)
+        values (3, #{keyword}, 0, 1, 0, now())
     </insert>
 
     <update id="updateLabelStatus">
@@ -53,21 +53,28 @@
     <select id="findList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
         SELECT cusf.id AS id, frequency, cusf.keyword as keyword,addTime,linkageStatus,
         cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch
+        SELECT cusf.id AS id, cusf.frequency, cusf.keyword as keyword, cusf.addTime,
+        cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch,
+        cusf.dynamicStatus, s.linkMan as name
         FROM cm_user_search_frequency cusf
+        left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
         WHERE cusf.delStatus = 1
         <if test="beginTime !=null and beginTime !=''">
-            AND (searchTime BETWEEN #{beginTime} AND #{endTime} or searchTime IS NULL)
+            AND (cusf.searchTime BETWEEN #{beginTime} AND #{endTime} or cusf.searchTime IS NULL)
         </if>
         <if test="keyword !=null and keyword !=''">
-            AND keyword LIKE CONCAT('%',#{keyword},'%')
+            AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
+        </if>
+        <if test="labelStatus == 1">
+            AND cusf.dynamicStatus = 0
         </if>
         <if test="labelStatus !=null">
-            AND trueStatus = #{labelStatus}
+            AND cusf.trueStatus = #{labelStatus}
         </if>
         <if test="fromSearch != null">
-            AND fromSearch = #{fromSearch}
+            AND cusf.fromSearch = #{fromSearch}
         </if>
-        ORDER BY frequency DESC,searchTime DESC
+        ORDER BY cusf.addTime DESC, cusf.searchTime DESC
     </select>
 
     <select id="findRecommendList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
@@ -119,4 +126,105 @@
         where keyword = #{keyword}
           and delstatus = 1
     </select>
+
+    <select id="getServiceList" resultType="com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel">
+        SELECT
+            ser.serviceProviderID AS serviceProviderId,
+            ser.linkMan,
+            ser.userID AS userId
+        FROM serviceprovider ser
+        WHERE ser.organizeId = 0 AND ser.validFlag = 1 AND ser.status = 90 GROUP BY ser.serviceProviderID
+        order by ser.addTime asc
+    </select>
+
+    <select id="getStateKeyWordList" resultType="com.caimei365.manager.entity.caimei.KeyWord">
+        SELECT cusf.id AS id, cusf.frequency, cusf.keyword as keyword, cusf.addTime,
+        cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch,
+        cusf.serviceProviderId, cusf.dynamicStatus, s.linkMan as name
+        FROM cm_user_search_frequency cusf
+        left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
+        WHERE cusf.delStatus = 1 AND cusf.dynamicStatus = 1
+        <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="fromSearch != null">
+            AND cusf.fromSearch = #{fromSearch}
+        </if>
+        <if test="serviceProviderId != null">
+            AND cusf.serviceProviderID = #{serviceProviderId}
+        </if>
+        ORDER BY cusf.addTime DESC
+    </select>
+
+    <insert id="insertLabelByState">
+        insert into cm_user_search_frequency(fromSearch, keyword, frequency, trueStatus, dynamicStatus, addTime)
+        values (1, #{keyword}, 0, 0, 1, now())
+    </insert>
+
+    <select id="getPriorKeywordList" resultType="com.caimei365.manager.entity.caimei.CmPriorKeyword">
+        select
+            cpk.id, cpk.searchId AS searchId ,cusf.fromSearch as fromSearch, cusf.keyword as keyword, cusf.dynamicStatus,
+            cusf.serviceProviderId, cpk.addTime, s.linkMan as name
+        from cm_prior_keyword cpk
+        left join cm_user_search_frequency cusf on cpk.searchId = cusf.id
+        left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
+        WHERE cpk.delFlag = 0 AND cusf.delStatus = 1
+        <if test="keyword !=null and keyword !=''">
+            AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
+        </if>
+        <if test="fromSearch != null">
+            AND cusf.fromSearch = #{fromSearch}
+        </if>
+        <if test="dynamicStatus != null">
+            AND cusf.dynamicStatus = #{dynamicStatus}
+        </if>
+        order by cpk.addTime desc
+    </select>
+
+    <select id="getPickKeyword" resultType="com.caimei365.manager.entity.caimei.KeyWord">
+        SELECT cusf.id AS id, cusf.frequency, cusf.keyword as keyword, cusf.addTime,
+        cusf.searchTime as searchTime,cusf.trueStatus as labelStatus,cusf.fromSearch as fromSearch,
+        cusf.serviceProviderId, cusf.dynamicStatus, s.linkMan as name
+        FROM cm_user_search_frequency cusf
+        left join serviceprovider s on cusf.serviceProviderId = s.serviceProviderID
+        WHERE cusf.delStatus = 1
+        <if test="keyword !=null and keyword !=''">
+            AND cusf.keyword LIKE CONCAT('%',#{keyword},'%')
+        </if>
+        <if test="fromSearch != null">
+            AND cusf.fromSearch = #{fromSearch}
+        </if>
+        <if test="dynamicStatus != null">
+            AND cusf.dynamicStatus = #{dynamicStatus}
+        </if>
+        ORDER BY cusf.addTime DESC
+    </select>
+
+    <select id="getPriorCount" resultType="java.lang.Integer">
+        select count(id) from cm_prior_keyword where delFlag = 0
+    </select>
+
+    <select id="getPrior" resultType="java.lang.Integer">
+        select id from cm_prior_keyword where delFlag = 0 and searchId = #{searchId}
+    </select>
+
+    <insert id="insertPriorKeyword">
+        insert into cm_prior_keyword (searchId, addTime, delFlag)
+        values (#{searchId}, now(), 0)
+    </insert>
+
+    <update id="delPriorKeyword">
+        update cm_prior_keyword
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
+    <update id="delPriorKeywordById">
+        update cm_prior_keyword
+        set delFlag = 1
+        where searchId = #{id}
+    </update>
 </mapper>

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

@@ -0,0 +1,473 @@
+<?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.CmClubRemarksDao">
+
+    <select id="getServiceList" resultType="com.caimei365.manager.entity.caimei.cmUser.ServiceProviderModel">
+        SELECT
+            ser.serviceProviderID AS serviceProviderId,
+            ser.linkMan,
+            ser.userID AS userId,
+            ser.mainServiceProviderID AS mainServiceProviderId,
+            svs.linkMan as mainName
+        FROM serviceprovider ser
+                 LEFT JOIN cm_serviceteam_group csg ON csg.serviceId = ser.serviceProviderID
+                 LEFT JOIN cm_serviceteam_role csr ON csr.id = csg.teamId
+                 LEFT JOIN (SELECT serviceProviderID, linkMan FROM serviceprovider WHERE validFlag = 1 AND STATUS = 90) svs ON svs.serviceProviderID = csr.leaderId
+        WHERE ser.organizeId = 0 AND ser.validFlag = 1 AND ser.status = 90 and ser.serviceProviderID not in(1371, 1342) GROUP BY ser.serviceProviderID
+        order by csr.createdTime, ser.addTime asc
+    </select>
+
+    <select id="getRegisteredNumber" resultType="java.lang.Integer">
+        SELECT
+                (SELECT COUNT(id) FROM cm_club_remarks WHERE createServiceProviderId = #{serviceProviderId} and addTime LIKE concat('%',#{addTime},'%') AND clubId IS NOT NULL)
+                    + (SELECT COUNT(id) FROM cm_visitor_remarks WHERE serviceProviderId = #{serviceProviderId} AND addTime LIKE concat('%',#{addTime},'%') AND clubId IS NOT NULL)
+    </select>
+
+    <select id="getUnregisteredNumber" resultType="java.lang.Integer">
+        SELECT
+                (SELECT COUNT(id) FROM cm_visitor_remarks WHERE serviceProviderId = #{serviceProviderId} and addTime LIKE concat('%',#{addTime},'%') AND clubId IS NULL)
+    </select>
+
+    <select id="getClassName" resultType="com.caimei365.manager.entity.caimei.cmUser.CmConsulttype">
+        select id, className
+        from cm_consulttype
+        where delFlag = 0
+    </select>
+
+    <select id="findRegistList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmClubRemarks">
+        SELECT DISTINCT
+        ccr.id AS remarksId, ccr.remarks, s.linkman AS spName, ccr.addTime, ccr.questionMan,
+        csr.leaderId AS leaderId, IFNULL(ccr.consultType,'') AS consult, c.Name AS clubName,
+        ccr.clubType, ccr.pinceSensitve, ccr.satisfied, ccr.followup, ccr.extra,
+        ccr.communicationSituation, ccr.communicationMethods, ccr.customerSource, ccr.customerGender, ccr.groupAddition,
+        ccr.customerAge, ccr.trendsKeyword, ccr.stateKeyword, c.newDeal, c.contractMobile, '1' as type,
+        (SELECT linkMan FROM serviceprovider s WHERE s.serviceProviderID = ccr.serviceProviderId) AS serviceName,
+        (SELECT NAME FROM serviceprovider s WHERE s.serviceProviderID= csr.leaderId) AS leaderName,
+        (SELECT mainImage FROM product p WHERE p.productID= ccre.productID) AS productMainImage,
+        (SELECT NAME FROM product p WHERE p.productID= ccre.productID) AS proName,
+        ccre.reportText AS reportText, ccre.status AS reportStatus, ccre.auditName AS auditName, ccre.auditTime AS auditTime,
+        p.mainImage AS mainImage, ccr.productId as productId, p.name AS productName, sh.name AS shopName, ccr.reportID
+        FROM cm_club_remarks ccr
+        LEFT JOIN serviceprovider s ON ccr.createServiceProviderId = s.serviceProviderID
+        LEFT JOIN club c ON c.clubId=ccr.clubId
+        LEFT JOIN cm_serviceTeam_group csg ON ccr.createServiceProviderId = csg.serviceId
+        LEFT JOIN cm_serviceTeam_role csr ON csr.id = csg.teamId
+        LEFT JOIN cm_club_report ccre ON ccre.Id= ccr.reportID
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN shop sh ON sh.shopID = p.shopID
+        <where>
+            s.validFlag = 1 and s.serviceProviderID not in (1371, 1342)
+            <if test="remarks != null and remarks !=''">
+                AND ccr.remarks LIKE concat('%',#{remarks},'%')
+            </if>
+            <if test="clubName !=null and clubName !=''">
+                AND c.Name like concat('%',#{clubName},'%')
+            </if>
+            <if test="leaderId != null">
+                and csr.leaderId = #{leaderId}
+            </if>
+            <if test="serviceProviderId != null">
+                and ccr.serviceProviderId = #{serviceProviderId}
+            </if>
+            <if test="consult != null">
+                and ccr.consultType like concat('%',#{consult},'%')
+            </if>
+            <if test="todayTime != null and todayTime != ''">
+                and ccr.addTime like concat('%', #{todayTime}, '%')
+            </if>
+            <if test="startAddTime != '' and startAddTime != null">
+                and ccr.addTime <![CDATA[  >  ]]> #{startAddTime}
+            </if>
+            <if test="endAddTime != '' and endAddTime != null">
+                and ccr.addTime <![CDATA[  <  ]]> #{endAddTime}
+            </if>
+            <if test="newDeal !=null">
+                and c.newDeal=#{newDeal}
+            </if>
+            <if test="reportId !=null">
+                and ccr.reportID=#{reportId}
+            </if>
+            <if test="isRegister != null">
+                <if test="isRegister == 1">
+                    and ccr.clubId is null
+                </if>
+                <if test="isRegister == 2">
+                    and ccr.clubId is not null
+                </if>
+            </if>
+        </where>
+
+        union
+
+        SELECT DISTINCT
+        ccr.id AS remarksId, ccr.remarks, s.name AS spName, ccr.addTime, ccr.questionMan,
+        csr.leaderId AS leaderId, IFNULL(ccr.consultType,'') AS consult, c.Name AS clubName,
+        ccr.clubType, ccr.pinceSensitve, ccr.satisfied, ccr.followup, ccr.extra,
+        ccr.communicationSituation AS communicationSituation, ccr.communicationMethods AS communicationMethods, ccr.customerSource AS customerSource,
+        ccr.customerGender AS customerGender, ccr.groupAddition AS groupAddition, ccr.customerAge AS customerAge,
+        ccr.trendsKeyword AS trendsKeyword, ccr.stateKeyword AS stateKeyword, c.newDeal, c.contractMobile, '2' as type,
+        (SELECT linkMan FROM serviceprovider s WHERE s.serviceProviderID = ccr.serviceProviderId) AS serviceName,
+        (SELECT NAME FROM serviceprovider s WHERE s.serviceProviderID = csr.leaderId) AS leaderName,
+        (SELECT mainImage FROM product p WHERE p.productID= ccre.productID) AS productMainImage,
+        (SELECT NAME FROM product p WHERE p.productID= ccre.productID) AS proName,
+        ccre.reportText AS reportText, ccre.status AS reportStatus, ccre.auditName AS auditName, ccre.auditTime AS auditTime,
+        p.mainImage AS mainImage, ccr.productId as productId, p.name AS productName, sh.name AS shopName, ccr.reportID
+        FROM cm_visitor_remarks ccr
+        LEFT JOIN serviceprovider s ON ccr.serviceProviderId = s.serviceProviderID
+        LEFT JOIN club c ON c.clubId = ccr.clubId
+        LEFT JOIN cm_serviceTeam_group csg ON ccr.serviceProviderId = csg.serviceId
+        LEFT JOIN cm_serviceTeam_role csr ON csr.id = csg.teamId
+        LEFT JOIN cm_club_report ccre ON  ccre.Id= ccr.reportID
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN shop sh ON sh.shopID = p.shopID
+        <where>
+            <if test="remarks != null and remarks !=''">
+                AND ccr.remarks LIKE concat('%',#{remarks},'%')
+            </if>
+            <if test="clubName !=null and clubName !=''">
+                AND ccr.clubId is not null
+                AND c.Name like concat('%',#{clubName},'%')
+            </if>
+            <if test="leaderId != null">
+                and csr.leaderId = #{leaderId}
+            </if>
+            <if test="serviceProviderId != null">
+                and ccr.serviceProviderId = #{serviceProviderId}
+            </if>
+            <if test="consult != null">
+                and ccr.consultType like concat('%',#{consult},'%')
+            </if>
+            <if test="todayTime != null and todayTime != ''">
+                and ccr.addTime like concat('%', #{todayTime}, '%')
+            </if>
+            <if test="startAddTime != '' and startAddTime != null">
+                and ccr.addTime <![CDATA[  >  ]]> #{startAddTime}
+            </if>
+            <if test="endAddTime != '' and endAddTime != null">
+                and ccr.addTime <![CDATA[  <  ]]> #{endAddTime}
+            </if>
+            <if test="newDeal !=null">
+                and c.newDeal=#{newDeal}
+            </if>
+            <if test="reportId !=null">
+                and ccr.reportID=#{reportId}
+            </if>
+            <if test="isRegister != null">
+                <if test="isRegister == 1">
+                    and ccr.clubId is null
+                </if>
+                <if test="isRegister == 2">
+                    and ccr.clubId is not null
+                </if>
+            </if>
+            and ccr.remarks IS NOT NULL
+        </where>
+        ORDER BY ADDTIME DESC
+    </select>
+
+    <update id="updateClubRemarks">
+        UPDATE cm_club_remarks
+        SET reportID=null
+        WHERE id = #{remarksId}
+    </update>
+
+    <update id="updateVisitorRemarks">
+        UPDATE cm_visitor_remarks
+        SET reportID=null
+        WHERE id = #{remarksId}
+    </update>
+
+    <select id="getProduct" resultType="com.caimei365.manager.entity.caimei.product.Product">
+        select p.*, s.name as shopName from product p
+        left join shop s on s.shopId = p.shopId
+        where p.productId = #{productId}
+    </select>
+
+    <select id="getReportById" resultType="com.caimei365.manager.entity.caimei.cmUser.CmReport">
+        SELECT ccr.Id as reportId, p.mainImage AS mainImage,p.`name` AS productName,c.`name` AS clubName,
+        ccr.reportName AS reportName, ccr.reportText AS reportText, ccr.addTime AS ADDTIME,
+        ccr.status AS STATUS, ccr.auditName AS auditName, ccr.auditTime AS auditTime, c.newDeal, ccr.auditText
+        FROM cm_club_report ccr
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN club c ON c.clubID = ccr.clubID
+        where  ccr.id = #{reportId}
+        limit 1
+    </select>
+
+    <select id="findClassName" resultType="java.lang.String">
+        select className
+        from cm_consulttype
+        where id = #{id}
+    </select>
+
+    <select id="getRemarksImageList" resultType="java.lang.String">
+        select imageUrl
+        from cm_club_remarks_file
+        where remarksId = #{remarksId}
+          and fileType = 1
+    </select>
+
+    <select id="getRemarksFileList" resultType="com.caimei365.manager.entity.caimei.cmUser.RemarksFileVo">
+        select fileName, ossName
+        from cm_club_remarks_file
+        where remarksId = #{remarksId}
+          and fileType = 2
+    </select>
+
+    <select id="getReportList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmReport">
+        SELECT ccr.Id as reportId, p.mainImage AS mainImage,p.`name` AS productName,c.`name` AS clubName,
+               ccr.reportName AS reportName, ccr.reportText AS reportText, ccr.addTime AS ADDTIME,
+               ccr.status AS STATUS, ccr.auditName AS auditName, ccr.auditTime AS auditTime, c.newDeal, ccr.auditText
+        FROM cm_club_report ccr
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN club c ON c.clubID = ccr.clubID
+        <where>
+            <if test="reportId!=null and reportId!=''">
+                AND ccr.id=#{reportId}
+            </if>
+            <if test="productName!=null and productName!=''">
+                AND p.name LIKE concat('%',#{productName},'%')
+            </if>
+            <if test="clubId != null">
+                c.clubID = #{clubId}
+            </if>
+            <if test="clubName!=null and clubName!=''">
+                AND c.name LIKE concat('%',#{clubName},'%')
+            </if>
+            <if test="reportName!=null and reportName!=''">
+                AND ccr.reportName LIKE concat('%',#{reportName},'%')
+            </if>
+            <if test="status != null">
+                AND ccr.status = #{status}
+            </if>
+            <if test="newDeal != null">
+                AND c.newDeal =#{newDeal}
+            </if>
+            <if test="startAddTime != null and startAddTime != ''">
+                and ccr.addTime <![CDATA[  >  ]]> #{startAddTime}
+            </if>
+            <if test="endAddTime != null and endAddTime != ''">
+                and ccr.addTime <![CDATA[  <  ]]> #{endAddTime}
+            </if>
+        </where>
+        ORDER BY ccr.`addTime` DESC
+    </select>
+
+    <select id="clubRemarksConut" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM cm_club_remarks
+        WHERE reportID = #{reportId}
+    </select>
+
+    <select id="visitorRemarksConut" resultType="java.lang.Integer">
+        SELECT COUNT(*)
+        FROM cm_visitor_remarks
+        WHERE reportID = #{reportId}
+    </select>
+
+    <delete id="deleteClubRemarks">
+        DELETE
+        FROM cm_club_report
+        WHERE id = #{reportId}
+    </delete>
+
+    <update id="updateAuditRemarks">
+        UPDATE cm_club_report
+        SET status  =   #{status},
+            auditName   =   #{auditName},
+            auditText   =   #{auditText},
+            auditTime   =   now()
+        WHERE id = #{reportId}
+    </update>
+
+    <select id="getConsultList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmConsulttype">
+        SELECT
+        a.id AS "id",
+        a.className AS "className",
+        a.status AS "status",
+        a.sortNumber AS "sortNumber",
+        a.createdTime AS "createdTime",
+        a.delflag AS "delflag"
+        FROM cm_consulttype a
+        <where>
+            delFlag = 0
+            <if test="status != null">
+                and a.status = #{status}
+            </if>
+            <if test="className != null and className != ''">
+                AND a.className LIKE concat('%',#{className},'%')
+            </if>
+        </where>
+        order by sortnumber ASC
+    </select>
+
+    <insert id="insertConsult" parameterType="com.caimei365.manager.entity.caimei.cmUser.CmConsulttype"  keyProperty="id" useGeneratedKeys="true">
+        INSERT INTO cm_consulttype(
+            className,
+            status,
+            sortNumber,
+            createdTime,
+            delflag
+        ) VALUES (
+                     #{className},
+                     1,
+                     #{sortNumber},
+                     now(),
+                     0
+                 )
+    </insert>
+
+    <update id="updateConsult">
+        UPDATE cm_consulttype SET
+        <if test="className != null and className != '' ">
+            className = #{className},
+        </if>
+        <if test="status != null and status != ''">
+            status = #{status},
+        </if>
+        <if test="sortNumber != null">
+            sortNumber = #{sortNumber},
+        </if>
+        <if test="createdTime != null">
+            createdTime = #{createdTime},
+        </if>
+        delflag = 0
+        WHERE id = #{id}
+    </update>
+
+    <update id="deleteConsult">
+        update cm_consulttype
+        set delflag = 1
+        WHERE id = #{id}
+    </update>
+
+    <select id="getVisitRemarkList" resultType="com.caimei365.manager.entity.caimei.cmUser.VisitRemarkVo">
+        SELECT cvr.id as remarksId,cvr.questionManId,cvr.serviceProviderId,cvr.remarks,cvr.addTime,
+               cvr.questionMan,cvr.clubId,cvr.concactTime,c.name as clubName,s.linkMan as serviceName
+        FROM cm_visitor_remarks cvr
+        LEFT JOIN serviceprovider s ON s.serviceProviderID = cvr.serviceProviderId
+        LEFT JOIN club c ON c.clubId= cvr.clubId
+        <where>
+            <if test="serviceProviderId != null and serviceProviderId != ''">
+                AND cvr.serviceProviderId = #{serviceProviderId}
+            </if>
+            <if test="concat == 1">
+                and cvr.clubId is not null
+            </if>
+            <if test="concat == 2">
+                and cvr.clubId is null
+            </if>
+            <if test="questionMan != null and questionMan != ''">
+                and cvr.questionMan LIKE concat('%',#{questionMan},'%')
+            </if>
+        </where>
+        GROUP BY cvr.questionManId
+        ORDER BY cvr.addTime DESC
+    </select>
+
+    <select id="getClubRemarksList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmClubRemarks">
+        SELECT DISTINCT
+        ccr.id AS remarksId, ccr.remarks, s.linkman AS spName, ccr.addTime, ccr.questionMan,
+        csr.leaderId AS leaderId, IFNULL(ccr.consultType,'') AS consult, c.Name AS clubName,
+        ccr.clubType, ccr.pinceSensitve, ccr.satisfied, ccr.followup, ccr.extra,
+        ccr.communicationSituation, ccr.communicationMethods, ccr.customerSource, ccr.customerGender, ccr.groupAddition,
+        ccr.customerAge, ccr.trendsKeyword, ccr.stateKeyword, c.newDeal, c.contractMobile, '1' as type,
+        (SELECT linkMan FROM serviceprovider s WHERE s.serviceProviderID = ccr.serviceProviderId) AS serviceName,
+        (SELECT NAME FROM serviceprovider s WHERE s.serviceProviderID= csr.leaderId) AS leaderName,
+        (SELECT mainImage FROM product p WHERE p.productID= ccre.productID) AS productMainImage,
+        (SELECT NAME FROM product p WHERE p.productID= ccre.productID) AS proName,
+        ccre.reportText AS reportText, ccre.status AS reportStatus, ccre.auditName AS auditName, ccre.auditTime AS auditTime,
+        p.mainImage AS mainImage, ccr.productId as productId, p.name AS productName, sh.name AS shopName, ccr.reportID
+        FROM cm_club_remarks ccr
+        LEFT JOIN serviceprovider s ON ccr.createServiceProviderId = s.serviceProviderID
+        LEFT JOIN club c ON c.clubId=ccr.clubId
+        LEFT JOIN cm_serviceTeam_group csg ON ccr.createServiceProviderId = csg.serviceId
+        LEFT JOIN cm_serviceTeam_role csr ON csr.id = csg.teamId
+        LEFT JOIN cm_club_report ccre ON ccre.Id= ccr.reportID
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN shop sh ON sh.shopID = p.shopID
+        <where>
+            s.validFlag = 1 and s.serviceProviderID not in (1371, 1359, 1342)
+            <if test="questionManId != null and questionManId != ''">
+                AND ccr.clubId is null
+            </if>
+            <if test="questionManId == null or questionManId == ''">
+                <if test="clubId != null">
+                    and ccr.clubId = #{clubId}
+                </if>
+            </if>
+            <if test="remarks != null and remarks !=''">
+                AND ccr.remarks LIKE concat('%',#{remarks},'%')
+            </if>
+            <if test="consult != null">
+                and ccr.consultType like concat('%',#{consult},'%')
+            </if>
+            <if test="startAddTime != '' and startAddTime != null">
+                and ccr.addTime <![CDATA[  >  ]]> #{startAddTime}
+            </if>
+            <if test="endAddTime != '' and endAddTime != null">
+                and ccr.addTime <![CDATA[  <  ]]> #{endAddTime}
+            </if>
+        </where>
+
+        union
+
+        SELECT DISTINCT
+        ccr.id AS remarksId, ccr.remarks, s.name AS spName, ccr.addTime, ccr.questionMan,
+        csr.leaderId AS leaderId, IFNULL(ccr.consultType,'') AS consult, c.Name AS clubName,
+        ccr.clubType, ccr.pinceSensitve, ccr.satisfied, ccr.followup, ccr.extra,
+        ccr.communicationSituation AS communicationSituation, ccr.communicationMethods AS communicationMethods, ccr.customerSource AS customerSource,
+        ccr.customerGender AS customerGender, ccr.groupAddition AS groupAddition, ccr.customerAge AS customerAge,
+        ccr.trendsKeyword AS trendsKeyword, ccr.stateKeyword AS stateKeyword, c.newDeal, c.contractMobile, '2' as type,
+        (SELECT linkMan FROM serviceprovider s WHERE s.serviceProviderID = ccr.serviceProviderId) AS serviceName,
+        (SELECT NAME FROM serviceprovider s WHERE s.serviceProviderID = csr.leaderId) AS leaderName,
+        (SELECT mainImage FROM product p WHERE p.productID= ccre.productID) AS productMainImage,
+        (SELECT NAME FROM product p WHERE p.productID= ccre.productID) AS proName,
+        ccre.reportText AS reportText, ccre.status AS reportStatus, ccre.auditName AS auditName, ccre.auditTime AS auditTime,
+        p.mainImage AS mainImage, ccr.productId as productId, p.name AS productName, sh.name AS shopName, ccr.reportID
+        FROM cm_visitor_remarks ccr
+        LEFT JOIN serviceprovider s ON ccr.serviceProviderId = s.serviceProviderID
+        LEFT JOIN club c ON c.clubId = ccr.clubId
+        LEFT JOIN cm_serviceTeam_group csg ON ccr.serviceProviderId = csg.serviceId
+        LEFT JOIN cm_serviceTeam_role csr ON csr.id = csg.teamId
+        LEFT JOIN cm_club_report ccre ON  ccre.Id= ccr.reportID
+        LEFT JOIN product p ON p.productID = ccr.productID
+        LEFT JOIN shop sh ON sh.shopID = p.shopID
+        <where>
+            <if test="questionManId != null and questionManId != ''">
+                AND ccr.questionManId LIKE concat('%',#{questionManId},'%')
+            </if>
+            <if test="clubId != null">
+                and ccr.clubId = #{clubId}
+            </if>
+            <if test="remarks != null and remarks !=''">
+                AND ccr.remarks LIKE concat('%',#{remarks},'%')
+            </if>
+            <if test="consult != null">
+                and ccr.consultType like concat('%',#{consult},'%')
+            </if>
+            <if test="startAddTime != '' and startAddTime != null">
+                and ccr.addTime <![CDATA[  >  ]]> #{startAddTime}
+            </if>
+            <if test="endAddTime != '' and endAddTime != null">
+                and ccr.addTime <![CDATA[  <  ]]> #{endAddTime}
+            </if>
+        </where>
+        ORDER BY ADDTIME DESC
+    </select>
+
+    <select id="getVisitorImageList" resultType="java.lang.String">
+        select imageUrl
+        from cm_visitor_remarks_file
+        where remarksId = #{remarksId}
+          and fileType = 1
+    </select>
+
+    <select id="getVisitorFileList" resultType="com.caimei365.manager.entity.caimei.cmUser.RemarksFileVo">
+        select fileName, ossName
+        from cm_visitor_remarks_file
+        where remarksId = #{remarksId}
+          and fileType = 2
+    </select>
+
+</mapper>

+ 371 - 0
src/main/resources/mapper/user/CustomerServiceDao.xml

@@ -0,0 +1,371 @@
+<?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.CustomerServiceDao">
+
+    <select id="getCustomerShopList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopStatistics">
+        SELECT
+            DISTINCT css.id as id,
+                     css.shopID AS shopId,
+                     s.name as shopName,
+                     s.linkMan,
+                     s.contractMobile AS mobile,
+                     s.status AS shopStatus,
+                     css.status,
+                     css.addTime
+        FROM cm_shop_statistics css
+                 LEFT JOIN shop s ON css.shopId = s.shopId
+        <where>
+            css.delFlag = 0
+            <if test="shopName != null and shopName != ''">
+                and s.name like concat('%',#{shopName},'%')
+            </if>
+            <if test="status != null">
+                and css.status = #{status}
+            </if>
+        </where>
+        order by css.addTime desc, s.addTime desc
+    </select>
+
+    <select id="getCustomerShopId" resultType="java.lang.Integer">
+        SELECT shopId FROM cm_shop_statistics where delFlag = 0
+    </select>
+
+    <select id="getShopList" resultType="com.caimei365.manager.entity.caimei.CmShop">
+        select * from shop
+        where status = 90 and shopType = 1
+        <if test="shopName != null and shopName != ''">
+            and name like concat('%',#{shopName},'%')
+        </if>
+        <if test="shopId != null">
+            and shopId = #{shopId}
+        </if>
+        order by addTime desc
+    </select>
+
+    <insert id="insertCustomerShop">
+        insert into cm_shop_statistics (shopId, status, addTime, delFlag)
+        values (#{shopId}, #{status}, now(), #{delFlag})
+    </insert>
+
+    <update id="updateCustomerShop">
+        update cm_shop_statistics
+        set status = #{status}
+        where id = #{id}
+    </update>
+    <select id="getCmInformationList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmRoosInformation">
+        SELECT id,
+               IP,
+               shopId,
+               followUpStatus,
+               consultName,
+               consultMobile,
+               isClick,
+               createTime
+        FROM cm_roos_information
+        <where>
+          shopId = #{shopId}
+          AND consultName IS NOT NULL
+          AND consultMobile IS NOT NULL
+            <if test="consultName != null and consultName != ''">
+                and consultName like concat('%',#{consultName},'%')
+            </if>
+            <if test="consultMobile != null and consultMobile != ''">
+                and consultMobile like concat('%',#{consultMobile},'%')
+            </if>
+            <if test="followUpStatus != null">
+                and followUpStatus = #{followUpStatus}
+            </if>
+        </where>
+        order by createTime desc
+    </select>
+
+    <select id="updateInformation">
+        update cm_roos_information
+        set followUpStatus = #{followUpStatus}
+        where id = #{id}
+    </select>
+
+    <select id="getShopInfoList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopInfo">
+        SELECT
+            csi.id,
+            csi.infoId,
+            i.guidanceImage,
+            i.title,
+            i.pubdate,
+            csi.status,
+            csi.addTime
+        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
+            <if test="infoId != null">
+                and csi.infoId = #{infoId}
+            </if>
+            <if test="title != null and title != ''">
+                and i.title like concat('%',#{title},'%')
+            </if>
+            <if test="status != null">
+                and csi.status = #{status}
+            </if>
+        </where>
+        order by csi.addTime desc, i.pubdate desc
+    </select>
+
+    <select id="getShopInfoId" resultType="java.lang.Integer">
+        select infoId from cm_shop_info where delFlag = 0
+    </select>
+
+    <select id="getInfoList" resultType="com.caimei365.manager.entity.caimei.cmUser.Info">
+        select * from info
+        where delFlag = 0 and onlineStatus = 2
+        <if test="id != null">
+            and id = #{id}
+        </if>
+        <if test="title != null and title != ''">
+            and title like concat('%',#{title},'%')
+        </if>
+        order by pubdate desc
+    </select>
+
+    <insert id="insertShopInfo">
+        insert into cm_shop_info (shopId, infoId, status, addTime, delFlag)
+        values (#{shopId}, #{infoId}, #{status}, now(), #{delFlag})
+    </insert>
+
+    <update id="updateShopInfoStatus">
+        update cm_shop_info
+        set status = #{status}
+        where id = #{id}
+    </update>
+
+    <update id="delShopInfo">
+        update cm_shop_info
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
+    <select id="getShopKeyword" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopKeyword">
+        SELECT
+            csk.id,
+            csk.shopId,
+            cusf.keyword,
+            cusf.frequency as number,
+            cusf.searchTime,
+            csk.status,
+            csk.addTime
+        FROM cm_shop_keyword csk
+                 LEFT JOIN cm_user_search_frequency cusf ON cusf.id = csk.searchId
+        <where>
+            csk.shopId = #{shopId}
+            and csk.delFlag = 0 and cusf.delStatus = 1
+            <if test="keyword != null and keyword != ''">
+                and cusf.keyword like concat('%',#{keyword},'%')
+            </if>
+            <if test="status != null">
+                and csk.status = #{status}
+            </if>
+        </where>
+        order by csk.addTime desc, (SELECT COUNT(recordID) FROM cm_behavior_record WHERE pageType = 8 AND pageLabel = cusf.keyword) desc
+    </select>
+
+    <select id="getShopKeywordId" resultType="java.lang.Integer">
+        select searchId from cm_shop_keyword where delFlag = 0
+    </select>
+
+    <select id="getSearchFrequencyList" resultType="com.caimei365.manager.entity.caimei.cmUser.CmUserSearchFrequency">
+        select * from cm_user_search_frequency
+        where delStatus = 1 and trueStatus = 1
+        <if test="keyword != null and keyword != ''">
+            and keyword like concat('%',#{keyword},'%')
+        </if>
+        order by searchTime desc
+    </select>
+
+    <insert id="insertShopKeyword">
+        insert into cm_shop_keyword (shopId, searchId, status, addTime, delFlag)
+        values (#{shopId}, #{searchId}, #{status}, now(), #{delFlag})
+    </insert>
+
+    <update id="updateShopKeywordStatus">
+        update cm_shop_keyword
+        set status = #{status}
+        where id = #{id}
+    </update>
+
+    <update id="delShopKeyword">
+        update cm_shop_keyword
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
+    <select id="getShopPopUp" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopPopUp">
+        select
+        id,
+        shopId,
+        image,
+        guidingOne,
+        guidingTwo,
+        addTime
+        from cm_shop_popUp
+        where shopId = #{shopId}
+    </select>
+
+    <insert id="insertShopPopUp">
+        insert into cm_shop_popUp(shopId, image, guidingOne, guidingTwo, addTime)
+        values (#{shopId}, #{image}, #{guidingOne}, #{guidingTwo}, now())
+    </insert>
+
+    <update id="updateShopPopUp">
+        update cm_shop_popUp
+        set image = #{image},
+            guidingOne = #{guidingOne},
+            guidingTwo = #{guidingTwo}
+        where id = #{id}
+    </update>
+
+    <select id="getShopAdvertisingImage" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopAdvertisingImage">
+        select
+            csa.id,
+            csa.shopId,
+            s.name as shopName,
+            csa.pcImage,
+            csa.appImage,
+            csa.jumpLink,
+            csa.sort,
+            csa.addTime,
+            csa.status,
+            csa.delFlag
+            from cm_shop_advertisingImage csa
+            left join shop s on s.shopId = csa.shopId
+            <where>
+                csa.delFlag = 0
+                <if test="shopName != null and shopName != ''">
+                    and s.name like concat('%',#{shopName},'%')
+                </if>
+                <if test="status != null">
+                    and csa.status = #{status}
+                </if>
+            </where>
+            order by csa.sort asc, csa.addTime desc
+    </select>
+
+    <select id="getShopAdvertisingImageById" resultType="com.caimei365.manager.entity.caimei.cmUser.CmShopAdvertisingImage">
+        select id, shopId, pcImage, appImage, jumpLink, sort, addTime, status, delFlag
+        from cm_shop_advertisingImage
+        where id = #{id}
+    </select>
+
+    <insert id="insertShopAdvertisingImage">
+        insert into cm_shop_advertisingImage (shopId, pcImage, appImage, jumpLink, sort, addTime, status, delFlag)
+        values (#{shopId}, #{pcImage}, #{appImage}, #{jumpLink}, #{sort}, now(), #{status}, #{delFlag})
+    </insert>
+
+    <update id="updateShopAdvertisingImage">
+        update cm_shop_advertisingImage
+        set shopId  = #{shopId},
+            pcImage = #{pcImage},
+            appImage = #{appImage},
+            jumpLink = #{jumpLink},
+            status = #{status}
+        where id = #{id}
+    </update>
+
+    <update id="updateShopAdvertisingImageSort">
+        update cm_shop_advertisingImage
+        set sort = #{sort}
+        where id = #{id}
+    </update>
+
+    <update id="updateShopAdvertisingImageStatus">
+        update cm_shop_advertisingImage
+        set status = #{status}
+        where id = #{id}
+    </update>
+
+    <update id="delShopAdvertisingImage">
+        update cm_shop_advertisingImage
+        set delFlag = 1
+        where id = #{id}
+    </update>
+
+    <select id="getPageShop" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShop">
+        SELECT
+            cps.id,
+            cps.shopId,
+            s.name AS shopName,
+            cps.shopLink,
+            IFNULL(SUM(cps.accessNumber), 0) AS accessNumber,
+            IFNULL(SUM(cps.accessDuration), 0) AS accessDuration,
+            IFNULL((IFNULL(SUM(cps.accessDuration), 0) / IFNULL(SUM(cps.accessNumber), 0)), 0) AS averageDuration
+        FROM cm_page_shop cps
+                 LEFT JOIN shop s ON s.shopId = cps.shopId
+        <where>
+            cps.shopId = #{shopId}
+            <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
+                and cps.accessDate BETWEEN #{startTime} and #{endTime}
+            </if>
+        </where>
+        group by cps.shopId
+    </select>
+
+    <select id="getPageShopProduct" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShopProduct">
+        SELECT
+            cpsp.id,
+            cpsp.shopId,
+            cpsp.productId,
+            p.name as productName,
+            p.mainImage,
+            copi.validFlag,
+            cpsp.link,
+            IFNULL(SUM(cpsp.accessNumber), 0) AS accessNumber,
+            IFNULL(SUM(cpsp.accessDuration), 0) AS accessDuration,
+            IFNULL((IFNULL(SUM(cpsp.accessDuration), 0) / IFNULL(SUM(cpsp.accessNumber), 0)), 0) AS averageDuration
+        FROM cm_page_shop_product cpsp
+                 LEFT JOIN product p ON p.productId = cpsp.productId
+                 LEFT JOIN cm_organize_product_info copi ON copi.productId = cpsp.productId
+        WHERE cpsp.shopId = #{shopId} and copi.organizeId = 0
+        <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
+            and cpsp.accessDate BETWEEN #{startTime} and #{endTime}
+        </if>
+        group by cpsp.productId
+    </select>
+
+    <select id="getPageShopInfo" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShopInfo">
+        SELECT
+            cpsi.id,
+            cpsi.shopId,
+            cpsi.infoId,
+            i.guidanceImage,
+            i.title,
+            i.onlineStatus,
+            cpsi.link,
+            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
+        WHERE cpsi.shopId = #{shopId}
+        <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
+            and cpsi.accessDate BETWEEN #{startTime} and #{endTime}
+        </if>
+        group by cpsi.infoId
+    </select>
+
+    <select id="getPageShopKeyword" resultType="com.caimei365.manager.entity.caimei.cmUser.CmPageShopKeyword">
+        SELECT
+            cpsk.id,
+            cpsk.shopId,
+            cusf.keyword,
+            cpsk.link,
+            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
+        WHERE cpsk.shopId = #{shopId}
+        <if test="startTime != null and startTime != '' and endTime != null and endTime != ''">
+            and cpsk.accessDate BETWEEN #{startTime} and #{endTime}
+        </if>
+        group by cpsk.searchId
+    </select>
+</mapper>