Quellcode durchsuchen

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

huangzhiguo vor 2 Jahren
Ursprung
Commit
029549efdb
27 geänderte Dateien mit 2155 neuen und 20 gelöschten Zeilen
  1. 8 0
      src/main/java/com/caimei/modules/archive/entity/CmProductArchive.java
  2. 23 1
      src/main/java/com/caimei/modules/archive/web/CmProductArchiveController.java
  3. 18 0
      src/main/java/com/caimei/modules/baike/web/CmBaikeProductController.java
  4. 8 1
      src/main/java/com/caimei/modules/info/entity/InfoAd.java
  5. 13 0
      src/main/java/com/caimei/modules/info/web/InfoController.java
  6. 34 0
      src/main/java/com/caimei/modules/product/dao/KeywordFrequencyDao.java
  7. 60 0
      src/main/java/com/caimei/modules/product/entity/SearchFrequency.java
  8. 49 0
      src/main/java/com/caimei/modules/product/entity/SearchFrequencyVo.java
  9. 167 0
      src/main/java/com/caimei/modules/product/service/KeywordFrequencyService.java
  10. 294 0
      src/main/java/com/caimei/modules/product/service/RedisServiceCom.java
  11. 318 0
      src/main/java/com/caimei/modules/product/web/KeywordFrequencyController.java
  12. 13 1
      src/main/java/com/caimei/modules/product/web/ProductNewController.java
  13. 10 10
      src/main/resources/config/beta/caimei.properties
  14. BIN
      src/main/resources/export/keyword.xls
  15. BIN
      src/main/resources/export/thesaurus.xls
  16. 6 3
      src/main/resources/mappings/modules/archive/CmProductArchiveMapper.xml
  17. 1 0
      src/main/resources/mappings/modules/info/InfoAdMapper.xml
  18. 160 0
      src/main/resources/mappings/modules/product/SearchFrequencyMapper.xml
  19. 28 1
      src/main/webapp/WEB-INF/views/modules/archive/cmProductArchiveForm.jsp
  20. 22 1
      src/main/webapp/WEB-INF/views/modules/baikePage/cmBaikeProductForm.jsp
  21. 4 0
      src/main/webapp/WEB-INF/views/modules/info/infoAdList.jsp
  22. 22 1
      src/main/webapp/WEB-INF/views/modules/info/infoForm.jsp
  23. 22 1
      src/main/webapp/WEB-INF/views/modules/product-new/productEdit.jsp
  24. 321 0
      src/main/webapp/WEB-INF/views/modules/product/keywordFrequency.jsp
  25. 275 0
      src/main/webapp/WEB-INF/views/modules/product/keywordThesaurus.jsp
  26. 46 0
      src/main/webapp/WEB-INF/views/modules/product/upkeyword.jsp
  27. 233 0
      src/main/webapp/static/auto-input.js

+ 8 - 0
src/main/java/com/caimei/modules/archive/entity/CmProductArchive.java

@@ -22,7 +22,15 @@ public class CmProductArchive extends DataEntity<CmProductArchive> {
 	private Integer productType;		// 商品属性:1产品,2仪器
 	private Integer productClassify;		// 商品分类:1生美,2医美
 	private Date addTime;		// 添加时间
+    private String seoKeyword;  //关键词
 
+	public void setSeoKeyword(String seoKeyword) {
+		this.seoKeyword = seoKeyword;
+	}
+
+	public String getSeoKeyword() {
+		return seoKeyword;
+	}
 
 	private Integer existProductType;	//商品库商品是否有设置商品属性:0没有,1有
 	

+ 23 - 1
src/main/java/com/caimei/modules/archive/web/CmProductArchiveController.java

@@ -3,7 +3,11 @@ package com.caimei.modules.archive.web;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.alibaba.fastjson.JSONArray;
+import com.caimei.modules.product.dao.KeywordFrequencyDao;
 import com.caimei.modules.product.entity.Product;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
+import com.caimei.redis.RedisService;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
@@ -20,6 +24,9 @@ import com.thinkgem.jeesite.common.utils.StringUtils;
 import com.caimei.modules.archive.entity.CmProductArchive;
 import com.caimei.modules.archive.service.CmProductArchiveService;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * 商品资料Controller
  * @author Aslee
@@ -31,7 +38,13 @@ public class CmProductArchiveController extends BaseController {
 
 	@Autowired
 	private CmProductArchiveService cmProductArchiveService;
-	
+
+	@Autowired
+	private RedisService redisService;
+
+	@Autowired
+	private KeywordFrequencyDao keywordFrequencyDao;
+
 	@ModelAttribute
 	public CmProductArchive get(@RequestParam(required=false) String id) {
 		CmProductArchive entity = null;
@@ -53,7 +66,16 @@ public class CmProductArchiveController extends BaseController {
 
 	@RequestMapping(value = "form")
 	public String form(CmProductArchive cmProductArchive, Model model) {
+		//先从reids中获取keyword值,不存在时在查询数据库
+		List<SearchFrequencyVo> searchFrequencyVos=new ArrayList<>();
+		if(redisService.getExpireTime("keyword")>0){
+			searchFrequencyVos= JSONArray.parseArray(redisService.get("keyword").toString(),SearchFrequencyVo.class);
+		}else{
+			searchFrequencyVos = keywordFrequencyDao.getKeywordList();
+		}
 		model.addAttribute("cmProductArchive", cmProductArchive);
+		model.addAttribute("SearchFrequencyVo",searchFrequencyVos);
+
 		return "modules/archive/cmProductArchiveForm";
 	}
 

+ 18 - 0
src/main/java/com/caimei/modules/baike/web/CmBaikeProductController.java

@@ -4,6 +4,7 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.alibaba.fastjson.JSONArray;
 import com.caimei.modules.baike.dao.CmBaikeProductDao;
 import com.caimei.modules.baike.dao.CmBaikeProductRecommendDao;
 import com.caimei.modules.baike.dao.CmBaikeTypeDao;
@@ -12,9 +13,12 @@ import com.caimei.modules.baike.service.CmBaikeTypeService;
 import com.caimei.modules.info.dao.InfoDao;
 import com.caimei.modules.opensearch.GenerateUtils;
 import com.caimei.modules.oss.utils.OSSUtils;
+import com.caimei.modules.product.dao.KeywordFrequencyDao;
 import com.caimei.modules.product.entity.CmProductRecommend;
 import com.caimei.modules.product.entity.Product;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
 import com.caimei.modules.user.entity.NewCmShop;
+import com.caimei.redis.RedisService;
 import com.caimei.utils.AppUtils;
 import com.google.common.collect.Maps;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -65,6 +69,12 @@ public class CmBaikeProductController extends BaseController {
 
 	@Resource
 	private InfoDao infoDao;
+
+	@Autowired
+	private RedisService redisService;
+
+	@Autowired
+	private KeywordFrequencyDao keywordFrequencyDao;
 	
 	@ModelAttribute
 	public CmBaikeProduct get(@RequestParam(required=false) String id) {
@@ -132,10 +142,18 @@ public class CmBaikeProductController extends BaseController {
 		cmBaikeProduct.setShopList(shopList);
 		// 敏感词
 		String sensitiveWords = infoDao.getSensitiveWords(4);
+		//先从reids中获取keyword值,不存在时在查询数据库
+		List<SearchFrequencyVo> searchFrequencyVos=new ArrayList<>();
+		if(redisService.getExpireTime("keyword")>0){
+			searchFrequencyVos= JSONArray.parseArray(redisService.get("keyword").toString(),SearchFrequencyVo.class);
+		}else{
+			searchFrequencyVos = keywordFrequencyDao.getKeywordList();
+		}
 		model.addAttribute("cmBaikeProduct", cmBaikeProduct);
 		model.addAttribute("typeList", typeList);
 		model.addAttribute("commodityType", commodityType);
 		model.addAttribute("sensitiveWords", sensitiveWords);
+		model.addAttribute("SearchFrequencyVo",searchFrequencyVos);
 		return "modules/baikePage/cmBaikeProductForm";
 	}
 

+ 8 - 1
src/main/java/com/caimei/modules/info/entity/InfoAd.java

@@ -20,7 +20,14 @@ public class InfoAd extends DataEntity<InfoAd> {
 	private String guidanceImage;		// 引导图
 	private Long clickRate;		// 点击量
 	private String enabledStatus;		// 启用/禁用状态
-	
+//	private String soft;      //排序值
+//	public void setSoft(String soft) {
+//		this.soft = soft;
+//	}
+//
+//	public String getSoft() {
+//		return soft;
+//	}
 	public InfoAd() {
 		super();
 	}

+ 13 - 0
src/main/java/com/caimei/modules/info/web/InfoController.java

@@ -6,11 +6,14 @@ import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import com.alibaba.fastjson.JSONArray;
 import com.caimei.modules.info.dao.InfoDao;
 import com.caimei.modules.info.entity.CmInfoDocSyn;
 import com.caimei.modules.info.service.CmInfoDocSynService;
 import com.caimei.modules.opensearch.GenerateUtils;
 import com.caimei.modules.opensearch.CoreServiceUitls;
+import com.caimei.modules.product.dao.KeywordFrequencyDao;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
 import com.caimei.redis.RedisService;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
@@ -58,6 +61,8 @@ public class InfoController extends BaseController {
     private GenerateUtils generateUtils;
 	@Autowired
 	private InfoDao infoDao;
+	@Autowired
+	private KeywordFrequencyDao keywordFrequencyDao;
 	@ModelAttribute
 	public Info get(@RequestParam(required=false) String id) {
 		Info entity = null;
@@ -137,12 +142,20 @@ public class InfoController extends BaseController {
 		}
 		InfoType infoType = new InfoType();
 		List<InfoType> typeList = infoTypeService.findList(infoType);
+		//先从reids中获取keyword值,不存在时在查询数据库
+		List<SearchFrequencyVo> searchFrequencyVos=new ArrayList<>();
+		if(redisService.getExpireTime("keyword")>0){
+			searchFrequencyVos= JSONArray.parseArray(redisService.get("keyword").toString(),SearchFrequencyVo.class);
+		}else{
+			searchFrequencyVos = keywordFrequencyDao.getKeywordList();
+		}
 		// 敏感词
 		String sensitiveWords = infoDao.getSensitiveWords(3);
 		model.addAttribute("typeList", typeList);
 		model.addAttribute("info", info);
 		model.addAttribute("ltype", ltype);
 		model.addAttribute("sensitiveWords", sensitiveWords);
+		model.addAttribute("SearchFrequencyVo", searchFrequencyVos);
 		return "modules/info/infoForm";
 	}
 

+ 34 - 0
src/main/java/com/caimei/modules/product/dao/KeywordFrequencyDao.java

@@ -0,0 +1,34 @@
+package com.caimei.modules.product.dao;
+
+import com.caimei.modules.product.entity.SearchFrequency;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
+import com.thinkgem.jeesite.common.persistence.CrudDao;
+import com.thinkgem.jeesite.common.persistence.annotation.MyBatisDao;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@MyBatisDao
+public interface KeywordFrequencyDao extends CrudDao<SearchFrequency> {
+
+    List<SearchFrequency> findList(SearchFrequency searchFrequency);
+
+    List<SearchFrequency> getSearchFrom(Integer trueStatus);
+    void addKeyWordList(@Param("idList") int[] idList);
+
+    List<SearchFrequency> getvalueListByIds(@Param("idList") int[] idList);
+
+    void delKeyWordById(@Param("id") Integer id,@Param("delStatus") Integer delStatus);
+
+    int insert(SearchFrequency searchFrequency);
+
+    int update(SearchFrequency searchFrequency);
+    List<SearchFrequency> getInfoByIdList(@Param("idList") int[] idList);
+
+    List<SearchFrequencyVo> getKeywordList();
+
+    List<SearchFrequencyVo> getvalueList(@Param("keyword") String keyword);
+    SearchFrequency getKeyById(Integer id);
+
+    List<String> verificationKeword(@Param("keyword")String keyword);
+}

+ 60 - 0
src/main/java/com/caimei/modules/product/entity/SearchFrequency.java

@@ -0,0 +1,60 @@
+package com.caimei.modules.product.entity;
+
+import com.thinkgem.jeesite.common.persistence.DataEntity;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.sql.Timestamp;
+
+@Data
+public class SearchFrequency extends DataEntity<SearchFrequency> {
+       private Integer keyId ;
+    /**
+     * 数据来源(1:首页;2:信息中心)
+     */
+    private Integer fromSearch   ;
+    /**
+     * 接口路径
+     */
+    private String  path;
+    /**
+     * 关键词
+     */
+    private String  keyword ;
+    /**
+     * 关键词出现次数
+     */
+    private Integer  frequency ;
+    /**
+     * 搜索时间
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Timestamp searchTime ;
+    /**
+     * 0:未加入关键词库;1:已加入关键词库
+     */
+    private Integer trueStatus;
+
+    /**
+     * 0:已删除;1未删除
+     */
+    private Integer delStatus;
+    /**
+     *  区分是关键词界面还是关键词库界面 (1关键词;2关键词库)
+     */
+    private Integer status;
+    /**
+     * 联动搜索次数
+     */
+    private Integer linkageFrequency;
+
+    public SearchFrequency() {
+        super();
+    }
+
+    public SearchFrequency(String id){
+        super(id);
+    }
+
+    private String serachDate;
+}

+ 49 - 0
src/main/java/com/caimei/modules/product/entity/SearchFrequencyVo.java

@@ -0,0 +1,49 @@
+package com.caimei.modules.product.entity;
+
+import com.thinkgem.jeesite.common.persistence.DataEntity;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.sql.Timestamp;
+
+/**
+ * 用于redis缓存(list和json互转)
+ */
+@Data
+public class SearchFrequencyVo{
+//       private Integer id ;
+//    /**
+//     * 数据来源(1:首页;2:信息中心)
+//     */
+//    private Integer fromSearch   ;
+//    /**
+//     * 接口路径
+//     */
+//    private String  path;
+    /**
+     * 关键词
+     */
+    private String  keyword ;
+//    /**
+//     * 关键词出现次数
+//     */
+//    private Integer  frequency ;
+//    /**
+//     * 搜索时间
+//     */
+//    private Timestamp searchTime ;
+//    /**
+//     * 0:未加入关键词库;1:已加入关键词库
+//     */
+//    private Integer trueStatus;
+//
+//    /**
+//     * 0:已删除;1未删除
+//     */
+//    private Integer delStatus;
+//    /**
+//     *  区分是关键词界面还是关键词库界面 (1关键词;2关键词库)
+//     */
+//    private Integer status;
+
+}

+ 167 - 0
src/main/java/com/caimei/modules/product/service/KeywordFrequencyService.java

@@ -0,0 +1,167 @@
+package com.caimei.modules.product.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.caimei.modules.product.dao.KeywordFrequencyDao;
+import com.caimei.modules.product.entity.SearchFrequency;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
+import com.thinkgem.jeesite.common.persistence.Page;
+import com.thinkgem.jeesite.common.service.CrudService;
+import com.thinkgem.jeesite.common.utils.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+@Service
+@Transactional(readOnly = true)
+public class KeywordFrequencyService extends CrudService<KeywordFrequencyDao, SearchFrequency> {
+
+   @Autowired
+   private KeywordFrequencyDao keywordFrequencyDao;
+    @Autowired
+    private RedisServiceCom redisService;
+
+//   public Page<SearchFrequency> getKeyInfo(Page<SearchFrequency> searchFrequency,SearchFrequency search){
+//       DataEntity entity= new DataEntity();
+//       entity.setPage(searchFrequency);
+//       List<SearchFrequency> listSearchFrequency=keywordFrequencyDao.getKeyInfo(search);
+//       searchFrequency.setList(listSearchFrequency);
+//       searchFrequency.setCount(listSearchFrequency.size());
+//       return searchFrequency;
+//   }
+    public Page<SearchFrequency> findPage(Page<SearchFrequency> page, SearchFrequency searchFrequency) {
+        return super.findPage(page, searchFrequency);
+    }
+    /**
+     * 查询未加入关键词库的关键词来源
+     * @return
+     */
+    public List<SearchFrequency> getSearchFrom(Integer trueStatus){
+        List<SearchFrequency> seacherFrom = keywordFrequencyDao.getSearchFrom(trueStatus);
+        return seacherFrom;
+    }
+
+    /**
+     * 加入关键词库
+     * @param ids
+     * @return
+     */
+    @Transactional(readOnly = false)
+    public String addKeyWordList(String ids){
+        String[]  idList=ids.split(",");
+        int[] array = Arrays.asList(idList).stream().mapToInt(Integer::parseInt).toArray();
+        keywordFrequencyDao.addKeyWordList(array);
+        //保存后重置关键词redis缓存
+        cacheKeyWord();
+        List<SearchFrequency> searchFrequencyVos = keywordFrequencyDao.getvalueListByIds(array);
+        conKeyWord(searchFrequencyVos);
+//        String[]  idList=ids.split(",");
+//        int[] array = Arrays.asList(idList).stream().mapToInt(Integer::parseInt).toArray();
+//        for (int i=0; i<array.length;i++){
+//            keywordFrequencyDao.addKeyWordList(i);
+//        }
+        return "加入关键词库成功";
+    }
+    /**
+     * 验证关键词是否存在
+     * @param keyword
+     * @return
+     */
+    public boolean verificationKeword(String keyword){
+        List<String> keyList = keywordFrequencyDao.verificationKeword(keyword);
+        if(null !=keyList&&keyList.size()>0){
+            return true;
+        }else{
+            return false;
+        }
+    }
+    /**
+     * 删除关键词
+     * @param id
+     * @return
+     */
+    @Transactional(readOnly = false)
+    public String delKeyWordById(Integer id,Integer delStatus){
+        if(null!=delStatus&&delStatus==1){
+            keywordFrequencyDao.delKeyWordById(id,0);
+        }else{
+            keywordFrequencyDao.delKeyWordById(id,1);
+        }
+        //删除缓存中的数据
+        SearchFrequency keyById = keywordFrequencyDao.getKeyById(id);
+        //根据key值获取数据,如果只有一条则直接删除,大于一条则删除后重新缓存
+        if(keyById!=null&& StringUtils.isNoneEmpty(keyById.getKeyword())){
+            String str=keyById.getKeyword();
+            String key="";
+            for(int i=0;i<str.length();i++){
+                key+=str.charAt(i);
+                redisService.remove(key);
+                List<SearchFrequencyVo> searchFrequencyVos = keywordFrequencyDao.getvalueList(key);
+                if(null !=searchFrequencyVos&& searchFrequencyVos.size()>0){
+                    String keyword = JSONObject.toJSONString(searchFrequencyVos);//有值的字段才转
+                    redisService.set(key,keyword,60L * 60 * 24 * 30);
+                }
+            }
+        }
+        return "删除关键词成功";
+    }
+    @Transactional(readOnly = false)
+    public void save(SearchFrequency searchFrequency) {
+        super.save(searchFrequency);
+    }
+    public List<SearchFrequency> export(String ids) {
+        String[]  idList=ids.split(",");
+        int[] array = Arrays.asList(idList).stream().mapToInt(Integer::parseInt).toArray();
+        List<SearchFrequency> infoByIdList = keywordFrequencyDao.getInfoByIdList(array);
+        return infoByIdList;
+    }
+
+    /**
+     *
+     * @param searchFrequencyList
+     */
+    @Transactional(readOnly = false)
+    public void importKeyword(List<SearchFrequency> searchFrequencyList){
+        if(null !=searchFrequencyList && searchFrequencyList.size()>0){
+            for (SearchFrequency searchFrequency:searchFrequencyList ) {
+                keywordFrequencyDao.insert(searchFrequency);
+            }
+        }
+    }
+
+    /**
+     * redis缓存关键词(把所有的关键词整合到一个字符串中)
+     * 用时从redis取出转成list集合返回给前端进行联动
+     */
+    public void cacheKeyWord(){
+        //获取已加入关键词库有效的关键词进行缓存
+        List<SearchFrequencyVo> keywordList = keywordFrequencyDao.getKeywordList();
+        String keyword = JSONObject.toJSONString(keywordList);//有值的字段才转
+//        String keyword =JSONArray.fromObject(keywordList).toString();//所有字段属性都转
+        redisService.set("keyword",keyword,60L * 60 * 24 * 30);
+//        System.out.println(redisService.getExpireTime("keyword"));
+//        String key=redisService.get("keyword").toString();
+//        System.out.println(key);
+    }
+    /**
+     * redis缓存关键词(把所有的关键词整合到一个字符串中)
+     * 用时从redis取出转成list集合返回给前端进行联动
+     */
+    public void conKeyWord(List<SearchFrequency> list){
+        List<SearchFrequency> keywordList = list;
+        for (SearchFrequency searchFrequency:keywordList) {
+            String str=searchFrequency.getKeyword();
+            String key="";
+            for(int i=0;i<str.length();i++){
+                key+=str.charAt(i);
+                List<SearchFrequencyVo> searchFrequencyVos = keywordFrequencyDao.getvalueList(key);
+                String keyword = JSONObject.toJSONString(searchFrequencyVos);//有值的字段才转
+                redisService.set(key,keyword,60L * 60 * 24 * 30);
+            }
+        }
+//        System.out.println(redisService.getExpireTime("keyword"));
+//        String key=redisService.get("keyword").toString();
+//        System.out.println(key);
+    }
+}

+ 294 - 0
src/main/java/com/caimei/modules/product/service/RedisServiceCom.java

@@ -0,0 +1,294 @@
+package com.caimei.modules.product.service;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis 服务工具类
+ *
+ * @author : Charles
+ * @date : 2021/3/4
+ */
+@Slf4j
+@Service
+public class RedisServiceCom {
+
+	@Resource
+	private RedisTemplate<Serializable, Object> redisTemplate;
+
+    /**
+     * 批量删除
+     * @param keys
+     */
+	public void remove(String... keys) {
+		for(String key :keys){
+			remove(key);
+		}
+	}
+
+    /**
+     * 批量删除正则匹配到的
+     * @param pattern
+     */
+	public void removePattern(String pattern) {
+		Set<Serializable> keys = redisTemplate.keys(pattern);
+        assert keys != null;
+        if (keys.size() > 0){
+			redisTemplate.delete(keys);
+		}
+	}
+
+    /**
+     * 删除
+     * @param key
+     */
+	public void remove(String key) {
+		if (exists(key)) {
+			redisTemplate.delete(key);
+		}
+	}
+
+    /**
+     * 判断缓存中是否存在
+     * @param key
+     * @return boolean
+     */
+	public boolean exists(String key) {
+		return StringUtils.isBlank(key) ? false : redisTemplate.hasKey(key);
+	}
+
+    /**
+     * 读取缓存
+     * @param key
+     * @return
+     */
+	public Object get(String key) {
+		Object result = null;
+		ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+		result = operations.get(key);
+		return result;
+	}
+
+    /**
+     * 写入缓存
+     * @param key
+     * @param value
+     * @return
+     */
+	public boolean set(String key, Object value) {
+		boolean result = false;
+		try {
+			ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+			operations.set(key, value);
+			result = true;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+
+    /**
+     * 写入缓存并加上过期时间(秒)
+     * @param key
+     * @param value
+     * @param expireTimeSeconds
+     * @return
+     */
+	public boolean set(String key, Object value, Long expireTimeSeconds) {
+		boolean result = false;
+		try {
+			ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
+			operations.set(key, value);
+			redisTemplate.expire(key, expireTimeSeconds, TimeUnit.SECONDS);
+			result = true;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+    /**
+     * 写入过期时间(秒)
+     * @param key
+     * @param expireTimeSeconds
+     * @return
+     */
+	public boolean expire(String key, Long expireTimeSeconds) {
+		boolean result = false;
+		try {
+			redisTemplate.expire(key, expireTimeSeconds, TimeUnit.SECONDS);
+			result = true;
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return result;
+	}
+    /* **************************** 针对list操作的方法 **************************** */
+    /**
+     * 在key对应list的尾部添加
+     * @param key
+     * @param value
+     * @return
+     */
+	public long rightPushForList(String key, Object value) {
+		return redisTemplate.opsForList().rightPush(key, value);
+	}
+
+    /**
+     * 在key对应list的头部添加
+     * @param key
+     * @param value
+     * @return
+     */
+	public long leftPushForList(String key, Object value) {
+		return redisTemplate.opsForList().leftPush(key, value);
+	}
+
+    /**
+     * key对应list的长度
+     * @param key
+     * @return
+     */
+	public long listSize(String key) {
+		return redisTemplate.opsForList().size(key);
+	}
+
+    /**
+     * 获取list集合
+     * @param Key
+     * @param begin
+     * @param end
+     * @return
+     */
+	public List<?> getList(String Key, int begin, int end) {
+		return redisTemplate.opsForList().range(Key, begin, end);
+	}
+
+    /**
+     * 在key对应list的尾部移除
+     * @param key
+     * @return
+     */
+	public Object rightPopForList(String key) {
+		return redisTemplate.opsForList().rightPop(key);
+	}
+
+    /**
+     * 在key对应list的头部移除
+     * @param key
+     * @return
+     */
+	public Object leftPopForList(String key) {
+		return redisTemplate.opsForList().leftPop(key);
+	}
+
+    /**
+     * 移除list的index位置上的值
+     * @param Key
+     * @param index
+     * @param value
+     */
+	public void removeList(String Key, long index, Object value) {
+		redisTemplate.opsForList().remove(Key, index, value);
+	}
+
+    /**
+     * 重置list的index位置上的值
+     * @param Key
+     * @param index
+     * @param value
+     */
+	public void setList(String Key, long index, Object value) {
+		redisTemplate.opsForList().set(Key, index, value);
+	}
+
+
+    /**
+     * 写入list
+     * @param key
+     * @param list
+     */
+	public void setList(String key, List list) {
+		if(list!=null&&list.size()>0){
+			for (Object object : list) {
+				rightPushForList(key,object);
+			}
+		}
+	}
+
+    /**
+     * 写入map
+     * @param key
+     * @param map
+     */
+	public void setMap(String key, Map<String, Object> map) {
+		redisTemplate.opsForHash().putAll(key, map);
+	}
+
+    /**
+     * 获取map
+     * @param key
+     * @param mapKey
+     * @return
+     */
+	public Object get(String key, String mapKey) {
+		return redisTemplate.opsForHash().get(key, mapKey);
+	}
+
+    /**
+     * 写入map
+     * @param key
+     * @param hashKey
+     * @param hashValue
+     */
+	public void setMapByKV(String key, Object hashKey, Object hashValue) {
+		redisTemplate.opsForHash().put(key, hashKey,hashValue);
+	}
+
+    /**
+     * 删除map中的某个key-value
+     * @param key
+     * @param hashKey
+     */
+	public void removeHash(String key, String hashKey) {
+		redisTemplate.opsForHash().delete(key, hashKey);
+	}
+
+    /**
+     *
+     * @param key
+     * @return
+     */
+	public Map<Object, Object> getEntries(String key) {
+		return redisTemplate.opsForHash().entries(key);
+	}
+
+    /**
+     *
+     * @param key
+     * @param step
+     * @return
+     */
+	public long increase(String key, long step) {
+		return redisTemplate.opsForValue().increment(key, step);
+	}
+
+    /**
+     * 获取失效时间
+     * @param key
+     * @return
+     */
+	public long getExpireTime(String key) {
+		return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+	}
+
+}

+ 318 - 0
src/main/java/com/caimei/modules/product/web/KeywordFrequencyController.java

@@ -0,0 +1,318 @@
+package com.caimei.modules.product.web;
+
+import com.caimei.modules.common.utils.ExcelUtil;
+import com.caimei.modules.order.entity.CmAuthorizedConsignment;
+import com.caimei.modules.order.entity.CmDiscernReceipt;
+import com.caimei.modules.order.utils.OrderUtil;
+import com.caimei.modules.product.entity.SearchFrequency;
+import com.caimei.modules.product.entity.SearchFrequencyVo;
+import com.caimei.modules.product.service.KeywordFrequencyService;
+import com.github.pagehelper.PageInfo;
+import com.thinkgem.jeesite.common.config.Global;
+import com.thinkgem.jeesite.common.persistence.Page;
+import com.thinkgem.jeesite.common.utils.DateUtils;
+import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
+import com.thinkgem.jeesite.common.web.BaseController;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.hssf.usermodel.HSSFRow;
+import org.apache.poi.hssf.usermodel.HSSFSheet;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.servlet.mvc.support.RedirectAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.awt.*;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.List;
+
+@Controller
+@RequestMapping(value = "${adminPath}/product/keywordFrequency")
+public class KeywordFrequencyController extends BaseController {
+
+        @Autowired
+        private KeywordFrequencyService keywordFrequencyService;
+
+    /**
+     * 查询未加入关键词库的数据
+     * @param searchFrequency
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+        @RequestMapping(value="/getKeyInfo")
+        public String getKeyInfo(SearchFrequency searchFrequency, HttpServletRequest request, HttpServletResponse response,  Model model){//@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
+            searchFrequency.setTrueStatus(0);
+            Page<SearchFrequency> keyInfo = keywordFrequencyService.findPage(new Page<SearchFrequency>(request,response),searchFrequency);
+            List<SearchFrequency> seacherFrom = keywordFrequencyService.getSearchFrom(1);
+            model.addAttribute("keyInfo",keyInfo);
+            model.addAttribute("searchFrequency",searchFrequency);
+            model.addAttribute("seacherFrom",seacherFrom);
+            return "modules/product/keywordFrequency";
+        }
+    /**
+     * 查询已加入关键词库的数据
+     * @param searchFrequency
+     * @param request
+     * @param response
+     * @param model
+     * @return
+     */
+    @RequestMapping(value="/getKeywordThesaurusInfo")
+    public String getKeywordThesaurusInfo(SearchFrequency searchFrequency, HttpServletRequest request, HttpServletResponse response,  Model model){//@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
+        searchFrequency.setTrueStatus(1);
+        Page<SearchFrequency> keyInfo = keywordFrequencyService.findPage(new Page<SearchFrequency>(request,response),searchFrequency);
+        List<SearchFrequency> list = keyInfo.getList();
+        for (SearchFrequency search:list) {
+            if(null != search.getSearchTime()){
+                SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                Date da=new Date(search.getSearchTime().getTime());
+                String date = fmt.format(da);
+                search.setSerachDate(date);
+            }
+        }
+        keyInfo.setList(list);
+        List<SearchFrequency> seacherFrom = keywordFrequencyService.getSearchFrom(2);
+        model.addAttribute("keyInfo",keyInfo);
+        model.addAttribute("searchFrequency",searchFrequency);
+        model.addAttribute("seacherFrom",seacherFrom);
+        return "modules/product/keywordThesaurus";
+    }
+
+        /**
+         * 查询未加入关键词库的关键词来源
+         * @return
+         */
+        @ResponseBody
+        @RequestMapping("/getSeacherFrom")
+        public List<String> getSearchFrom(Integer trueStatus){
+//            List<String> seacherFrom = keywordFrequencyService.getSearchFrom(trueStatus);
+            return null;
+        }
+
+    /**
+     * 加入关键词库
+     * @param ids
+     * @return
+     */
+    @RequestMapping("/addKeyWordList")
+    @ResponseBody
+    public String addKeyWordList(String ids,Model model){
+        keywordFrequencyService.addKeyWordList(ids);
+        return "success";
+    }
+    /**
+     * 验证关键词库是该否存在关键词
+     * @param keyword
+     * @return
+     */
+    @RequestMapping("/verificationKeword")
+    @ResponseBody
+    public String verificationKeword(String keyword,Model model){
+        boolean b = keywordFrequencyService.verificationKeword(keyword);
+        if(b){
+            return "-1";
+        }else{
+            return "0";
+        }
+
+    }
+    /**
+     * 删除关键词
+     * status 区分是关键词界面还是关键词库界面 (1关键词;2关键词库)
+     * @param id
+     * @return
+     */
+    @RequestMapping("/delKeyWordById")
+    public String delKeyWordById(Integer id,Integer status,RedirectAttributes redirectAttributes){
+        keywordFrequencyService.delKeyWordById(id,status);
+        addMessage(redirectAttributes, "删除关键词成功");
+        if(status==1){
+            return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeyInfo";
+
+        }
+        return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeywordThesaurusInfo";
+
+    }
+
+    /**
+     * 跳转编辑添加页面
+     * @param searchFrequency
+     * @param model
+     * @return
+     */
+    @RequestMapping(value = "form")
+    public String form(SearchFrequency searchFrequency, Model model) {
+        model.addAttribute("searchFrequency", searchFrequency);
+        return "modules/product/upkeyword";
+    }
+
+    /**
+     * 更新关键词
+     * @param searchFrequency
+     * @param redirectAttributes
+     * @param model
+     * @return
+     */
+    @RequestMapping("save")
+    public String save(SearchFrequency searchFrequency,RedirectAttributes redirectAttributes,Model model){
+        if (!beanValidator(model, searchFrequency)){
+            return form(searchFrequency, model);
+        }
+        //如果是新增操作时
+        searchFrequency.setTrueStatus(1);
+        searchFrequency.setFromSearch(6);//为管理员添加
+        searchFrequency.setPath("管理员添加");
+        Date date=new Date();
+        SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        sd.format(date);
+//        searchFrequency.setSearchTime(new java.sql.Timestamp(date.getTime()));
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        searchFrequency.setSearchTime(new java.sql.Timestamp(cal.getTime().getTime()));
+
+        if(null !=searchFrequency.getKeyId()){
+            searchFrequency.setId(searchFrequency.getKeyId().toString());
+        }
+        keywordFrequencyService.save(searchFrequency);
+        if(searchFrequency.getStatus()==2){
+            //保存后重置关键词redis缓存
+            keywordFrequencyService.cacheKeyWord();
+            List<SearchFrequency> list=new ArrayList<>();
+            list.add(searchFrequency);
+            keywordFrequencyService.conKeyWord(list);
+        }
+        addMessage(redirectAttributes, "保存成功");
+        //编辑
+        if(null !=searchFrequency.getStatus()&&1==searchFrequency.getStatus()){
+            return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeyInfo";
+        }
+        //新增
+        return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeywordThesaurusInfo";
+
+    }
+
+    /**
+     * 导出关键词
+     * @param ids
+     * @param redirectAttributes
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "export")
+    public void export(String ids, RedirectAttributes redirectAttributes, HttpServletRequest request, HttpServletResponse response) {
+        //获取订单数据
+        String fileName = "关键词列表.xls";
+        String template = Global.getConfig("export.template");
+        String templateFileName = template + "/keyword.xls";
+        try {
+            Map data = new HashMap<String, Object>();
+            List<SearchFrequency> list = keywordFrequencyService.export(ids);
+            data.put("list", list);
+//            data.put("orderUtil", new OrderUtil());
+            new ExcelUtil().createExcel(templateFileName, data, fileName, response);
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "关键词导出失败!" + e.getMessage());
+            logger.info(e.getMessage());
+            e.printStackTrace();
+        }
+    }
+    /**
+     * 导出关键词库关键词
+     * @param ids
+     * @param redirectAttributes
+     * @param request
+     * @param response
+     */
+    @RequestMapping(value = "exportThesaurus")
+    public void exportThesaurus(String ids, RedirectAttributes redirectAttributes, HttpServletRequest request, HttpServletResponse response) {
+        //获取订单数据
+        String fileName = "关键词列表.xls";
+        String template = Global.getConfig("export.template");
+        String templateFileName = template + "/thesaurus.xls";
+        try {
+            Map data = new HashMap<String, Object>();
+            List<SearchFrequency> list = keywordFrequencyService.export(ids);
+            data.put("list", list);
+//            data.put("orderUtil", new OrderUtil());
+            new ExcelUtil().createExcel(templateFileName, data, fileName, response);
+        } catch (Exception e) {
+            addMessage(redirectAttributes, "关键词导出失败!" + e.getMessage());
+            logger.info(e.getMessage());
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 导入关键词
+     * @param file
+     * @param redirectAttributes
+     * @return
+     */
+    @RequestMapping(value = "importKeyword")
+    public String importKeyword(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes){
+        String contentType = file.getContentType();
+        String fileName = file.getOriginalFilename();
+        if (file.isEmpty()) {
+            addMessage(redirectAttributes,"请选择需要导入的关键词文件");
+            return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeywordThesaurusInfo";
+        }
+        try {
+            //根据路径获取这个操作excel的实例
+            HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
+            //根据页面index 获取sheet页
+            HSSFSheet sheet = wb.getSheetAt(0);
+            HSSFRow row = null;
+            //循环sesheet页中数据从第二行开始,第一行是标题
+            List<SearchFrequency> searchFrequencyList=new ArrayList<>();
+            for(int i=1;i<sheet.getPhysicalNumberOfRows()-1;i++){
+                row = sheet.getRow(i);
+                SearchFrequency searchFrequency=new SearchFrequency();
+                if(null !=row.getCell(1)){
+                searchFrequency.setKeyword(row.getCell(1).toString());
+                }else{
+                    continue;
+                }
+                if(null != row.getCell(2)){
+                    if("首页搜索".equals(row.getCell(2).toString())){
+                        searchFrequency.setFromSearch(1);
+                    }else if("信息中心搜索".equals(row.getCell(2).toString())){
+                        searchFrequency.setFromSearch(2);
+                    }else if("管理员添加".equals(row.getCell(2).toString())){
+                        searchFrequency.setFromSearch(6);
+                    }
+                }
+                if(null != row.getCell(3)){
+                    searchFrequency.setSearchTime(new java.sql.Timestamp(row.getCell(3).getDateCellValue().getTime()));
+                }
+                searchFrequency.setPath("管理员添加");
+                searchFrequency.setTrueStatus(1);
+                searchFrequencyList.add(searchFrequency);
+            }
+            //保存文件数据
+            keywordFrequencyService.importKeyword(searchFrequencyList);
+            //保存后重置关键词redis缓存
+            keywordFrequencyService.cacheKeyWord();
+            keywordFrequencyService.conKeyWord(searchFrequencyList);
+        } catch (IOException  e) {//| ParseException
+            e.printStackTrace();
+        }
+        addMessage(redirectAttributes,"导入的关键词成功");
+        return "redirect:"+Global.getAdminPath()+"/product/keywordFrequency/getKeywordThesaurusInfo";
+    }
+}

+ 13 - 1
src/main/java/com/caimei/modules/product/web/ProductNewController.java

@@ -1,5 +1,7 @@
 package com.caimei.modules.product.web;
 
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
 import com.caimei.dfs.image.beens.ImageUploadInfo;
 import com.caimei.modules.brand.entity.CmBrand;
 import com.caimei.modules.brand.service.CmBrandService;
@@ -11,6 +13,7 @@ import com.caimei.modules.opensearch.GenerateUtils;
 import com.caimei.modules.order.dao.NewShopOrderDao;
 import com.caimei.modules.order.service.NewOrderService;
 import com.caimei.modules.order.service.WeChatService;
+import com.caimei.modules.product.dao.KeywordFrequencyDao;
 import com.caimei.modules.product.dao.ProductNewDao;
 import com.caimei.modules.product.entity.*;
 import com.caimei.modules.product.service.*;
@@ -97,6 +100,8 @@ public class ProductNewController extends BaseController {
     private WeChatService weChatService;
     @Autowired
     private NewShopOrderDao newShopOrderDao;
+    @Autowired
+    private KeywordFrequencyDao keywordFrequencyDao;
 
 
     @ModelAttribute
@@ -397,6 +402,13 @@ public class ProductNewController extends BaseController {
             product.setSupplierTaxPoint(product.getTaxPoint());
         }
         List<SplitCode> splitCodeList = productNewDao.findSplitCode(product.getShopID());
+        //先从reids中获取keyword值,不存在时在查询数据库
+        List<SearchFrequencyVo> searchFrequencyVos=new ArrayList<>();
+        if(redisService.getExpireTime("keyword")>0){
+             searchFrequencyVos= JSONArray.parseArray(redisService.get("keyword").toString(),SearchFrequencyVo.class);
+        }else{
+             searchFrequencyVos = keywordFrequencyDao.getKeywordList();
+        }
         model.addAttribute("splitCodeList",splitCodeList);
         model.addAttribute("combinationList", combinationList);
         model.addAttribute("brandList", brandList);
@@ -404,9 +416,9 @@ public class ProductNewController extends BaseController {
         model.addAttribute("classify", classify);
         model.addAttribute("provinceList", provinceList);
         model.addAttribute("product", product);
+        model.addAttribute("SearchFrequencyVo",searchFrequencyVos);
         return "modules/product-new/productEdit";
     }
-
     @RequestMapping(value = "productNewSave")
     public String productNewSave(Product product, RedirectAttributes redirectAttributes) {
         // 组合搜索关键词

+ 10 - 10
src/main/resources/config/beta/caimei.properties

@@ -125,7 +125,7 @@ activiti.diagram.labelFontName=\u5B8B\u4F53
 #activiti\u5916\u90E8\u8868\u5355\u6839\u5730\u5740\u914D\u7F6E
 activiti.form.server.url=
 
-#测试服务器本地存储地址
+#\u6D4B\u8BD5\u670D\u52A1\u5668\u672C\u5730\u5B58\u50A8\u5730\u5740
 userfiles.basedir=/mnt/newdatadrive/nfs_client/
 
 #\u5DE5\u7A0B\u8DEF\u5F84\uFF0C\u5728\u4EE3\u7801\u751F\u6210\u65F6\u83B7\u53D6\u4E0D\u5230\u5DE5\u7A0B\u8DEF\u5F84\u65F6\uFF0C\u53EF\u518D\u6B64\u6307\u5B9A\u7EDD\u5BF9\u8DEF\u5F84\u3002
@@ -147,43 +147,43 @@ keyword.product=mnt/newdatadrive/nfs_client/keywords/keyword.txt
 #\u7528\u6237\u5546\u54C1\u4EF7\u683C\u8FC7\u5C0F\u90AE\u4EF6\u63D0\u793A
 user.mails=jun.li@caimei365.com
 
-#易宝分账
+#\u6613\u5B9D\u5206\u8D26
 yeepay.appkey=BM12345678902069
 yeepay.secretKey=OH6huQqihk0ZfGzWgR1WcQ==
 yeepay.secretRoot=https://openapi.yeepay.com/yop-center
 yeepay.divideCallback=http://admintest.365mdd.com/a/order/newShouldPay/divideCallback
 yeepay.mails=jun.li@caimei365.com
 
-#微信公众号信息(测试公众号无数据此处使用正式公众号)
+#\u5FAE\u4FE1\u516C\u4F17\u53F7\u4FE1\u606F(\u6D4B\u8BD5\u516C\u4F17\u53F7\u65E0\u6570\u636E\u6B64\u5904\u4F7F\u7528\u6B63\u5F0F\u516C\u4F17\u53F7)
 appId=wx91c4152b60ca91a3
 appSecret=a563dd2c07c9c815a4e697c8b6cb73dc
 token=caimei
 encryptMessage=false
 encodingAesKey=wJWhhXuWAByeBPA8NicwFGraVhjKqWBUm94sOKN3s66
-#微信获取文章配置
+#\u5FAE\u4FE1\u83B7\u53D6\u6587\u7AE0\u914D\u7F6E
 wx.getToken=https\://api.weixin.qq.com/cgi-bin/token
 wx.getMaterial=https\://api.weixin.qq.com/cgi-bin/material/batchget_material
 wx.getMaterialCount=https\://api.weixin.qq.com/cgi-bin/material/get_materialcount
 
-#运费商品默认ID
+#\u8FD0\u8D39\u5546\u54C1\u9ED8\u8BA4ID
 freightProductID=999
 
 cm.config=beta
-#线上直接读取服务器位置文件
+#\u7EBF\u4E0A\u76F4\u63A5\u8BFB\u53D6\u670D\u52A1\u5668\u4F4D\u7F6E\u6587\u4EF6
 export.template=/mnt/newdatadrive/data/custom/manager-export-template
 
-# SPI-server(CKEditor5图片上传API,搜索更新索引)
+# SPI-server\uFF08CKEditor5\u56FE\u7247\u4E0A\u4F20API\uFF0C\u641C\u7D22\u66F4\u65B0\u7D22\u5F15\uFF09
 caimei.spi=https://spi-b.caimei365.com
 caimei.core=https://core-b.caimei365.com
 caimei.manager=https://manager-b.caimei365.com
 
-#阿里云oss存储
+#\u963F\u91CC\u4E91oss\u5B58\u50A8
 aliyun.accessKeyId=LTAI4GBL3o4YkWnbKYgf2Xia
 aliyun.accessKeySecret=dBjAXqbYiEPP6Ukuk2ZsXQeET7FVkK
 aliyun.bucketName=caimei-oss
 aliyun.endpoint=https://oss-cn-shenzhen.aliyuncs.com
 
-#商品资料库文件临时路径
+#\u5546\u54C1\u8D44\u6599\u5E93\u6587\u4EF6\u4E34\u65F6\u8DEF\u5F84
 archive.tempPath=/mnt/newdatadrive/data/runtime/tomcat-instance/manager/tempFile/
-#ffmpeg路径
+#ffmpeg\u8DEF\u5F84
 ffmpeg.path=/mnt/newdatadrive/apps/ffmpeg/ffmpeg-master/bin/ffmpeg

BIN
src/main/resources/export/keyword.xls


BIN
src/main/resources/export/thesaurus.xls


+ 6 - 3
src/main/resources/mappings/modules/archive/CmProductArchiveMapper.xml

@@ -130,7 +130,8 @@
 			archiveLevel,
 			productType,
 			productClassify,
-			addTime
+			addTime,
+			seoKeyword
 		) VALUES (
 			#{productId},
 			#{productName},
@@ -139,7 +140,8 @@
 			#{archiveLevel},
 			#{productType},
 			#{productClassify},
-			#{addTime}
+			#{addTime},
+		    #{seoKeyword}
 		)
 	</insert>
 	
@@ -151,7 +153,8 @@
 			productImage = #{productImage},
 			archiveLevel = #{archiveLevel},
 			productType = #{productType},
-			productClassify = #{productClassify}
+			productClassify = #{productClassify},
+			seoKeyword= #{seoKeyword}
 		WHERE id = #{id}
 	</update>
 	

+ 1 - 0
src/main/resources/mappings/modules/info/InfoAdMapper.xml

@@ -6,6 +6,7 @@
 		a.id AS "id",
 		a.serviceObject AS "serviceObject",
 		a.link AS "link",
+-- 		a.soft as "soft",
 		a.location AS "location",
 		a.recommendContent AS "recommendContent",
 		a.title AS "title",

+ 160 - 0
src/main/resources/mappings/modules/product/SearchFrequencyMapper.xml

@@ -0,0 +1,160 @@
+<?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.caimei.modules.product.dao.KeywordFrequencyDao">
+         <select id="findList" resultType="com.caimei.modules.product.entity.SearchFrequency">
+             select
+                    id as keyId,
+                    fromSearch,
+                    path,
+                    keyword,
+                    frequency,
+                    searchTime,
+                    trueStatus,
+                    delStatus,
+                    linkageFrequency
+              from cm_user_search_frequency
+             where  delStatus=1
+             <if test="trueStatus != null">
+                 AND trueStatus=#{trueStatus}
+             </if>
+             <if test="keyword != null and keyword != ''">
+                 AND keyword like CONCAT('%',#{keyword},'%')
+             </if>
+             <if test="fromSearch != null">
+                 AND fromSearch = #{fromSearch}
+             </if>
+             <if test="trueStatus == 0">
+                 order by  frequency desc
+             </if>
+             <if test="trueStatus == 1">
+                 order by  searchTime desc
+             </if>
+         </select>
+
+    <select id="getSearchFrom" resultType="com.caimei.modules.product.entity.SearchFrequency">
+            select
+            fromSearch
+        from cm_user_search_frequency
+        where trueStatus=#{trueStatus} and delStatus=1
+         group by fromSearch
+    </select>
+
+
+    <select id="getInfoBykeyword" resultType="com.caimei.modules.product.entity.SearchFrequency">
+        select
+            id as keyId,
+            fromSearch,
+            path,
+            keyword,
+            frequency,
+            searchTime,
+            trueStatus,
+            delStatus,
+            linkageFrequency
+        from cm_user_search_frequency
+        where keyword=#{keyword}
+        and   fromSearch=#{fromSearch}
+    </select>
+    <insert id="saveInfo" parameterType="com.caimei.modules.product.entity.SearchFrequency">
+        insert into cm_user_search_frequency(fromSearch,path,keyword,frequency,searchTime)
+        values (#{fromSearch},#{path},#{keyword},#{frequency},#{searchTime})
+
+    </insert>
+    <update id="upFrequencyById">
+        update cm_user_search_frequency set frequency=#{frequency} where id=#{id}
+    </update>
+    <update id="addKeyWordList">
+        update cm_user_search_frequency set trueStatus=1
+        where id in
+        <foreach collection="idList" open="(" separator="," close=")" item="reId">
+            #{reId,jdbcType=INTEGER}
+        </foreach>
+    </update>
+    <select id="getvalueListByIds" resultType="com.caimei.modules.product.entity.SearchFrequency">
+        select
+        keyword
+        from cm_user_search_frequency
+        where trueStatus=1
+        and   delStatus=1
+        and keyword is not null
+        and id in
+        <foreach collection="idList" open="(" separator="," close=")" item="reId">
+            #{reId,jdbcType=INTEGER}
+        </foreach>
+    </select>
+    <update id="delKeyWordById" parameterType="java.lang.Integer">
+        update cm_user_search_frequency
+        <set>
+            frequency=0,
+            linkageFrequency=0,
+            trueStatus=0,
+        <if test="delStatus != null">
+            delStatus=0
+        </if>
+        </set>
+        where id =#{id}
+    </update>
+    <insert id="insert" parameterType="com.caimei.modules.product.entity.SearchFrequency">
+        insert into cm_user_search_frequency(fromSearch,path,keyword,frequency,searchTime,trueStatus,linkageFrequency)
+        values (#{fromSearch},#{path},#{keyword},#{frequency},#{searchTime},#{trueStatus},0)
+    </insert>
+    <update id="update">
+        update cm_user_search_frequency set keyword=#{keyword},searchTime=#{searchTime} where id=#{id}
+    </update>
+    <select id="getInfoByIdList" resultType="com.caimei.modules.product.entity.SearchFrequency">
+        select
+            id as keyId,
+            fromSearch,
+            path,
+            keyword,
+            frequency,
+            searchTime,
+            trueStatus,
+            delStatus,
+            linkageFrequency
+        from cm_user_search_frequency
+        where
+           id in
+        <foreach collection="idList" open="(" separator="," close=")" item="reId">
+            #{reId,jdbcType=INTEGER}
+        </foreach>
+    </select>
+
+
+    <select id="getKeywordList" resultType="com.caimei.modules.product.entity.SearchFrequencyVo">
+        select
+            keyword
+        from cm_user_search_frequency
+        where trueStatus=1
+          and   delStatus=1
+          and keyword is not null
+    </select>
+    <select id="getvalueList" resultType="com.caimei.modules.product.entity.SearchFrequencyVo">
+        select
+            keyword
+        from cm_user_search_frequency
+        where trueStatus=1
+          and   delStatus=1
+          and keyword is not null
+        <if test="keyword != null and keyword != ''">
+            and keyword like concat(#{keyword},'%')
+        </if>
+    </select>
+    <select id="getKeyById" resultType="com.caimei.modules.product.entity.SearchFrequency">
+        select
+        keyword
+        from cm_user_search_frequency
+        where trueStatus=1
+        and   delStatus=0
+        and keyword is not null
+        and id=#{id}
+    </select>
+    <select id="verificationKeword" resultType="java.lang.String">
+        select
+            keyword
+        from cm_user_search_frequency
+        where trueStatus=1
+          and   delStatus=1
+          and keyword =#{keyword}
+    </select>
+</mapper>

+ 28 - 1
src/main/webapp/WEB-INF/views/modules/archive/cmProductArchiveForm.jsp

@@ -170,12 +170,39 @@
 				</form:select>
 			</div>
 		</div>
+		<div class="control-group">
+			<label class="control-label">SEO关键词:</label>
+			<div class="auto-input">
+				<form:input path="seoKeyword" htmlEscape="false" style="position: relative" class="input-xlarge"/>
+				<label id="seoKeywordSensitiveWords" class="red"></label>
+			</div>
+		</div>
 		<div class="form-actions">
 			<input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/>&nbsp;
 			<input id="btnCancel" class="btn" type="button" value="返 回" onclick="history.go(-1)"/>
 		</div>
 	</form:form>
-<script>
+	<script type="text/javascript" src="${ctxStatic}/auto-input.js"></script>
+	<script>
+		//关键词联动
+		function autocomplete(text) {
+			// return ['三全鲜食(北新泾店)', 'Hot honey 首尔炸鸡(仙霞路)', '新旺角茶餐厅', '泷千家(天山西路店)', '胖仙女纸杯蛋糕(上海凌空店)', '贡茶', '豪大大香鸡排超级奶爸', '茶芝兰(奶茶,手抓饼)', '十二泷町', '星移浓缩咖啡', '阿姨奶茶/豪大大', '新麦甜四季甜品炸鸡', 'Monica摩托主题咖啡店', '浮生若茶(凌空soho店)', 'NONO JUICE  鲜榨果汁', 'CoCo都可(北新泾店)', '快乐柠檬(神州智慧店)', 'Merci Paul cafe', '猫山王(西郊百联店)', '枪会山', '纵食', '钱记', '壹杯加', '唦哇嘀咖', '爱茜茜里(西郊百联)', '爱茜茜里(近铁广场)', '鲜果榨汁(金沙江路和美广店)', '开心丽果(缤谷店)', '超级鸡车(丰庄路店)', '妙生活果园(北新泾店)', '香宜度麻辣香锅', '凡仔汉堡(老真北路店)', '港式小铺', '蜀香源麻辣香锅(剑河路店)', '北京饺子馆', '饭典*新简餐(凌空SOHO店)', '焦耳·川式快餐(金钟路店)', '动力鸡车', '浏阳蒸菜', '四海游龙(天山西路店)', '樱花食堂(凌空店)', '壹分米客家传统调制米粉(天山店)', '福荣祥烧腊(平溪路店)', '速记黄焖鸡米饭', '红辣椒麻辣烫', '(小杨生煎)西郊百联餐厅', '阳阳麻辣烫', '南拳妈妈龙虾盖浇饭'].filter(function (item) {
+			//     return text && item.indexOf(text) > -1;
+			// });
+			var keywordlist=new Array();
+			<c:forEach items="${SearchFrequencyVo}" var="search">
+			keywordlist.push("${search.keyword}")
+			</c:forEach>
+			return keywordlist.filter(function (item) {
+				return text && item.indexOf(text) > -1;
+			});
+		}
+
+		new AutoComplete({
+			el: '.auto-input',
+			callback: autocomplete,
+			offsetLeft: -25
+		});
 	$(function () {
 		showInfo();
 		$('.upload-content .conList .btn:nth-of-type(1)').html('<div><span>+</span><h5>选择图片</h5></div>');

+ 22 - 1
src/main/webapp/WEB-INF/views/modules/baikePage/cmBaikeProductForm.jsp

@@ -262,6 +262,7 @@
 		.Main-content{
 			height: 100px;
 		}
+
 	</style>
 	<script type="text/javascript">
 		$(document).ready(function() {
@@ -662,7 +663,7 @@
 		</div>
 		<div class="control-group">
 			<label class="control-label">SEO关键词:</label>
-			<div class="controls">
+			<div class="auto-input">
 				<form:input path="seoKeyword" htmlEscape="false" style="position: relative" class="input-xlarge"/>
                 <label id="seoKeywordSensitiveWords" class="red"></label>
 			</div>
@@ -865,6 +866,7 @@
 <% request.setAttribute("caimeiCore", Global.getConfig("caimei.core"));%>
 <script type="text/javascript" src="${ctxStatic}/ckeditor5-new/ckeditor.js"></script>
 <script type="text/javascript" src="${ctxStatic}/sensitiveWords/mint-filter.umd.js"></script>
+<script type="text/javascript" src="${ctxStatic}/auto-input.js"></script>
 <script>
 	var paramIndex = 6;
 	var questionIndex = 2;
@@ -1313,6 +1315,25 @@
 			buttons: {"关闭": '-1'}
 		});
 	}
+	//关键词联动
+	function autocomplete(text) {
+		// return ['三全鲜食(北新泾店)', 'Hot honey 首尔炸鸡(仙霞路)', '新旺角茶餐厅', '泷千家(天山西路店)', '胖仙女纸杯蛋糕(上海凌空店)', '贡茶', '豪大大香鸡排超级奶爸', '茶芝兰(奶茶,手抓饼)', '十二泷町', '星移浓缩咖啡', '阿姨奶茶/豪大大', '新麦甜四季甜品炸鸡', 'Monica摩托主题咖啡店', '浮生若茶(凌空soho店)', 'NONO JUICE  鲜榨果汁', 'CoCo都可(北新泾店)', '快乐柠檬(神州智慧店)', 'Merci Paul cafe', '猫山王(西郊百联店)', '枪会山', '纵食', '钱记', '壹杯加', '唦哇嘀咖', '爱茜茜里(西郊百联)', '爱茜茜里(近铁广场)', '鲜果榨汁(金沙江路和美广店)', '开心丽果(缤谷店)', '超级鸡车(丰庄路店)', '妙生活果园(北新泾店)', '香宜度麻辣香锅', '凡仔汉堡(老真北路店)', '港式小铺', '蜀香源麻辣香锅(剑河路店)', '北京饺子馆', '饭典*新简餐(凌空SOHO店)', '焦耳·川式快餐(金钟路店)', '动力鸡车', '浏阳蒸菜', '四海游龙(天山西路店)', '樱花食堂(凌空店)', '壹分米客家传统调制米粉(天山店)', '福荣祥烧腊(平溪路店)', '速记黄焖鸡米饭', '红辣椒麻辣烫', '(小杨生煎)西郊百联餐厅', '阳阳麻辣烫', '南拳妈妈龙虾盖浇饭'].filter(function (item) {
+		//     return text && item.indexOf(text) > -1;
+		// });
+		var keywordlist=new Array();
+		<c:forEach items="${SearchFrequencyVo}" var="search">
+		keywordlist.push("${search.keyword}")
+		</c:forEach>
+		return keywordlist.filter(function (item) {
+			return text && item.indexOf(text) > -1;
+		});
+	}
+
+	new AutoComplete({
+		el: '.auto-input',
+		callback: autocomplete,
+		offsetLeft: -25
+	});
 </script>
 </body>
 </html>

+ 4 - 0
src/main/webapp/WEB-INF/views/modules/info/infoAdList.jsp

@@ -79,6 +79,7 @@
 				<th>广告位置</th>
 				<th>引导图</th>
 				<th>链接</th>
+<%--				<th>排序</th>--%>
 				<th>点击量</th>
 				<th>添加时间</th>
 				<th>状态</th>
@@ -101,6 +102,9 @@
 				<td>
 					${infoAd.link}
 				</td>
+<%--				<td>--%>
+<%--						<input id="soft" value="${infoAd.soft}" onblur="savaSoftValue()">--%>
+<%--				</td>--%>
 				<td>
 					${empty infoAd.clickRate?0:(infoAd.clickRate)}
 				</td>

+ 22 - 1
src/main/webapp/WEB-INF/views/modules/info/infoForm.jsp

@@ -45,7 +45,7 @@
 		</tr>
 		<tr>
 			<th><span class="red">*</span>SEO关键词:</th>
-			<td colspan="3">
+			<td colspan="3" class="auto-input">
 				<form:input path="keyword" htmlEscape="false" maxlength="50" class="input-xxlarge required"/>
 				<label id="keywordSensitiveWords" class="red"></label>
 			</td>
@@ -171,7 +171,28 @@
 <script type="text/javascript" src="${ctxStatic}/jquery-validation/1.19.3/jquery.validate.js"></script>
 <script type="text/javascript" src="${ctxStatic}/ckeditor5-new/ckeditor.js"></script>
 <script type="text/javascript" src="${ctxStatic}/sensitiveWords/mint-filter.umd.js"></script>
+<script type="text/javascript" src="${ctxStatic}/auto-input.js"></script>
 <script type="text/javascript">
+
+	//关键词联动
+	function autocomplete(text) {
+		// return ['三全鲜食(北新泾店)', 'Hot honey 首尔炸鸡(仙霞路)', '新旺角茶餐厅', '泷千家(天山西路店)', '胖仙女纸杯蛋糕(上海凌空店)', '贡茶', '豪大大香鸡排超级奶爸', '茶芝兰(奶茶,手抓饼)', '十二泷町', '星移浓缩咖啡', '阿姨奶茶/豪大大', '新麦甜四季甜品炸鸡', 'Monica摩托主题咖啡店', '浮生若茶(凌空soho店)', 'NONO JUICE  鲜榨果汁', 'CoCo都可(北新泾店)', '快乐柠檬(神州智慧店)', 'Merci Paul cafe', '猫山王(西郊百联店)', '枪会山', '纵食', '钱记', '壹杯加', '唦哇嘀咖', '爱茜茜里(西郊百联)', '爱茜茜里(近铁广场)', '鲜果榨汁(金沙江路和美广店)', '开心丽果(缤谷店)', '超级鸡车(丰庄路店)', '妙生活果园(北新泾店)', '香宜度麻辣香锅', '凡仔汉堡(老真北路店)', '港式小铺', '蜀香源麻辣香锅(剑河路店)', '北京饺子馆', '饭典*新简餐(凌空SOHO店)', '焦耳·川式快餐(金钟路店)', '动力鸡车', '浏阳蒸菜', '四海游龙(天山西路店)', '樱花食堂(凌空店)', '壹分米客家传统调制米粉(天山店)', '福荣祥烧腊(平溪路店)', '速记黄焖鸡米饭', '红辣椒麻辣烫', '(小杨生煎)西郊百联餐厅', '阳阳麻辣烫', '南拳妈妈龙虾盖浇饭'].filter(function (item) {
+		//     return text && item.indexOf(text) > -1;
+		// });
+		var keywordlist=new Array();
+		<c:forEach items="${SearchFrequencyVo}" var="search">
+		keywordlist.push("${search.keyword}")
+		</c:forEach>
+		return keywordlist.filter(function (item) {
+			return text && item.indexOf(text) > -1;
+		});
+	}
+
+	new AutoComplete({
+		el: '.auto-input',
+		callback: autocomplete,
+		offsetLeft: -25
+	});
 	$(document).ready(function() {
 		//$("#name").focus();
 		$("#inputForm").validate({

+ 22 - 1
src/main/webapp/WEB-INF/views/modules/product-new/productEdit.jsp

@@ -260,6 +260,7 @@
             padding-left: 0 !important;
             margin-left: 0 !important;
         }
+
     </style>
 </head>
 <body>
@@ -308,7 +309,7 @@
         </tr>
         <tr>
             <th>搜索关键字:</th>
-            <td colspan="3" class="skword">
+            <td colspan="3" class="skword auto-input">
                 <form:input path="searchKeyList[0]" maxlength="32" placeholder="建议输入品牌关键词"
                             onchange="checkmaxlengthsBySearch(this,this.value,32)" class="input-small"/>
                 <form:input path="searchKeyList[1]" maxlength="32" placeholder="建议输入商品学名关键词"
@@ -895,6 +896,8 @@
 
 <% request.setAttribute("caimeiCore", Global.getConfig("caimei.core"));%>
 <script type="text/javascript" src="${ctxStatic}/ckeditor5-new/ckeditor.js"></script>
+<script type="text/javascript" src="${ctxStatic}/auto-input.js"></script>
+
 <script type="text/javascript">
 
     /*$(function () {
@@ -909,7 +912,25 @@
             $("#visibility").prop("disabled",true);
         }
     });*/
+    //关键词联动
+    function autocomplete(text) {
+        // return ['三全鲜食(北新泾店)', 'Hot honey 首尔炸鸡(仙霞路)', '新旺角茶餐厅', '泷千家(天山西路店)', '胖仙女纸杯蛋糕(上海凌空店)', '贡茶', '豪大大香鸡排超级奶爸', '茶芝兰(奶茶,手抓饼)', '十二泷町', '星移浓缩咖啡', '阿姨奶茶/豪大大', '新麦甜四季甜品炸鸡', 'Monica摩托主题咖啡店', '浮生若茶(凌空soho店)', 'NONO JUICE  鲜榨果汁', 'CoCo都可(北新泾店)', '快乐柠檬(神州智慧店)', 'Merci Paul cafe', '猫山王(西郊百联店)', '枪会山', '纵食', '钱记', '壹杯加', '唦哇嘀咖', '爱茜茜里(西郊百联)', '爱茜茜里(近铁广场)', '鲜果榨汁(金沙江路和美广店)', '开心丽果(缤谷店)', '超级鸡车(丰庄路店)', '妙生活果园(北新泾店)', '香宜度麻辣香锅', '凡仔汉堡(老真北路店)', '港式小铺', '蜀香源麻辣香锅(剑河路店)', '北京饺子馆', '饭典*新简餐(凌空SOHO店)', '焦耳·川式快餐(金钟路店)', '动力鸡车', '浏阳蒸菜', '四海游龙(天山西路店)', '樱花食堂(凌空店)', '壹分米客家传统调制米粉(天山店)', '福荣祥烧腊(平溪路店)', '速记黄焖鸡米饭', '红辣椒麻辣烫', '(小杨生煎)西郊百联餐厅', '阳阳麻辣烫', '南拳妈妈龙虾盖浇饭'].filter(function (item) {
+        //     return text && item.indexOf(text) > -1;
+        // });
+        var keywordlist=new Array();
+        <c:forEach items="${SearchFrequencyVo}" var="search">
+        keywordlist.push("${search.keyword}")
+        </c:forEach>
+        return keywordlist.filter(function (item) {
+            return text && item.indexOf(text) > -1;
+        });
+    }
 
+    new AutoComplete({
+        el: '.auto-input',
+        callback: autocomplete,
+        offsetLeft: -25
+    });
     function js(){
             var val = $("#productType").val();
             var mac = $("#machineType").val();

+ 321 - 0
src/main/webapp/WEB-INF/views/modules/product/keywordFrequency.jsp

@@ -0,0 +1,321 @@
+<%--
+  Created by IntelliJ IDEA.
+  User: Administrator
+  Date: 2020/4/12
+  Time: 12:01
+  To change this template use File | Settings | File Templates.
+--%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+    <title>关键词列表</title>
+    <meta name="decorator" content="default"/>
+    <style type="text/css">
+        .table th{text-align: center;}
+        .table td{text-align: center;}
+    </style>
+    <script type="text/javascript">
+        // $(document).ready(function() {
+        //
+        // });
+        function page(n,s){
+            $("#pageNo").val(n);
+            $("#pageSize").val(s);
+            $("#searchForm").submit();
+            return false;
+        }
+        window.onload = function () {
+            <%--$.ajax({--%>
+            <%--    //几个参数需要注意一下--%>
+            <%--    type: "get",//方法类型--%>
+            <%--    dataType:"json",--%>
+            <%--    url: "${ctx}/product/keywordFrequency/getSeacherFrom?trueStatus=1" ,//url--%>
+            <%--    success: function (data) {--%>
+            <%--        $('#search').get(0).options.length = 0;--%>
+            <%--        $('#search').append('<option value="" aria-selected="true">请选择</option>');--%>
+            <%--        $.each(data, function(i, obj) {--%>
+            <%--            var option = $('<option />');--%>
+            <%--            option.val(obj);--%>
+            <%--            if(obj==1){--%>
+            <%--                option.text("首页搜索");--%>
+            <%--            }else if(obj==2){--%>
+            <%--                option.text("信息中心搜索");--%>
+            <%--            }else if(obj==3){--%>
+            <%--                option.text("美业资料搜索");--%>
+            <%--            }else if(obj==4){--%>
+            <%--                option.text("采美百科搜索");--%>
+            <%--            }else if(obj==6){--%>
+            <%--                option.text("管理员添加");--%>
+            <%--            }--%>
+            <%--            $('#search').append(option);--%>
+            <%--        });--%>
+            <%--    },--%>
+            <%--    error : function() {--%>
+            <%--        alert("服务异常!");--%>
+            <%--    }--%>
+            <%--});--%>
+        }
+        //选中所有
+        function allCkbfun(ckb){
+            var isChecked = ckb.checked;
+            $(".check-item").attr('checked', isChecked);
+            if(true==isChecked){
+                $(".check-item").parents(".item-info").addClass("row-selected");
+            }else{
+                $(".check-item").parents(".item-info").removeClass("row-selected");
+            }
+        }
+        //复选框选单击事件
+        function checkfun(ckb){
+            var isChecked = ckb.checked;
+            if(true==isChecked){
+                $(ckb).parents(".item-info").addClass("row-selected");
+            }else{
+                $(ckb).parents(".item-info").removeClass("row-selected");
+            }
+        }
+        //加入关键词库
+        function updateEnabledStatus(ids){
+            var msg='确定加入关键词库?';
+            // if('0'==status){
+            //     msg='确定停用?';
+            // }
+            top.$.jBox.confirm(msg,'系统提示',function(v){
+                if(v=='ok'){
+                    $.post("${ctx}/product/keywordFrequency/addKeyWordList",{'ids':ids}, function(data) {
+                        $("#searchForm").submit();
+                    },"JSON");//这里返回的类型有:json,html,xml,text
+                }
+                top.$.jBox.tip('加入关键词库成功', 'success');
+                // window.location.reload();
+                window.location.href = "${ctx}/product/keywordFrequency/getKeyInfo";
+                return;
+            });
+        }
+        //删除关键词
+        function delEnabledStatus(ids){
+            var msg='确定删除关键词?';
+            // if('0'==status){
+            //     msg='确定停用?';
+            // }
+            top.$.jBox.confirm(msg,'系统提示',function(v,h,f){
+                if(v=='ok'){
+                    $.post("${ctx}/product/keywordFrequency/delKeyWordById",{'id':ids}, function(data) {
+                        $("#searchForm").submit();
+                    },"JSON");//这里返回的类型有:json,html,xml,text
+                }
+                // top.$.jBox.tip('删除成功', 'success');
+                // window.location.reload();
+                return;
+            },{buttonsFocus:1,persistent: true});
+        }
+        function updateStatus(){
+            var items = new Array();
+            $items=$('.check-item:checked');
+            if(0==$items.length){
+                top.$.jBox.tip('请选择需要加入关键词库的数据', 'error');
+                return;
+            }
+            $items.each(function(i){
+                items.push($(this).parents(".item-info").attr("id"));
+            });
+            updateEnabledStatus(items.toString());
+        }
+        function getSelectKeywords(){
+            var items = new Array();
+            $items=$('.check-item:checked');
+            if(0==$items.length){
+                top.$.jBox.tip('请选择需要导出的关键词', 'error');
+                return;
+            }
+            $items.each(function(i){
+                items.push($(this).parents(".item-info").attr("id"));
+            });
+            exportKeyword(items.toString());
+        }
+        //导出关键词
+           function exportKeyword(ids){
+                window.location.href = "${ctx}/product/keywordFrequency/export?ids=" + ids;
+           }
+
+        <%--function verification(key){--%>
+        <%--    return new Promise(function(resolve, reject){--%>
+        <%--        $.ajax({--%>
+        <%--            //几个参数需要注意一下--%>
+        <%--            type: "get",//方法类型--%>
+        <%--            dataType:"json",--%>
+        <%--            url: "${ctx}/product/keywordFrequency/verificationKeword?keyword="+key ,//url--%>
+        <%--            success: function (data) {--%>
+        <%--                resolve('ok')--%>
+        <%--                if(data=="-1"){--%>
+        <%--                    reject('关键词已存在')--%>
+        <%--                }else{--%>
+        <%--                    resolve()--%>
+        <%--                }--%>
+        <%--            },--%>
+        <%--            error : function() {--%>
+        <%--                alert("服务异常!");--%>
+        <%--            }--%>
+        <%--        });--%>
+        <%--    })--%>
+        <%--}--%>
+
+        function verification(key){
+            return new Promise(function(resolve, reject){
+                $.ajax({
+                    //几个参数需要注意一下
+                    type: "get",//方法类型
+                    dataType:"json",
+                    url: "${ctx}/product/keywordFrequency/verificationKeword?keyword="+key ,//url
+                    success: function (data) {
+                        console.log('verification', data)
+                        if(data=="-1"){
+                            resolve('faild')
+                        }else{
+                            resolve('ok')
+                        }
+                    },
+                    error : function() {
+                        reject('服务器异常')
+                    }
+                });
+            })
+        }
+
+        function joinKeywordLibrary(keyId){
+            <%--return new Promise(function(resolve, reject){--%>
+            <%--    $.ajax({--%>
+            <%--        //几个参数需要注意一下--%>
+            <%--        type: "get",//方法类型--%>
+            <%--        dataType:"json",--%>
+            <%--        url: "${ctx}/product/keywordFrequency/addKeyWordList?ids=" + keyId ,//url--%>
+            <%--        success: function (data) {--%>
+            <%--            console.log('joinKeywordLibrary', data)--%>
+            <%--            resolve()--%>
+            <%--        },--%>
+            <%--        error : function() {--%>
+            <%--            reject('加入关键词库失败')--%>
+            <%--        }--%>
+            <%--    });--%>
+            <%--})--%>
+
+        }
+
+        async  function onJoinKeywordLibrary(keyId, key){
+            try{
+                const result = await verification(key)
+                if(result !== 'ok'){
+                    return confirm('该关键词在关键键词词库已存在!')
+                }
+                const confirmRes = confirm('确认将关键词加入关键词库吗?')
+                console.log('confirmRes', confirmRes)
+                if(!confirmRes){
+                    return
+                }
+                // await joinKeywordLibrary(keyId)
+                await fetch("${ctx}/product/keywordFrequency/addKeyWordList?ids=" + keyId)
+                top.$.jBox.tip('添加成功', 'success');
+                window.location.href = '${ctx}/product/keywordFrequency/getKeyInfo/' ;
+            }catch (e){
+                alert(e)
+            }
+        }
+    </script>
+</head>
+<body>
+<ul class="nav nav-tabs">
+    <li class="active">用户关键词统计</li>
+<%--    <shiro:hasPermission name="user:newCmClub:edit"><li><a href="${ctx}/new/user/cmSp/cmSpForm">添加协销人员</a></li></shiro:hasPermission>--%>
+<%--    <li><a href="${ctx}/serviceteam/cmServiceteamRole/">协销小组</a></li>--%>
+<%--    <li><a href="${ctx}/new/user/cmSp/leader/">协销总管理员</a></li>--%>
+</ul>
+<form:form id="searchForm" modelAttribute="searchFrequency" action="${ctx}/product/keywordFrequency/getKeyInfo/" method="post" class="breadcrumb form-search">
+    <sys:message content="${message}"/>
+    <input id="pageNo" name="pageNo" type="hidden" value="${pageNo}"/>
+    <input id="pageSize" name="pageSize" type="hidden" value="${pageSize}"/>
+    <div class="ul-form">
+        <label>关键词:</label>
+        <form:input path="keyword" htmlEscape="false" maxlength="20" class="input-medium"/>
+        <label>来源:</label>
+        <form:select path="fromSearch" class="input-medium" id="search">
+            <form:option value="" label="请选择"/>
+            <form:option value="1" label="首页搜索"/>
+            <form:option value="2" label="信息中心搜索"/>
+            <form:option value="3" label="美业资料搜索"/>
+            <form:option value="4" label="采美百科"/>
+            <form:option value="6" label="管理员添加"/>
+            <%--            <form:options items="${seacherFrom}" itemLabel="fromSearch" itemValue="id"--%>
+<%--                          htmlEscape="false"/>--%>
+        </form:select>
+        &nbsp;&nbsp;<input id="btnSubmit" class="btn btn-primary" type="submit" value="查询"/>
+        &nbsp;&nbsp;<input id="addKeyWord" class="btn btn-primary" type="button" value="加入关键词库" onclick="updateStatus()"/>
+        &nbsp;&nbsp;<input id="export" class="btn btn-primary" type="button" value="导出" onclick="getSelectKeywords()"/>
+    </div>
+</form:form>
+<table id="contentTable" class="table table-striped table-bordered table-condensed">
+    <thead>
+    <tr>
+        <th style="width:20px;"><input class="check-all" type="checkbox" onclick="allCkbfun(this);"/></th>
+        <th>序号</th>
+        <th>关键词</th>
+        <th>搜索来源</th>
+        <th>搜索次数</th>
+        <shiro:hasPermission name="user:newCmClub:edit"><th>操作</th></shiro:hasPermission>
+    </tr>
+    </thead>
+    <tbody>
+    <c:forEach items="${keyInfo.list}" var="newCmSp" varStatus="status">
+        <tr class="item-info" id="${newCmSp.keyId}">
+            <td><input class="check-item" type="checkbox" id="checkbox" value="" onclick="checkfun(this)"/></td>
+            <td>${status.index+1}</td>
+                <%--<td>${newCmSp.name}</td>--%>
+            <td>${newCmSp.keyword}</td>
+            <td>
+                <c:if test="${newCmSp.fromSearch eq 1}">
+                    首页搜索
+                </c:if>
+                <c:if test="${newCmSp.fromSearch eq 2}">
+                    信息中心搜索
+                </c:if>
+                <c:if test="${newCmSp.fromSearch eq 3}">
+                    美业资料搜索
+                </c:if>
+                <c:if test="${newCmSp.fromSearch eq 4}">
+                    采美百科搜索
+                </c:if>
+                <c:if test="${newCmSp.fromSearch eq 6}">
+                    管理员添加
+                </c:if>
+            </td>
+                <%--<td>${newCmSp.spIdentity}</td>--%>
+            <td>${newCmSp.frequency}</td>
+            <shiro:hasPermission name="user:newCmClub:edit">
+                <td>
+<%--                    <c:if test="${newCmSp.status eq 90 || newCmSp.status eq 91}">--%>
+<%--                        onclick="updatePwd(${newCmSp.serviceProviderID})"--%>
+<%--                        <a onclick="updateEnabledStatus('${newCmSp.keyId}')">加入关键词库</a>--%>
+<%--                        <a href="${ctx}/product/keywordFrequency/addKeyWordList?ids=${newCmSp.keyId}" onclick="return confirmx('确认将关键词加入关键词库吗?', this.href)">加入关键词库</a>--%>
+                            <a href="javascript:void(0);" onclick="onJoinKeywordLibrary(${newCmSp.keyId},'${newCmSp.keyword}')">加入关键词库</a>
+<%--                         <a href="${ctx}/product/keywordFrequency/addKeyWordList?ids=${newCmSp.keyId}" onclick="verification('${newCmSp.keyword}')">加入关键词库</a>--%>
+
+<%--                        href="${ctx}/new/user/cmSp/cmSpEdit?id=${newCmSp.serviceProviderID}"--%>
+                        <a href="${ctx}/product/keywordFrequency/form?keyId=${newCmSp.keyId}&status=1&keyword=${newCmSp.keyword}">编辑</a>
+
+<%--                        onclick="sendMsg(${newCmSp.serviceProviderID})"--%>
+                            <a href="${ctx}/product/keywordFrequency/delKeyWordById?id=${newCmSp.keyId}&status=1" onclick="return confirmx('确认要删除该关键词吗?', this.href)">删除</a>
+<%--                        <a href="javascript:void(0);" onclick="delEnabledStatus('${newCmSp.keyId}')">删除</a>--%>
+<%--                        <a href="${ctx}/product/keywordFrequency/delKeyWordById?id=${newCmSp.keyId}">删除2</a>--%>
+
+<%--                    </c:if>--%>
+                </td>
+            </shiro:hasPermission>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+<div class="pagination">${keyInfo}</div>
+</body>
+</html>
+

+ 275 - 0
src/main/webapp/WEB-INF/views/modules/product/keywordThesaurus.jsp

@@ -0,0 +1,275 @@
+<%--
+  Created by IntelliJ IDEA.
+  User: Administrator
+  Date: 2020/4/12
+  Time: 12:01
+  To change this template use File | Settings | File Templates.
+--%>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+    <title>词库列表</title>
+    <meta http-equiv="Content-Type" content="multipart/form-data;charset=utf-8" />
+    <meta name="decorator" content="default"/>
+    <style type="text/css">
+        .table th{text-align: center;}
+        .table td{text-align: center;}
+    </style>
+    <script type="text/javascript">
+        $(document).ready(function() {
+            $("#btnImport").click(function(){
+                // //获取id为up_file的input的值
+                // var fileName = document.getElementById("up_file").value;
+                // alert(fileName);
+                //
+                // //截取文件后缀名
+                // var file_suffix = fileName.substr(fileName.length-3);
+                //
+                // //弹出后缀名
+                // alert(file_suffix);
+                // if(file_suffix != "dll"){
+                //     alert("您上传的文件类型不被允许,请重传,只允许上传.dll文件");
+                //     return false;
+                // }
+                $.jBox($("#importBox").html(), {title:"导入数据", buttons:{"关闭":true},
+                    bottomText:"导入文件不能超过5M,仅允许导入“xls”或“xlsx”格式文件!"});
+            });
+        });
+
+        function aaa(){
+            var fileName = document.getElementById("uploadFile").value;
+            // if(1==1){
+            //     alert('请选择需要导入的文件', 'error');
+            //     return false;
+            // }
+            return true;
+        }
+        function page(n,s){
+            $("#pageNo").val(n);
+            $("#pageSize").val(s);
+            $("#searchForm").submit();
+            return false;
+        }
+        window.onload = function () {
+            <%--$.ajax({--%>
+            <%--    //几个参数需要注意一下--%>
+            <%--    type: "get",//方法类型--%>
+            <%--    dataType:"json",--%>
+            <%--    url: "${ctx}/product/keywordFrequency/getSeacherFrom?trueStatus=1" ,//url--%>
+            <%--    success: function (data) {--%>
+            <%--        $('#search').get(0).options.length = 0;--%>
+            <%--        $('#search').append('<option value="" aria-selected="true">请选择</option>');--%>
+            <%--        $.each(data, function(i, obj) {--%>
+            <%--            var option = $('<option />');--%>
+            <%--            option.val(obj);--%>
+            <%--            if(obj==1){--%>
+            <%--                option.text("首页搜索");--%>
+            <%--            }else if(obj==2){--%>
+            <%--                option.text("信息中心搜索");--%>
+            <%--            }else if(obj==3){--%>
+            <%--                option.text("美业资料搜索");--%>
+            <%--            }else if(obj==4){--%>
+            <%--                option.text("采美百科搜索");--%>
+            <%--            }else if(obj==6){--%>
+            <%--                option.text("管理员添加");--%>
+            <%--            }--%>
+            <%--            $('#search').append(option);--%>
+            <%--        });--%>
+            <%--    },--%>
+            <%--    error : function() {--%>
+            <%--        alert("服务异常!");--%>
+            <%--    }--%>
+            <%--});--%>
+        }
+        //选中所有
+        function allCkbfun(ckb){
+            var isChecked = ckb.checked;
+            $(".check-item").attr('checked', isChecked);
+            if(true==isChecked){
+                $(".check-item").parents(".item-info").addClass("row-selected");
+            }else{
+                $(".check-item").parents(".item-info").removeClass("row-selected");
+            }
+        }
+        //复选框选单击事件
+        function checkfun(ckb){
+            var isChecked = ckb.checked;
+            if(true==isChecked){
+                $(ckb).parents(".item-info").addClass("row-selected");
+            }else{
+                $(ckb).parents(".item-info").removeClass("row-selected");
+            }
+        }
+        //加入关键词库
+        function updateEnabledStatus(ids){
+            var msg='确定加入关键词库?';
+            // if('0'==status){
+            //     msg='确定停用?';
+            // }
+            top.$.jBox.confirm(msg,'系统提示',function(v,h,f){
+                if(v=='ok'){
+                    $.post("${ctx}/product/keywordFrequency/addKeyWordList",{'ids':ids}, function(data) {
+                        $("#searchForm").submit();
+                    },"JSON");//这里返回的类型有:json,html,xml,text
+                }
+                // top.$.jBox.tip('加入关键词库成功', 'success');
+                // window.location.reload();
+                return;
+            },{buttonsFocus:1,persistent: true});
+        }
+        //删除关键词
+        <%--function delEnabledStatus(ids){--%>
+        <%--    var msg='确定删除关键词?';--%>
+        <%--    // if('0'==status){--%>
+        <%--    //     msg='确定停用?';--%>
+        <%--    // }--%>
+        <%--    top.$.jBox.confirm(msg,'系统提示',function(v,h,f){--%>
+        <%--        if(v=='ok'){--%>
+        <%--            $.post("${ctx}/product/keywordFrequency/delKeyWordById",{'id':ids}, function(data) {--%>
+        <%--                $("#searchForm").submit();--%>
+        <%--            },"JSON");//这里返回的类型有:json,html,xml,text--%>
+        <%--        }--%>
+        <%--        // top.$.jBox.tip('删除成功', 'success');--%>
+        <%--        // window.location.reload();--%>
+        <%--        return;--%>
+        <%--    },{buttonsFocus:1,persistent: true});--%>
+        <%--}--%>
+        function updateStatus(){
+            var items = new Array();
+            $items=$('.check-item:checked');
+            if(0==$items.length){
+                top.$.jBox.tip('请选择', 'error');
+                return;
+            }
+            $items.each(function(i){
+                items.push($(this).parents(".item-info").attr("id"));
+            });
+            updateEnabledStatus(items.toString());
+        }
+        // //添加关键词
+        // function addkeyWord(){
+        //
+        // }
+        function getSelectKeywords(){
+            var items = new Array();
+            $items=$('.check-item:checked');
+            if(0==$items.length){
+                top.$.jBox.tip('请选择需要导出的关键词', 'error');
+                return;
+            }
+            $items.each(function(i){
+                items.push($(this).parents(".item-info").attr("id"));
+            });
+            exportKeyword(items.toString());
+        }
+        //导出关键词
+        function exportKeyword(ids){
+            window.location.href = "${ctx}/product/keywordFrequency/exportThesaurus?ids=" + ids;
+        }
+    </script>
+</head>
+<body>
+<div id="importBox" class="hide">
+    <form id="importForm" action="${ctx}/product/keywordFrequency/importKeyword" method="post" enctype="multipart/form-data"
+          class="form-search" style="padding-left:20px;text-align:center;" onsubmit="loading('正在导入,请稍等...');"><br/>
+        <input id="uploadFile" name="file" type="file" style="width:330px"/><br/><br/>  
+        <input id="btnImportSubmit" class="btn btn-primary" type="submit" onclick=" return aaa('this.f')" value="   导    入   "/>
+<%--        <a href="${ctx}/sys/user/import/template">下载模板</a>--%>
+    </form>
+</div>
+<ul class="nav nav-tabs">
+    <li class="active">关键词词库</li>
+    <%--    <shiro:hasPermission name="user:newCmClub:edit"><li><a href="${ctx}/new/user/cmSp/cmSpForm">添加协销人员</a></li></shiro:hasPermission>--%>
+    <%--    <li><a href="${ctx}/serviceteam/cmServiceteamRole/">协销小组</a></li>--%>
+    <%--    <li><a href="${ctx}/new/user/cmSp/leader/">协销总管理员</a></li>--%>
+</ul>
+
+<form:form id="searchForm" modelAttribute="searchFrequency" action="${ctx}/product/keywordFrequency/getKeywordThesaurusInfo/" method="post" class="breadcrumb form-search">
+    <sys:message content="${message}"/>
+    <input id="pageNo" name="pageNo" type="hidden" value="${pageNo}"/>
+    <input id="pageSize" name="pageSize" type="hidden" value="${pageSize}"/>
+    <div class="ul-form">
+        <label>关键词:</label>
+        <form:input path="keyword" htmlEscape="false" maxlength="20" class="input-medium"/>
+<%--        <label>来源:</label>--%>
+<%--        <form:select path="fromSearch" class="input-medium" id="search">--%>
+<%--            <form:option value="" label="请选择"/>--%>
+<%--            <form:option value="1" label="首页搜索"/>--%>
+<%--            <form:option value="2" label="信息中心搜索"/>--%>
+<%--            <form:option value="3" label="美业资料搜索"/>--%>
+<%--            <form:option value="4" label="采美百科"/>--%>
+<%--            <form:option value="6" label="管理员添加"/>--%>
+<%--        </form:select>--%>
+        &nbsp;&nbsp;<input id="btnSubmit" class="btn btn-primary" type="submit" value="查询"/>
+<%--        &nbsp;&nbsp;<input id="addKeyWord" class="btn btn-primary" type="button" value="加入关键词库" onclick="updateStatus()"/>--%>
+        &nbsp;&nbsp;<input id="addKey" class="btn btn-primary" type="button" value="添加关键词" onclick="window.location='${ctx}/product/keywordFrequency/form?status=2'"/>
+<%--        &nbsp;&nbsp;<input id="import" class="btn btn-primary" type="file" value="导入" onclick="window.location='${ctx}/product/keywordFrequency/importKeyword'"/>--%>
+        <input id="btnImport" class="btn btn-primary" type="button" value="导入"/></li>
+        &nbsp;&nbsp;<input id="export" class="btn btn-primary" type="button" value="导出" onclick="getSelectKeywords()"/>
+
+    </div>
+</form:form>
+<table id="contentTable" class="table table-striped table-bordered table-condensed">
+    <thead>
+    <tr>
+        <th style="width:20px;"><input class="check-all" type="checkbox" onclick="allCkbfun(this);"/></th>
+        <th>序号</th>
+        <th>关键词</th>
+<%--        <th>搜索来源</th>--%>
+        <th>联动词搜索次数</th>
+        <th>添加时间</th>
+        <shiro:hasPermission name="user:newCmClub:edit"><th>操作</th></shiro:hasPermission>
+    </tr>
+    </thead>
+    <tbody>
+    <c:forEach items="${keyInfo.list}" var="newCmSp" varStatus="status">
+        <tr class="item-info" id="${newCmSp.keyId}">
+            <td><input class="check-item" type="checkbox" id="checkbox" value="" onclick="checkfun(this)"/></td>
+            <td>${status.index+1}</td>
+                <%--<td>${newCmSp.name}</td>--%>
+            <td>${newCmSp.keyword}</td>
+<%--            <td>--%>
+<%--                <c:if test="${newCmSp.fromSearch eq 1}">--%>
+<%--                    首页搜索--%>
+<%--                </c:if>--%>
+<%--                <c:if test="${newCmSp.fromSearch eq 2}">--%>
+<%--                    信息中心搜索--%>
+<%--                </c:if>--%>
+<%--                <c:if test="${newCmSp.fromSearch eq 3}">--%>
+<%--                    美业资料搜索--%>
+<%--                </c:if>--%>
+<%--                <c:if test="${newCmSp.fromSearch eq 4}">--%>
+<%--                    采美百科搜索--%>
+<%--                </c:if>--%>
+<%--                <c:if test="${newCmSp.fromSearch eq 6}">--%>
+<%--                    管理员添加--%>
+<%--                </c:if>--%>
+<%--            </td>--%>
+            <td>${newCmSp.linkageFrequency}</td>
+            <td>${newCmSp.serachDate}</td>
+            <shiro:hasPermission name="user:newCmClub:edit">
+                <td>
+                        <%--                    <c:if test="${newCmSp.status eq 90 || newCmSp.status eq 91}">--%>
+                        <%--                        onclick="updatePwd(${newCmSp.serviceProviderID})"--%>
+<%--                    <a onclick="updateEnabledStatus('${newCmSp.keyId}')">加入关键词库</a>--%>
+                        <%--                        href="${ctx}/new/user/cmSp/cmSpEdit?id=${newCmSp.serviceProviderID}"--%>
+                    <a href="${ctx}/product/keywordFrequency/form?keyId=${newCmSp.keyId}&status=2&keyword=${newCmSp.keyword}">编辑</a>
+
+                        <%--                        onclick="sendMsg(${newCmSp.serviceProviderID})"--%>
+
+<%--                    <a href="javascript:void(0);" onclick="delEnabledStatus('${newCmSp.keyId}')">删除</a>--%>
+                    <a href="${ctx}/product/keywordFrequency/delKeyWordById?id=${newCmSp.keyId}&status=2" onclick="return confirmx('确认要删除该关键词吗?', this.href)">删除</a>
+
+                        <%--                    </c:if>--%>
+                </td>
+            </shiro:hasPermission>
+        </tr>
+    </c:forEach>
+    </tbody>
+</table>
+<div class="pagination">${keyInfo}</div>
+</body>
+</html>
+

+ 46 - 0
src/main/webapp/WEB-INF/views/modules/product/upkeyword.jsp

@@ -0,0 +1,46 @@
+<%@ page contentType="text/html;charset=UTF-8" %>
+<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
+<html>
+<head>
+    <title>关键词更新</title>
+    <meta name="decorator" content="default"/>
+    <script type="text/javascript">
+        $(document).ready(function() {
+            //$("#name").focus();
+            $("#inputForm").validate({
+                submitHandler: function(form){
+                    loading('正在提交,请稍等...');
+                    form.submit();
+                },
+            });
+        });
+    </script>
+</head>
+<body>
+<ul class="nav nav-tabs">
+    <c:if test="${searchFrequency.status eq '1'}">
+        <li><a href="${ctx}/product/keywordFrequency/getKeyInfo">用户关键词统计</a></li>
+    </c:if>
+    <c:if test="${searchFrequency.status eq '2'}">
+        <li><a href="${ctx}/product/keywordFrequency/getKeywordThesaurusInfo">词库列表</a></li>
+    </c:if>
+<%--    <li><a href="${ctx}/product/keywordFrequency/getKeyInfo">用户关键词统计</a></li>--%>
+<%--    <li class="active"><a href="${ctx}/order/cmAuthorizedConsignment/form?id=${cmAuthorizedConsignment.id}"><shiro:hasPermission name="order:cmAuthorizedConsignment:edit">${not empty cmAuthorizedConsignment.id?'编辑':'添加'}</shiro:hasPermission><shiro:lacksPermission name="order:cmAuthorizedConsignment:edit">查看</shiro:lacksPermission></a></li>--%>
+    <li class="active"><a href="${ctx}/product/keywordFrequency/form?keyId=${searchFrequency.keyId}&status=${searchFrequency.status}"><shiro:hasPermission name="order:cmAuthorizedConsignment:edit">${not empty searchFrequency.keyId?'编辑':'添加'}</shiro:hasPermission><shiro:lacksPermission name="order:cmAuthorizedConsignment:edit">查看</shiro:lacksPermission></a></li>
+</ul><br/>
+<form:form id="inputForm" modelAttribute="searchFrequency" action="${ctx}/product/keywordFrequency/save?status=${searchFrequency.status}" method="post" class="form-horizontal">
+    <form:hidden path="keyId"/>
+    <sys:message content="${message}"/>
+    <div class="control-group">
+        <label class="control-label"><font color="red">*</font>关键词:</label>
+        <div class="controls">
+            <form:input path="keyword" htmlEscape="false" maxlength="20" class="input-xlarge required" value="${searchFrequency.keyword}"/>
+        </div>
+    </div>
+    <div class="form-actions">
+        <shiro:hasPermission name="order:cmAuthorizedConsignment:edit"><input id="btnSubmit" class="btn btn-primary" type="submit" value="保 存"/>&nbsp;</shiro:hasPermission>
+        <input id="btnCancel" class="btn" type="button" value="返 回" onclick="history.go(-1)"/>
+    </div>
+</form:form>
+</body>
+</html>

+ 233 - 0
src/main/webapp/static/auto-input.js

@@ -0,0 +1,233 @@
+"use strict";
+
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
+
+function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
+
+var AutoComplete =
+    /*#__PURE__*/
+    function () {
+        function AutoComplete(options) {
+            _classCallCheck(this, AutoComplete);
+
+            this.options = {
+                el: '#autoInput',
+                callback: function callback(text) {
+                    return [];
+                },
+                itemClick: function itemClick() {
+                    return [];
+                },
+                itemTop: 'auto',
+                follow: 'input',
+                offsetTop: 5,
+                offsetLeft: 0,
+            };
+            Object.assign(this.options, options);
+            this.handleInput = this.debounce(this.inputEvent).bind(this);
+            this.handleBlur = this.debounce(this.blurEvent).bind(this);
+            this.init();
+        }
+        /**
+         * 初始化dom
+         */
+
+
+        _createClass(AutoComplete, [{
+            key: "init",
+            value: function init() {
+                this.container = document.querySelector(this.options.el);
+                this.inputList = this.container.querySelectorAll('input');
+                this.ul = document.createElement('ul');
+                this.ul.style.display = 'none';
+                this.container.appendChild(this.ul);
+                this.inputBindEvent();
+                this.initStyle();
+            }
+            /**
+             * 为input绑定focus事件
+             */
+
+        }, {
+            key: "inputBindEvent",
+            value: function inputBindEvent() {
+                var _this = this;
+
+                if (this.inputList.length === 0) return;
+                this.inputList.forEach(function (input) {
+                    input.addEventListener('focus', function () {
+                        _this.input = input;
+
+                        _this.setUlStyle();
+                    });
+                    input.addEventListener('input', _this.handleInput);
+                    input.addEventListener('blur', _this.handleBlur);
+                });
+            }
+            /**
+             * 初始化样式
+             */
+
+        }, {
+            key: "initStyle",
+            value: function initStyle() {
+                var containerStyle = getComputedStyle(this.container);
+
+                if (containerStyle.position === 'static') {
+                    this.container.style.position = 'relative';
+                }
+
+                this.container.style.zIndex = '99';
+
+                const style = document.createElement('style');
+                style.textContent = `
+                .auto-input ul { position: absolute; padding: 16px 0; background: #fff; user-select: none; max-height: 400px; overflowY: auto;border:1px solid #eee;z-index:999;overflow-y:auto;overflow-x:auto;}
+                .auto-input ul li { padding: 0 16px; font-size: 16px; line-height: 42px; color: #2c3e50; }
+                .auto-input ul li:hover { background: #ecf0f1; }
+                `
+                this.container.appendChild(style);
+            }
+            /**
+             * 初始化样式
+             */
+
+        }, {
+            key: "setUlStyle",
+            value: function setUlStyle() {
+                if (this.options.itemTop === 'auto') {
+                    var inputHeight = this.input.offsetHeight;
+                    var inputTop = this.input.offsetTop;
+                    this.ul.style.top = inputHeight + inputTop + this.options.offsetTop + 'px';
+                } else {
+                    this.ul.style.top = this.options.itemTop;
+                }
+
+                if (this.options.follow === 'input') {
+                    this.ul.style.left = this.input.offsetLeft + this.options.offsetLeft + 'px';
+                    this.ul.style.width = this.input.offsetWidth + 'px';
+                } else {
+                    this.ul.style.left = 0;
+                    this.ul.style.width = this.ul.offsetWidth + 'px';
+                }
+            }
+            /**
+             * 输入框input事件
+             */
+
+        }, {
+            key: "inputEvent",
+            value: function inputEvent(e) {
+                var keyword = e.target.value;
+                this.list = this.options.callback(keyword);
+
+                if (!(this.list instanceof Array)) {
+                    throw Error('callback result mast an array');
+                }
+
+                this.ul.style.display = this.list.length > 0 ? 'block' : 'none';
+                this.ul.innerHTML = '';
+                this.renderList();
+            }
+            /**
+             * 输入框blur事件
+             */
+
+        }, {
+            key: "blurEvent",
+            value: function blurEvent() {
+                this.ul.style.display = 'none';
+            }
+            /**
+             * 渲染列表
+             */
+
+        }, {
+            key: "renderList",
+            value: function renderList() {
+                var _this2 = this;
+
+                this.list.forEach(function (text) {
+                    var li = document.createElement('li');
+                    li.innerText = text;
+                    li.addEventListener('click', function () {
+                        return _this2.listItemClick(text);
+                    });
+
+                    _this2.ul.appendChild(li);
+                });
+            }
+            /**
+             * 列表元素点击事件
+             */
+
+        }, {
+            key: "listItemClick",
+            value: function listItemClick(text) {
+                this.input.value = text;
+                this.ul.innerHTML = '';
+                this.ul.style.display = 'none';
+            }
+            /**
+             * 防抖
+             */
+
+        }, {
+            key: "debounce",
+            value: function debounce(func) {
+                var wait = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 200;
+                var immediate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+                var timeout, result;
+                return function () {
+                    var context = this;
+                    var args = arguments;
+                    if (timeout) clearTimeout(timeout);
+
+                    if (immediate) {
+                        var callNow = !timeout;
+                        timeout = setTimeout(function () {
+                            timeout = null;
+                        }, wait);
+                        if (callNow) result = func.apply(context, args);
+                    } else {
+                        timeout = setTimeout(function () {
+                            func.apply(context, args);
+                        }, wait);
+                    }
+
+                    return result;
+                };
+            }
+        }]);
+
+        return AutoComplete;
+    }();
+
+// function autocomplete(text) {
+//     $.ajax({
+//         //几个参数需要注意一下
+//         type: "get",//方法类型
+//         dataType:"json",
+//         url: "${ctx}/product/new/keywordLinkage" ,//url
+//         success: function (data) {
+//             // return  data.filter(function (item) {
+//             //               return text && item.indexOf(text) > -1;
+//             //           });
+//             alert(data);
+//         },
+//         error : function() {
+//             alert("服务异常!");
+//         }
+//     });
+//     return ['三全鲜食(北新泾店)', 'Hot honey 首尔炸鸡(仙霞路)', '新旺角茶餐厅', '泷千家(天山西路店)', '胖仙女纸杯蛋糕(上海凌空店)', '贡茶', '豪大大香鸡排超级奶爸', '茶芝兰(奶茶,手抓饼)', '十二泷町', '星移浓缩咖啡', '阿姨奶茶/豪大大', '新麦甜四季甜品炸鸡', 'Monica摩托主题咖啡店', '浮生若茶(凌空soho店)', 'NONO JUICE  鲜榨果汁', 'CoCo都可(北新泾店)', '快乐柠檬(神州智慧店)', 'Merci Paul cafe', '猫山王(西郊百联店)', '枪会山', '纵食', '钱记', '壹杯加', '唦哇嘀咖', '爱茜茜里(西郊百联)', '爱茜茜里(近铁广场)', '鲜果榨汁(金沙江路和美广店)', '开心丽果(缤谷店)', '超级鸡车(丰庄路店)', '妙生活果园(北新泾店)', '香宜度麻辣香锅', '凡仔汉堡(老真北路店)', '港式小铺', '蜀香源麻辣香锅(剑河路店)', '北京饺子馆', '饭典*新简餐(凌空SOHO店)', '焦耳·川式快餐(金钟路店)', '动力鸡车', '浏阳蒸菜', '四海游龙(天山西路店)', '樱花食堂(凌空店)', '壹分米客家传统调制米粉(天山店)', '福荣祥烧腊(平溪路店)', '速记黄焖鸡米饭', '红辣椒麻辣烫', '(小杨生煎)西郊百联餐厅', '阳阳麻辣烫', '南拳妈妈龙虾盖浇饭'].filter(function (item) {
+//         return text && item.indexOf(text) > -1;
+//     });
+//
+// }
+//
+// new AutoComplete({
+//     el: '.auto-input',
+//     callback: autocomplete
+// });