Explorar o código

关键词1.0版本功能开发
商品管理编辑页面添加关键词联动

JiangChongBo %!s(int64=2) %!d(string=hai) anos
pai
achega
b8d7990929

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

@@ -11,39 +11,39 @@ import java.sql.Timestamp;
  */
 @Data
 public class SearchFrequencyVo{
-       private Integer id ;
-    /**
-     * 数据来源(1:首页;2:信息中心)
-     */
-    private Integer fromSearch   ;
-    /**
-     * 接口路径
-     */
-    private String  path;
+//       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;
+//    /**
+//     * 关键词出现次数
+//     */
+//    private Integer  frequency ;
+//    /**
+//     * 搜索时间
+//     */
+//    private Timestamp searchTime ;
+//    /**
+//     * 0:未加入关键词库;1:已加入关键词库
+//     */
+//    private Integer trueStatus;
+//
+//    /**
+//     * 0:已删除;1未删除
+//     */
+//    private Integer delStatus;
+//    /**
+//     *  区分是关键词界面还是关键词库界面 (1关键词;2关键词库)
+//     */
+//    private Integer status;
 
 }

+ 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) {
         // 组合搜索关键词

+ 21 - 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,24 @@
             $("#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
+    });
     function js(){
             var val = $("#productType").val();
             var mac = $("#machineType").val();

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

@@ -0,0 +1,232 @@
+"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
+            };
+            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-25 + '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
+// });