品优购项目记录:day11

今日目标:

(1)实现品优购价格区间筛选功能

(2)实现搜索结果分页功能

(3)理解多关键字搜索

(4)实现搜索结果排序功能

(5)实现隐藏品牌列表功能

(6)实现搜索页与首页对接功能

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

 

目录

1、按价格区间筛选

1.1 需求分析

1.2 前端

1.3 后端

2、搜索结果分页展示

2.1 需求分析

2.2 后端

2.3 前端

2.4 搜索优化

3、排序

3.1 需求分析

3.2 服务层实现(search-service)

3.3 按价格排序 -- 前端

3.4 按新品排序 -- 前端

3.5 按销量排序(实现思路)

3.6 按评价排序(实现思路)         

4、隐藏品牌列表

4.1 需求分析

4.2 前端

5、搜索页与首页对接

5.1 首页工程的相关改动

5.2 搜索工程的相关改动

6、同步更新索引库

6.1 需求分析

6.2 商家商品服务模块

6.3 商品搜索服务模块

6.4 控制层(manager-web)

7、同步删除索引库

7.1 商品搜索服务模块

7.2 控制层(manager-web)


 

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的服务

 

猜你喜欢

转载自blog.csdn.net/qq1031893936/article/details/81119611