1. 程式人生 > >品優購專案記錄:day11

品優購專案記錄:day11

今日目標:

(1)實現品優購價格區間篩選功能

(2)實現搜尋結果分頁功能

(3)理解多關鍵字搜尋

(4)實現搜尋結果排序功能

(5)實現隱藏品牌列表功能

(6)實現搜尋頁與首頁對接功能

(7)完成更新索引庫的功能

目錄

1.2 前端

1.3 後端

2.2 後端

2.3 前端

3、排序

4.2 前端

1、按價格區間篩選

1.1 需求分析

點選搜尋面板上的價格區間,實現按價格篩選

1.2 前端

(1)修改goodsController.js中的新增和移除選項方法

(2)頁面繫結變數和單擊事件

注意:需要初始化price

(3)繫結麵包屑變數

1.3 後端

(1)服務層實現(search-service),修改setFilterOptions方法,在方法末尾加入程式碼

        // 設定價格區間
        if (!searchMap.get("price").equals("")) {
            // 處理條件
            String[] price = ((String) searchMap.get("price")).split("-");
            if (!price[0].equals("0")) {// 價格不等於0
                // 設定價格下限
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria criteria = new Criteria("item_price").greaterThanEqual(price[0]);
                filterQuery.addCriteria(criteria);
                // 設定到查詢物件中
                query.addFilterQuery(filterQuery);
            }
            if (!price[1].equals("*")) {// 有上限
                // 設定價格上限
                FilterQuery filterQuery = new SimpleFilterQuery();
                Criteria criteria = new Criteria("item_price").lessThanEqual(price[1]);
                filterQuery.addCriteria(criteria);
                // 設定到查詢物件中
                query.addFilterQuery(filterQuery);
            }
        }

(2)效果

2、搜尋結果分頁展示

2.1 需求分析

在搜尋功能基礎上實現分頁查詢

2.2 後端

(1)服務層實現(search-service),新增方法

    /**
     * 設定分頁選項,並將分頁設定給查詢物件
     *
     * @param searchMap 條件
     * @param query     查詢物件
     */
    private void setPageOptions(Map searchMap, HighlightQuery query) {
        // 獲取當前頁碼
        Integer pageNo = (Integer) searchMap.get("pageNo");
        if (pageNo == null || pageNo < 1) {
            // 預設當前頁碼為1
            pageNo = 1;
        }
        // 獲取每頁顯示記錄數
        Integer pageSize = (Integer) searchMap.get("pageSize");
        if (pageSize == null || pageSize < 1) {
            // 預設每頁記錄數為20
            pageSize = 20;
        }
        // 設定起始記錄
        query.setOffset((pageNo - 1) * pageSize);
        // 設定每頁記錄數
        query.setRows(pageSize);
    }

(2)在searchList方法中呼叫設定分頁的方法,並在返回值中新增總頁數和總記錄數

2.3 前端

(1)構建分頁標籤,在searchController.js中新增方法,並在search方法中呼叫

    // 分頁屬性
    $scope.pageLabel = [];
    buildPageLabel = function () {
        // 總頁數
        var maxPageNo = $scope.resultMap.totalPages;
        // 起始頁
        var firstPage = 1;
        // 最後一頁
        var lastPage = maxPageNo;
        if (maxPageNo > 5) {// 如果總頁數大於5
            // 判斷特殊情況
            if ($scope.searchMap.pageNo - 3 <= 0) {// 頁碼下限越界
                lastPage = 5;
            } else if ($scope.resultMap.pageNo + 2 >= lastPage) {// 頁碼上限越界
                firstPage = maxPageNo - 4;
            } else {// 正常情況
                firstPage = $scope.resultMap.pageNo - 2;
                lastPage = $scope.resultMap.pageNo + 2;
            }

        }

        // 遍歷總頁數生成分頁屬性
        for (var i = firstPage; i <= lastPage; i++) {
            $scope.pageLabel.push(i);
        }

    }

(2)頁面繫結變數,展示分頁標籤

(3)點選頁碼或者上下一頁,傳送請求,在searchController.js中新增方法

    // 分頁查詢
    $scope.searchByPage = function(pageNo){
        if (pageNo < 1 || pageNo > $scope.resultMap.totalPages) {
            return ;
        }
        // 設定當前頁碼資訊到查詢條件中
        $scope.searchMap.pageNo = pageNo;
        // 執行查詢
        $scope.search();
    }

(4)頁面繫結單擊事件

(5)輸入頁面點選確定,查詢輸入的頁碼,繫結變數和單擊事件

注意:表單輸入框輸入的值為字串,我們需要在searchController.js中的searchByPage將pageNo轉換成數字

(6)上一頁和下一頁的不可用樣式,在searchController.js中新增方法

    // 判斷當前頁是否是第一頁
    $scope.isTopPage = function () {
        if ($scope.searchMap.pageNo == 1) {
            return true;
        } else {
            return false;
        }
    }
    // 判斷當前頁是否是最後一頁
    $scope.isEndPage = function () {
        if ($scope.resultMap.totalPages == $scope.searchMap.pageNo) {
            return true;
        } else {
            return false;
        }
    }

(7)在頁面使用三元運算子進行校驗

(8)省略號的顯示

(9)每次點選查詢時,重置當前頁碼

2.4 搜尋優化

當搜尋條件中出現空格時,會很大的減少甚至搜尋不到結果,所以我們需要在後端將空格處理掉

(1)修改服務層實現,在查詢之前,把空格處理掉

3、排序

3.1 需求分析

實現價格的排序(升降序可切換)

3.2 服務層實現(search-service)

(1)在ItemSearchServiceImpl新增方法

    /**
     * 設定排序
     *
     * @param searchMap 條件
     * @param query     查詢物件
     */
    private void setSort(Map searchMap, Query query) {
        // 獲取查詢域以及排序方式
        String sortValue = (String) searchMap.get("sort");
        String sortField = (String) searchMap.get("sortField");
        // 設定排序
        if (sortValue != null && !sortValue.equals("")) {
            if(sortValue.equals("ASC")) {// 升序
                Sort sort = new Sort(Sort.Direction.ASC, "item_" + sortField);
                query.addSort(sort);
            }
            if(sortValue.equals("DESC")) {// 升序
                Sort sort = new Sort(Sort.Direction.DESC, "item_" + sortField);
                query.addSort(sort);
            }
        }
    }

(2)在searchList方法中呼叫

3.3 按價格排序 -- 前端

(1)在searchController.js中新增方法

    // 排序搜尋
    $scope.sortSearch = function (sortField, sort) {
        // 設定排序欄位和排序方式到查詢物件中
        $scope.searchMap.sort = sort;
        $scope.searchMap.sortField = sortField;
        // 執行查詢
        $scope.search();
    }

注意:在searchMap中初始化sort和sortField

(2)頁面繫結單擊事件

3.4 按新品排序 -- 前端

說明:新品就是按上架時間來降序排序

準備工作:因為我們最開始匯入solr時,並沒有這個業務域,所以我們需要新增業務域(type為date),並在實體類的updateTime上新增Field註解。然後重新將資料匯入solr索引庫

(1)檢視資料是否正確匯入索引庫

(2)頁面繫結單擊事件

3.5 按銷量排序(實現思路)

(1)增加域item_salecount 用於儲存每個SKU的銷量資料

(2)編寫定時器程式,用於更新每個SKU的銷量資料(查詢近1個月的銷量資料,不是累計資料)

(3)定時器每天只需執行一次,可以設定為凌晨開始執行。

3.6 按評價排序(實現思路)

與按銷量排序思路基本相同,有一個細節需要注意:

評論分為好評、中評、差評,我們不能簡單地將評論數相加,而是應該根據每種評論加權進行統計。比如好評的權重是3 ,中評的權重是1,而差評的權重是 -3,這樣得出的是評價的綜合得分。

4、隱藏品牌列表

4.1 需求分析

如果使用者輸入的是品牌的關鍵字,則隱藏品牌列表

4.2 前端

(1)在searchController.js中新增方法

    // 判斷關鍵字是否包含品牌資訊
    $scope.keywordsIsBrand = function () {
        // 遍歷查詢結果中的品牌列表
        for (var i = 0; i < $scope.resultMap.brandList.length; i++) {
            // 判斷keywords中是否包含品牌資訊
            if ($scope.searchMap.keywords.indexOf($scope.resultMap.brandList[i].text) > 0) {// 包含
                return true;
            }
        }
        return false;
    }

(2)頁面繫結判斷指令

5、搜尋頁與首頁對接

使用者在首頁搜尋框輸入關鍵字,點選搜尋後自動跳轉到搜尋頁展示搜尋結果

5.1 首頁工程的相關改動

(1)在portal-web工程中的contentController.js中新增方法

    // 搜尋
    $scope.search = function () {
        location.href = "http://localhost:9104/search.html#?keywords=" + $scope.keywords;
    }

(2)頁面繫結變數和單擊事件

5.2 搜尋工程的相關改動

(1)在searchControllre.js中注入location服務,並在裡面新增方法

    // 接受首頁傳送過來的關鍵字
    $scope.loadKeywords = function () {
        // 將首頁傳送的關鍵字賦值給查詢物件
        $scope.searchMap.keywords = $location.search()['keywords'];
        // 執行查詢
        $scope.search();
    }

(2)使用初始化呼叫指令呼叫該方法

(3)效果:在首頁輸入手機,點選搜尋

6、同步更新索引庫

6.1 需求分析

在進行商品稽核後更新到solr索引庫,在商品刪除後刪除solr索引庫中相應的記錄.

6.2 商家商品服務模組

(1)sellergoods-interface,在GoodsService類中新增方法

    /**
     * 按商品id陣列和狀態查詢商品SKU列表
     *
     * @param ids    商品id陣列
     * @param status 狀態
     * @return java.util.List<com.pinyougou.pojo.TbItem>
     */
    List<TbItem> findItemListByGoodsIdsAndStatus(Long[] ids, String status);

(2)sellergoods-service,在GoodsServiceImpl類中實現

    @Override
    public List<TbItem> findItemListByGoodsIdsAndStatus(Long[] ids, String status) {
        // 建立查詢條件
        TbItemExample example = new TbItemExample();
        // 封裝查詢條件
        example.createCriteria().andGoodsIdIn(Arrays.asList(ids)).andStatusEqualTo(status);

        return itemMapper.selectByExample(example);
    }

6.3 商品搜尋服務模組

(1)search-interface,在ItemSearchService類中新增方法

    /**
     * 將商品SKU資料匯入索引庫
     *
     * @param itemList 商品SKU列表
     */
    void importList(List<TbItem> itemList);

(2)search-service,在ItemSearchServiceImpl類中實現

    @Override
    public void importList(List<TbItem> itemList) {
        // 將itemList放入索引庫
        solrTemplate.saveBeans(itemList);
        solrTemplate.commit();
    }

6.4 控制層(manager-web)

(1)修改GoodsController類中的updateStatus方法,注意引入ItemSearchService的服務

7、同步刪除索引庫

7.1 商品搜尋服務模組

(1)search-interface,在ItemSearchService中新增方法

    /**
     * 按商品id集合刪除索引庫資料
     *
     * @param ids 商品id集合
     */
    void deleteByGoodsIds(List ids);

(2)search-service,在ItemSearchServiceImpl中實現

    @Override
    public void deleteByGoodsIds(List ids) {
        // 建立查詢物件
        Query query =  new SimpleQuery("*:*");
        Criteria criteria = new Criteria("item_goodsid").in(ids);
        query.addCriteria(criteria);
        // 執行
        solrTemplate.delete(query);
        solrTemplate.commit();
    }

7.2 控制層(manager-web)

(1)在delete方法中,加入邏輯,注意引入ItemSearchService的服務