谷粒商城学习笔记(11.商城业务-检索服务)

一、页面环境

商城页面搜索页面
在这里插入图片描述

1、基本配置

将主页面导入search服务下
在这里插入图片描述
将静态资源放入nginx的资源中进行统一管理
在这里插入图片描述
后端导入thymeleaf依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

前端页面加thymeleaf渲染,并将全部需要访问资源的路径进行修改
在这里插入图片描述
配置路由转发(gateway服务的配置环境中)
在这里插入图片描述

二、首页跳转检索查询功能

1、首页跳转修改

search方法路径改为我们搜索页面的路径
在这里插入图片描述
搜索导航调用search方法
在这里插入图片描述

2、搜索服务-Controller类

建立controller类统一管理检索服务
在这里插入图片描述

@Controller
public class SearchController {

    @Autowired
    MallSearchService mallSearchService;

    @GetMapping("/list.html")
    public String listPage(SearchParam param, Model model){

        //1.根据传递过来的页面查询参数,去es中检索商品
        SearchResult result = mallSearchService.search(param);
        model.addAttribute("result", result);
        return "list";
    }
}

3、实体类

一个用于封装传入的数据,一个是统一返回的数据
在这里插入图片描述

/**
 * 封装页面所有可能传递过来的查询条件
 *
 *
 */
@Data
public class SearchParam {

    private String keyword; //页面传递过来的全文匹配关键字
    private Long catalog3Id; //三级分类id

    private String sort; //排序条件

    private Integer hasStock = 1;//是否有货
    private String skuPrice;//价格区间查询
    private List<Long> brandId;//根据品牌进行查询,可以多选
    private List<String> attrs;//按照属性进行筛选
    private Integer pageNum = 1;//页码
}
@Data
public class SearchResult {
    //查询到的所有商品信息
    private List<SkuEsModel> products;
    /**
     * 以下是分页信息
     */
    private Integer pageNum; //当前页码
    private Long total; //总记录数
    private Integer totalPages; //总页码
    private List<BrandVo> brands; //当前查询到的结果,所有设计到的品牌
    private List<AttrVo> attrs; //所有涉及到的所有属性
    private List<CatalogVo> catalogs; //所有涉及到的所有分类

    //======================以上是返回给页面的所有信息=============================
    @Data
    public static class BrandVo{
        private Long brandId;
        private String brandName;
        private String brandImg;
    }

    @Data
    public static class AttrVo{
        private Long attrId;
        private String attrName;
        private List<String> attrValue;
    }

    @Data
    public static class CatalogVo{
        private Long catalogId;
        private String catalogName;
    }

}

4、Service接口

public interface MallSearchService {
    /**
     * 检索所有参数
     * 返回结果 里面包含页面的所有信息
     */
    SearchResult search(SearchParam param);

}

5、Impl实现类

import com.alibaba.fastjson.JSON;
import com.atguigu.common.to.es.SkuEsModel;
import com.atguigu.gulimall.search.config.GulimallElasticSearchConfig;
import com.atguigu.gulimall.search.constant.EsConstant;
import com.atguigu.gulimall.search.service.MallSearchService;
import com.atguigu.gulimall.search.vo.SearchParam;
import com.atguigu.gulimall.search.vo.SearchResult;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.swing.*;
import javax.swing.text.Highlighter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class MallSearchServiceImpl implements MallSearchService {

    @Autowired
    private RestHighLevelClient client;

    @Override
    public SearchResult search(SearchParam param) {
        //1.动态构建出查询需要的DSL语句
        SearchResult result = null;
        //1.准备检索请求
        SearchRequest searchRequest = buildSearchRequrest(param);

        try {
            //2.执行检索请求
            SearchResponse response = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);

            //3.分析相应数据封装成我们需要的格式
            result = buildSearchResult(response, param);

        }catch (IOException e){
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 准备检索请求
     * #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
     * @return
     */
    private SearchRequest buildSearchRequrest(SearchParam param) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//构建DSL语句的
        /**
         * 查询: 过滤(按照属性,分类,品牌,价格区间,库存)
         */
        //1. 构建bool-query
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //1.1 must-模糊查询
        if(!StringUtils.isEmpty(param.getKeyword())){
            boolQuery.must(QueryBuilders.matchQuery("skuTitle",param.getKeyword()));
        }
        //1.2 bool-filter- 按照三级分类id查询
        if(param.getCatalog3Id()!=null){
            boolQuery.filter(QueryBuilders.termQuery("catalogId",param.getCatalog3Id()));
        }
        //1.2 bool-filter- 按照品牌id查询
        if(param.getBrandId()!=null && param.getBrandId().size()>0){
            boolQuery.filter(QueryBuilders.termsQuery("brandId", param.getBrandId()));
        }
        //1.2 bool-filter- 按照所有指定的属性进行查询
        if(param.getAttrs()!=null && param.getAttrs().size()>0){
            for(String attrStr : param.getAttrs()){
                //attrs=1_5寸:8寸&attrs=2_16g:8g
                BoolQueryBuilder nestedboolQuery = QueryBuilders.boolQuery();
                //attrs= 1_5寸:8寸
                String[] s = attrStr.split("_");
                String attrId = s[0];//检索的属性id
                String[] attrValue = s[1].split(".");//用这个属性的检索用值
                nestedboolQuery.must(QueryBuilders.termQuery("attrs.attrId", attrId));
                nestedboolQuery.must(QueryBuilders.termsQuery("attrs.attrValue", attrValue));
                //每一个必须都得生成一个nested查询
                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs",nestedboolQuery, ScoreMode.None);
                boolQuery.filter(nestedQuery);
            }
        }

        //1.2 bool-filter- 按照库存是否有进行查询
        boolQuery.filter(QueryBuilders.termsQuery("hasStock", param.getHasStock()==0));

        //1.2 bool-filter- 按照价格区间
        if(!StringUtils.isEmpty(param.getSkuPrice())){
            //1_500 _500 500_
            //gte上区间
            //lte下区间
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
            String[] s = param.getSkuPrice().split("_");
            if(s.length == 2){
                rangeQuery.gte(s[0]).lte(s[1]);
            }else if(s.length == 1){
                if(param.getSkuPrice().startsWith("_")){
                    rangeQuery.lte(s[0]);
                }
                if(param.getSkuPrice().endsWith("_")){
                    rangeQuery.gte(s[0]);
                }
            }
            boolQuery.filter(rangeQuery);
        }
        //把以前的所有条件都拿来进行封装
        sourceBuilder.query(boolQuery);

        /**
         * 排序,分页,高亮
         */

        //2.1 排序
        if(!StringUtils.isEmpty(param.getSort())){
            String sort = param.getSort();
            //sort = hotScore_asc/desc
            String[] s = sort.split("_");
            SortOrder order = s[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
            sourceBuilder.sort(s[0], order);
        }
        //2.2 分页 pageSize:5
        //pageNum:1 from:0 size:5 [0.1.2.3.4]
        //pageNum:2 from:5 size:5
        //from = (pageNum - 1)*size
        sourceBuilder.from((param.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
        sourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);

        //2.3 高亮
        if(!StringUtils.isEmpty(param.getKeyword())){
            HighlightBuilder builder = new HighlightBuilder();
            builder.field("skuTitle");
            builder.preTags("<b style='color:red'>");
            builder.postTags("</b>");
            sourceBuilder.highlighter(builder);
        }
        /**
         * 聚合分析
         */
        //1.品牌聚合
        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
        brand_agg.field("brandId").size(50);
        //品牌聚合的子聚合
        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
        sourceBuilder.aggregation(brand_agg);

        //2.分类聚合
        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
        sourceBuilder.aggregation(catalog_agg);

        //3.属性聚合
        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg","attrs");
        //聚合分析出当前attr_id
        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId");
        //聚合分析出当前attr_id对应的名字
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
        //聚合分析出当前attr_id对应的所有可能的属性值attrValue
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
        attr_agg.subAggregation(attr_id_agg);
        sourceBuilder.aggregation(attr_agg);

        String s = sourceBuilder.toString();
        System.out.println("构建DSL" + s);
        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, sourceBuilder);

        return searchRequest;
    }
    /**
     * 构建检索请求:
     * #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
     * */
//    private SearchRequest buildSearchRequrest(SearchParam searchParam) {
//        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();//构建DSL语句
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        /**
//         * 模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存)
//         * */
//        //1.构建bool-query
//        //1.1 模糊匹配 bool - must
//        if (!StringUtils.isEmpty(searchParam.getKeyword())){
//            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyword()));
//        }
//        //1.2 bool - filter 按照三级分类id查询
//        if (searchParam.getCatalog3Id()!=null){
//            boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));
//        }
//        //1.3 bool -filter  按照品牌id查询
//        if (searchParam.getBrandId()!=null&&searchParam.getBrandId().size()>0){
//            boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrandId()));
//        }
//        //1.4 bool -filter - nested  按照指定的属性查询
//        if (searchParam.getAttrs()!=null&&searchParam.getAttrs().size()>0){
//            //每一个属性查询必须都得生成一个nested查询
//            for (String attr : searchParam.getAttrs()) {
//                BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
//                //attrs=1_5寸:8寸&attrs=2_16G:8G
//                String[] attrSplit = attr.split("_");
//                String attrId = attrSplit[0];
//                String[] attrValues = attrSplit[1].split(":");
//                nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));
//                nestedBoolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",attrValues));
//                //每一个必须都得生成一个nested查询
//                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
//                boolQueryBuilder.filter(nestedQuery);
//            }
//        }
//        //1.5 bool -filter 是否有库存查询
//        if (searchParam.getHasStock()==null){
//            //如果没有传输是否有库存这个参数,默认查找有库存的
//            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",true));
//        }else {
//            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.getHasStock()==0));
//        }
//
//        //1.6按照价格区间
//        if (!StringUtils.isEmpty(searchParam.getSkuPrice())){
//            RangeQueryBuilder skuPriceRangeQuery = QueryBuilders.rangeQuery("skuPrice");
//            String[] s = searchParam.getSkuPrice().split("_");
//            if (s.length == 2 ){
//                //区间
//                skuPriceRangeQuery.gte(s[0]).lte(s[1]);
//            }else if (s.length==1){
//                if (searchParam.getSkuPrice().startsWith("_")){
//                    skuPriceRangeQuery.lte(s[0]);
//                }
//                if (searchParam.getSkuPrice().endsWith("_")){
//                    skuPriceRangeQuery.gte(s[0]);
//                }
//            }
//            boolQueryBuilder.filter(skuPriceRangeQuery);
//        }
//        searchSourceBuilder.query(boolQueryBuilder);
//
//        /**
//         * 排序,分页,
//         *       sort=saleCount_asc/desc
//         *       sort=skuPrice_asc/desc
//         *       sort= hotScore_asc/desc
//         * */
//        if (!StringUtils.isEmpty(searchParam.getSort())){
//            String sort = searchParam.getSort();
//            String[] sortSplit = sort.split("_");
//            SortOrder sortOrder = sortSplit[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
//            searchSourceBuilder.sort(sortSplit[0],sortOrder);
//        }
//        //分页
//        if (searchParam.getPageNum()==null){
//            //如果没有传输pagenum参数,默认为第一页
//            searchSourceBuilder.from(((1-1)*EsConstant.PRODUCT_PAGESIZE));
//            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
//        }else {
//            searchSourceBuilder.from((searchParam.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
//            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
//        }
//
//        /**
//         * 高亮
//         * */
//        if (!StringUtils.isEmpty(searchParam.getKeyword())){
//            HighlightBuilder highlightBuilder=new HighlightBuilder();
//            highlightBuilder.field("skuTitle");
//            highlightBuilder.preTags("<b style= 'color:red'>");
//            highlightBuilder.postTags("</b>");
//            searchSourceBuilder.highlighter(highlightBuilder);
//        }
//        /**
//         * 聚合分析
//         * */
//
//        //1.品牌的聚合
//        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
//        brand_agg.field("brandId");
//        //品牌的子聚合
//        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
//        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
//        //TODO 1. 品牌的聚合
//        searchSourceBuilder.aggregation(brand_agg);
//        //2.分类聚合 catalog_agg
//        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
//        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
//        //TODO 2. 分类的聚合
//        searchSourceBuilder.aggregation(catalog_agg);
//        //3.属性聚合 attr_agg
//        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
//        //3.1聚合当前所有的attrId
//        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(10);
//        //3.2聚合分析出当前attr_id对应的名字
//        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
//        //3.3聚合分析出当前attr_id对应的所有可能的属性值attrValue
//        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
//        attr_agg.subAggregation(attr_id_agg);
//        //TODO 3. 属性的聚合
//        searchSourceBuilder.aggregation(attr_agg);
//        //打印构造的DSL
//        String s = searchSourceBuilder.toString();
//        System.out.println("构建的DSL:"+s);
//
//        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, searchSourceBuilder);
//        return searchRequest;
//    }

    /**
     * 构建结果
     */
    private SearchResult buildSearchResult(SearchResponse response,SearchParam param){

        SearchResult result = new SearchResult();
        //1. 返回所有查询到的商品
        SearchHits hits = response.getHits();
        List<SkuEsModel> esModels = new ArrayList<>();
        if(hits.getHits() != null && hits.getHits().length > 0){
            for(SearchHit hit : hits.getHits()){
                String sourceAsString = hit.getSourceAsString();
                SkuEsModel esModel = JSON.parseObject(sourceAsString, SkuEsModel.class);
                if(!StringUtils.isEmpty(param.getKeyword())){
                    HighlightField skuTitle = hit.getHighlightFields().get("skuTitle");
                    String string =  skuTitle.getFragments()[0].string();
                    esModel.setSkuTitle(string);
                }
                esModels.add(esModel);
            }
        }
        result.setProducts(esModels);
        //2. 当前所有商品涉及到的所有属性信息
        List<SearchResult.AttrVo> attrVos = new ArrayList<>();
        ParsedNested attr_agg = response.getAggregations().get("attr_agg");
        ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");
        for(Terms.Bucket bucket : attr_id_agg.getBuckets()){
            SearchResult.AttrVo attrVo = new SearchResult.AttrVo();
            //1.得到属性的id
            long attrId = bucket.getKeyAsNumber().longValue();
            //2.得到属性的名字
            String attrName = ((ParsedStringTerms) bucket.getAggregations().get("attr_name_agg")).getBuckets().get(0).getKeyAsString();
            //3.得到属性的所有值
            List<String> attrValues = ((ParsedStringTerms) bucket.getAggregations().get("attr_value_agg")).getBuckets().stream().map(item->{
                String keyAsString = ((Terms.Bucket) item).getKeyAsString();
                return keyAsString;
            }).collect(Collectors.toList());
            attrVo.setAttrId(attrId);
            attrVo.setAttrName(attrName);
            attrVo.setAttrValue(attrValues);

            attrVos.add(attrVo);
        }
        result.setAttrs(attrVos);
        //3. 当前所有商品涉及到的所有品牌信息
        List<SearchResult.BrandVo> brandVos = new ArrayList<>();
        ParsedLongTerms brand_agg = response.getAggregations().get("brand_agg");
        for(Terms.Bucket bucket : brand_agg.getBuckets()){
            SearchResult.BrandVo brandVo = new SearchResult.BrandVo();
            //1. 得到品牌id
            long brandId = bucket.getKeyAsNumber().longValue();
            //2. 得到品牌名
            String brandName = ((ParsedStringTerms)bucket.getAggregations().get("brand_name_agg")).getBuckets().get(0).getKeyAsString();
            //3. 得到品牌的图片
            String brandImg = ((ParsedStringTerms)bucket.getAggregations().get("brand_img_agg")).getBuckets().get(0).getKeyAsString();
            brandVo.setBrandId(brandId);
            brandVo.setBrandName(brandName);
            brandVo.setBrandImg(brandImg);
            brandVos.add(brandVo);
        }
        result.setBrands(brandVos);
        //4. 当前所有商品涉及到的所有分类信息
        ParsedLongTerms catalog_agg = response.getAggregations().get("catalog_agg");

        List<SearchResult.CatalogVo> catalogVos = new ArrayList<>();
        List<? extends Terms.Bucket> buckets = catalog_agg.getBuckets();
        for(Terms.Bucket bucket : buckets){
            SearchResult.CatalogVo catalogVo = new SearchResult.CatalogVo();
            //得到分类id
            String keyAsString = bucket.getKeyAsString();
            catalogVo.setCatalogId(Long.parseLong(keyAsString));

            //得到分类名
            ParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");
            String catalog_name = catalog_name_agg.getBuckets().get(0).getKeyAsString();
            catalogVo.setCatalogName(catalog_name);
            catalogVos.add(catalogVo);
        }
        result.setCatalogs(catalogVos);
//==========以上从聚合信息中获取==============


        //5. 分页信息-页码
        result.setPageNum(param.getPageNum());
        //5. 分页信息-总记录数
        long total = hits.getTotalHits().value;
        result.setTotal(total);

        //5. 分页信息-总页码
        int totalPages = (int)total%EsConstant.PRODUCT_PAGESIZE == 0?(int)total/EsConstant.PRODUCT_PAGESIZE:((int)total/EsConstant.PRODUCT_PAGESIZE + 1);

        result.setTotalPages(totalPages);

        return result;
    }
}

6、搜索页面修改

将得到的数据进行回显
在这里插入图片描述

7、测试

1.查询方法

1.在Kibana中,首先建立新的查询mapping,命名为gulimall_product
在这里插入图片描述

{
  "gulimall_product" : {
    "mappings" : {
      "properties" : {
        "attrs" : {
          "type" : "nested",
          "properties" : {
            "attrId" : {
              "type" : "long"
            },
            "attrName" : {
              "type" : "keyword"
            },
            "attrValue" : {
              "type" : "keyword"
            }
          }
        },
        "brandId" : {
          "type" : "long"
        },
        "brandImg" : {
          "type" : "keyword"
        },
        "brandName" : {
          "type" : "keyword"
        },
        "catalogId" : {
          "type" : "long"
        },
        "catalogName" : {
          "type" : "keyword"
        },
        "hasStock" : {
          "type" : "boolean"
        },
        "hotScore" : {
          "type" : "long"
        },
        "saleCount" : {
          "type" : "long"
        },
        "skuId" : {
          "type" : "long"
        },
        "skuImg" : {
          "type" : "keyword"
        },
        "skuPrice" : {
          "type" : "keyword"
        },
        "skuTitle" : {
          "type" : "text",
          "analyzer" : "ik_smart"
        },
        "spuId" : {
          "type" : "keyword"
        }
      }
    }
  }
}

我们可以输入
GET gulimall_product/_search
查询之前以及商品上传的数据
在这里插入图片描述

2.在搜索服务中,使用新的检索规则
在这里插入图片描述
3.用postman测试接口

查看返回到的dsl
在这里插入图片描述
在这里插入图片描述
放入kibana中测试

GET gulimall_product/_search
{
  "from": 0,
  "size": 2,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "skuTitle": {
              "query": "华为",
              "operator": "OR",
              "prefix_length": 0,
              "max_expansions": 50,
              "fuzzy_transpositions": true,
              "lenient": false,
              "zero_terms_query": "NONE",
              "auto_generate_synonyms_phrase_query": true,
              "boost": 1
            }
          }
        }
      ],
      "filter": [
        {
          "terms": {
            "hasStock": [
              false
            ],
            "boost": 1
          }
        }
      ],
      "adjust_pure_negative": true,
      "boost": 1
    }
  },
  "aggregations": {
    "brand_agg": {
      "terms": {
        "field": "brandId",
        "size": 50,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "brand_name_agg": {
          "terms": {
            "field": "brandName",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        },
        "brand_img_agg": {
          "terms": {
            "field": "brandImg",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    },
    "catalog_agg": {
      "terms": {
        "field": "catalogId",
        "size": 20,
        "min_doc_count": 1,
        "shard_min_doc_count": 0,
        "show_term_doc_count_error": false,
        "order": [
          {
            "_count": "desc"
          },
          {
            "_key": "asc"
          }
        ]
      },
      "aggregations": {
        "catalog_name_agg": {
          "terms": {
            "field": "catalogName",
            "size": 1,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          }
        }
      }
    },
    "attr_agg": {
      "nested": {
        "path": "attrs"
      },
      "aggregations": {
        "attr_id_agg": {
          "terms": {
            "field": "attrs.attrId",
            "size": 10,
            "min_doc_count": 1,
            "shard_min_doc_count": 0,
            "show_term_doc_count_error": false,
            "order": [
              {
                "_count": "desc"
              },
              {
                "_key": "asc"
              }
            ]
          },
          "aggregations": {
            "attr_name_agg": {
              "terms": {
                "field": "attrs.attrName",
                "size": 1,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_key": "asc"
                  }
                ]
              }
            },
            "attr_value_agg": {
              "terms": {
                "field": "attrs.attrValue",
                "size": 50,
                "min_doc_count": 1,
                "shard_min_doc_count": 0,
                "show_term_doc_count_error": false,
                "order": [
                  {
                    "_count": "desc"
                  },
                  {
                    "_key": "asc"
                  }
                ]
              }
            }
          }
        }
      }
    }
  },
  "highlight": {
    "pre_tags": [
      "<b style='color:red'>"
    ],
    "post_tags": [
      "</b>"
    ],
    "fields": {
      "skuTitle": {}
    }
  }
}

查询到的数据,则表明我们查询功能成功
在这里插入图片描述

2.返回方法

打开前端页面

输入查询条件,可以看的返回数据
在这里插入图片描述

三、页面基本数据渲染

1、基本页面

这里把页面中的数据换为已经发布的商品数据主要修改前端
在这里插入图片描述
回显页面下我们数据库中存在的商品,以及相关信息
在这里插入图片描述

回显导航栏数据

品牌:
在这里插入图片描述
分类:
在这里插入图片描述
其他属性:
在这里插入图片描述
在这里插入图片描述

2、筛选条件渲染

上一步的导航栏数据已经渲染出来了,这步做渲染条件查询

定义search方法
在这里插入图片描述
定义一个替换url连接的方法,根据不同的查询条件拼接连接
在这里插入图片描述

3、分页功能

在这里插入图片描述
在 private SearchResult buildSearchResult(SearchResponse response,SearchParam param)中封装分页的信息:

        //5. 分页信息-页码
        result.setPageNum(param.getPageNum());
        //5. 分页信息-总记录数
        long total = hits.getTotalHits().value;
        result.setTotal(total);

        //5. 分页信息-总页码
        int totalPages = (int)total%EsConstant.PRODUCT_PAGESIZE == 0?(int)total/EsConstant.PRODUCT_PAGESIZE:((int)total/EsConstant.PRODUCT_PAGESIZE + 1);
        result.setTotalPages(totalPages);

        List<Integer> pageNavs = new ArrayList<>();
        for(int i = 1; i <= totalPages; i++){
            pageNavs.add(i);
        }
        result.setPageNavs(pageNavs);

在这里插入图片描述

4、页面排序功能

 <!--综合排序-->
            <div class="JD_con_right">
                <div class="filter">
                    <!--综合排序-->
                    <div class="filter_top">
                        <div class="filter_top_left" th:with="p = ${param.sort},priceRange = ${param.skuPrice}">
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(#strings.isEmpty(p) || #strings.startsWith(p,'hotScore'))?'color: #FFF;border-color: #e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="hotScore" href="/static/search/#">综合排序 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount'))?'color: #FFF;border-color:#e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="saleCount" href="/static/search/#">销量 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice'))?'color: #FFF;border-color:#e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="skuPrice" href="/static/search/#">价格 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a class="sort_a" href="/static/search/#">评论分</a>
                            <a class="sort_a" href="/static/search/#">上架时间</a>
                            <input id="skuPriceFrom" type="number" style="width: 100px;margin-left: 30px;" th:value="${#strings.isEmpty(priceRange)?'':#strings.substringBefore(priceRange,'_')}"> -
                            <input id="skuPriceTo" type="number" style="width: 100px;" th:value="${#strings.isEmpty(priceRange)?'':#strings.substringAfter(priceRange,'_')}"><button id="skuPriceSearchBtn">确定</button>
                        </div>
                        <div class="filter_top_right">
                            <span class="fp-text">
                               <b>1</b><em>/</em><i>169</i>
                           </span>
                            <a href="/static/search/#" class="prev"><</a>
                            <a href="/static/search/#" class="next"> > </a>
                        </div>
                    </div>

绑定点击事件,方法

    $(".sort_a").click(function (){
        //1.当前被点击的元素变为选中状态
        // 改变当前元素以及兄弟元素的样式
        // changeStyle(this);
        $(this).toggleClass("desc");
        //2.跳转到指定位置 sort=skuPrice_asc/desc
        var sort = $(this).attr("sort");
        sort = $(this).hasClass("desc")?sort+"_desc":sort+"_asc";
        location.href = replaceAndParamVal(location.href,"sort",sort);
        //禁用默认行为
        return false;
    });

    function changeStyle(ele){
        $(".sort_a").css({"color":"#333","border-color":"#CCC","background":"#FFF"});
        $(".sort_a").each(function(){
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬇";
            $(ele).text(text);
        });
        $(ele).css({"color":"#FFF","border-color":"#e4393c","background":"#e4393c"});
        //改变升降序
        $(ele).toggleClass("desc");//加上就是降序,不加就是升序
        if($(ele).hasClass("desc")){
            //降序
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬇";
            $(ele).text(text);
        }else{
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬆";
            $(ele).text(text);
        }
    };

    $("#skuPriceSearchBtn").click(function (){
        //1.拼上价格区间的查询条件
        var from = $("#skuPriceFrom").val();
        var to = $("#skuPriceTo").val();
        var query = from + "_" + to;
        location.href = replaceAndParamVal(location.href,"skuPrice",query);
    });

在这里插入图片描述

5、面包屑导航功能

也是在回显结果方法中构建面包屑返回数据

 //6.构建面包屑导航功能
        if(param.getAttrs() != null && param.getAttrs().size()>0){
            List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {
                //1.分析每个attrs传过来的查询参数值
                SearchResult.NavVo navVo = new SearchResult.NavVo();
                String[] s = attr.split("_");
                navVo.setNavValue(s[1]);
                R r = productFeignService.attrInfo(Long.parseLong(s[0]));
                result.getAttrIds().add(Long.parseLong(s[0]));
                if(r.getCode() == 0){
                    AttrResponseVo data = r.getData("attr", new TypeReference<AttrResponseVo>(){
                    });
                    navVo.setNavName(data.getAttrName());
                }else{
                    navVo.setNavName(s[0]);
                }
                //2.取消面包屑后,跳转剩下条件的页面
                //将请求地址的url清空
                //拿到所有的查询条件,去掉当前
                String replace = replaceQueryString(param, attr, "attrs");
                navVo.setLink("http://search.yjlmall.com/list.html?"+replace);
                return navVo;
            }).collect(Collectors.toList());

            result.setNavs(collect);
        }

        //品牌 分类
        if(param.getBrandId() != null && param.getBrandId().size() > 0){
            List<SearchResult.NavVo> navs = result.getNavs();
            SearchResult.NavVo navVo = new SearchResult.NavVo();
            navVo.setNavName("品牌");
            //TODO 远程查询所有品牌
            R r = productFeignService.brandsInfo(param.getBrandId());
            if(r.getCode() == 0){
                List<BrandVo> brand = r.getData("brand", new TypeReference<List<BrandVo>>() {});
                StringBuffer buffer = new StringBuffer();
                String replace = "";
                for (BrandVo brandVo : brand){
                    buffer.append(brandVo.getBrandName()+";");
                    replace = replaceQueryString(param,brandVo.getBrandId()+"","brandId");
                }
                navVo.setNavValue(buffer.toString());
                navVo.setLink("http://search.yjlmall.com/list.html?"+replace);
            }
            navs.add(navVo);
        }

统一编码返回结果方法

    private String replaceQueryString(SearchParam param, String value, String key){
        String encode = null;
        try{
            encode = URLEncoder.encode(value, "UTF-8");
            encode = encode.replace("+","%20");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return param.get_queryString().replace("&"+key+"=" + encode, "");
    }

利用远程调用product中的方法查询数据


@FeignClient("gulimall-product")
public interface ProductFeignService {

    @GetMapping("/product/attr/info/{attrId}")
    public R attrInfo(@PathVariable("attrId") Long attrId);

    @GetMapping("/product/brand/infos")
    public R brandsInfo(@RequestParam("brandIds") List<Long> brandIds);
}

在这里插入图片描述

四、主要代码

1、前端页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="/static/search/css/index.css">
    <link rel="stylesheet" type="text/css" href="/static/search/font/iconfont.css">
    <!--<script src="/static/search/./js/jquery-3.2.1.min.js"></script>-->
    <script src="/static/search/js/jquery-1.12.4.js"></script>
    <title>Document</title>
</head>
<body>
<!--头部-->
<div class="header_head">
    <div class="header_head_box">
        <b class="header_head_p">
            <div style="overflow: hidden">
                <a href="http://yjlmall.com" class="header_head_p_a1" style="width:73px;">
                    谷粒商城首页
                </a>
                <a href="/static/search/#" class="header_head_p_a">
                    <!--<img src="/static/search/img/img_05.png" style="border-radius: 50%;"/>-->
                    北京</a>
            </div>
            <div class="header_head_p_cs">
                <a href="/static/search/#" style="background: #C81623;color: #fff;">北京</a>
                <a href="/static/search/#">上海</a>
                <a href="/static/search/#">天津</a>
                <a href="/static/search/#">重庆</a>
                <a href="/static/search/#">河北</a>
                <a href="/static/search/#">山西</a>
                <a href="/static/search/#">河南</a>
                <a href="/static/search/#">辽宁</a>
                <a href="/static/search/#">吉林</a>
                <a href="/static/search/#">黑龙江</a>
                <a href="/static/search/#">内蒙古</a>
                <a href="/static/search/#">江苏</a>
                <a href="/static/search/#">山东</a>
                <a href="/static/search/#">安徽</a>
                <a href="/static/search/#">浙江</a>
                <a href="/static/search/#">福建</a>
                <a href="/static/search/#">湖北</a>
                <a href="/static/search/#">湖南</a>
                <a href="/static/search/#">广东</a>
                <a href="/static/search/#">广西</a>
                <a href="/static/search/#">江西</a>
                <a href="/static/search/#">四川</a>
                <a href="/static/search/#">海南</a>
                <a href="/static/search/#">贵州</a>
                <a href="/static/search/#">云南</a>
                <a href="/static/search/#">西藏</a>
                <a href="/static/search/#">陕西</a>
                <a href="/static/search/#">甘肃</a>
                <a href="/static/search/#">青海</a>
                <a href="/static/search/#">宁夏</a>
                <a href="/static/search/#">新疆</a>
                <a href="/static/search/#">港澳</a>
                <a href="/static/search/#">台湾</a>
                <a href="/static/search/#">钓鱼岛</a>
                <a href="/static/search/#">海外</a>
            </div>
        </b>
        <ul>
            <li>
                <a href="/static/search/#" class="li_2">你好,请登录</a>
            </li>
            <li>
                <a href="/static/search/#">免费注册</a>
            </li>
            <span>|</span>
            <li>
                <a href="/static/search/#">我的订单</a>
            </li>
            <span>|</span>
            <li class="header_wdjd" style="width:80px;">
                <a href="/static/search/#">我的谷粒商城</a>
                <img src="/static/search/image/down-@1x.png" />
                <!--<b class="glyphicon glyphicon-menu-down"></b>-->
                <div class="header_wdjd_txt">
                    <ul>
                        <li>
                            <a href="/static/search/#">待处理订单</a>
                        </li>
                        <li>
                            <a href="/static/search/#">消息</a>
                        </li>
                        <li>
                            <a href="/static/search/#">返修退换货</a>
                        </li>
                        <li>
                            <a href="/static/search/#">我的回答</a>
                        </li>
                        <li>
                            <a href="/static/search/#">降价商品</a>
                        </li>
                        <li>
                            <a href="/static/search/#">我的关注</a>
                        </li>
                    </ul>
                    <ul>
                        <li>
                            <a href="/static/search/#">我的京豆</a>
                        </li>
                        <li>
                            <a href="/static/search/#">我的优惠券</a>
                        </li>
                        <li>
                            <a href="/static/search/#">我的白条</a>
                        </li>
                        <li>
                            <a href="/static/search/#">我的理财</a>
                        </li>
                    </ul>
                </div>
            </li>
            <span>|</span>
            <li>
                <a href="/static/search/#">谷粒商城会员</a>
            </li>
            <span>|</span>
            <li>
                <a href="/static/search/#">企业采购</a>
            </li>
            <span>|</span>
            <li class="header_wdjd1">
                <a href="/static/search/#">客户服务</a>
                <img src="/static/search/image/down-@1x.png" />
                <!--<b class="glyphicon glyphicon-menu-down"></b>-->
                <div class="header_wdjd_txt">
                    <ul>
                        <p style="width:100%;">客户</p>
                        <li>
                            <a href="/static/search/#">帮助中心</a>
                        </li>
                        <li>
                            <a href="/static/search/#">售后服务</a>
                        </li>
                        <li>
                            <a href="/static/search/#">在线客服</a>
                        </li>
                        <li>
                            <a href="/static/search/#">意见建议</a>
                        </li>
                        <li>
                            <a href="/static/search/#">电话客服</a>
                        </li>
                        <li>
                            <a href="/static/search/#">客服邮箱</a>
                        </li>
                        <li>
                            <a href="/static/search/#">金融资讯</a>
                        </li>
                        <li>
                            <a href="/static/search/#">售全球客服</a>
                        </li>
                    </ul>
                    <ul>
                        <p style="width:100%;">商户</p>
                        <li>
                            <a href="/static/search/#">合作招商</a>
                        </li>
                        <li>
                            <a href="/static/search/#">学习中心</a>
                        </li>
                        <li>
                            <a href="/static/search/#">商家后台</a>
                        </li>
                        <li>
                            <a href="/static/search/#">京麦工作台</a>
                        </li>
                        <li>
                            <a href="/static/search/#">商家帮助</a>
                        </li>
                        <li>
                            <a href="/static/search/#">规则平台</a>
                        </li>
                    </ul>
                </div>
            </li>
            <span>|</span>
            <li class="header_wzdh">
                <a href="/static/search/#">网站导航</a>
                <img src="/static/search/image/down-@1x.png" />
                <!--<b class="glyphicon glyphicon-menu-down"></b>-->
                <div class="header_wzdh_txt">
                    <ul style="width: 25%;">
                        <p style="width:100%;">特色主题</p>
                        <li>
                            <a href="/static/search/#">谷粒商城试用</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城金融</a>
                        </li>
                        <li>
                            <a href="/static/search/#">全球售</a>
                        </li>
                        <li>
                            <a href="/static/search/#">国际站</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城会员</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城预售</a>
                        </li>
                        <li>
                            <a href="/static/search/#">买什么</a>
                        </li>
                        <li>
                            <a href="/static/search/#">俄语站</a>
                        </li>
                        <li>
                            <a href="/static/search/#">装机大师</a>
                        </li>
                        <li>
                            <a href="/static/search/#">0元评测</a>
                        </li>
                        <li>
                            <a href="/static/search/#">定期送</a>
                        </li>
                        <li>
                            <a href="/static/search/#">港澳售</a>
                        </li>
                        <li>
                            <a href="/static/search/#">优惠券</a>
                        </li>
                        <li>
                            <a href="/static/search/#">秒杀</a>
                        </li>
                        <li>
                            <a href="/static/search/#">闪购</a>
                        </li>
                        <li>
                            <a href="/static/search/#">印尼站</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城金融科技</a>
                        </li>
                        <li>
                            <a href="/static/search/#">In货推荐</a>
                        </li>
                        <li>
                            <a href="/static/search/#">陪伴计划</a>
                        </li>
                        <li>
                            <a href="/static/search/#">出海招商</a>
                        </li>
                    </ul>
                    <ul style="width: 20%;">
                        <p style="width:100%;">行业频道</p>
                        <li>
                            <a href="/static/search/#">手机</a>
                        </li>
                        <li>
                            <a href="/static/search/#">智能数码</a>
                        </li>
                        <li>
                            <a href="/static/search/#">玩3c</a>
                        </li>
                        <li>
                            <a href="/static/search/#">电脑办公</a>
                        </li>
                        <li>
                            <a href="/static/search/#">家用电器</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城智能</a>
                        </li>
                        <li>
                            <a href="/static/search/#">服装城</a>
                        </li>
                        <li>
                            <a href="/static/search/#">美妆馆</a>
                        </li>
                        <li>
                            <a href="/static/search/#">家装城</a>
                        </li>
                        <li>
                            <a href="/static/search/#">母婴</a>
                        </li>
                        <li>
                            <a href="/static/search/#">食品</a>
                        </li>
                        <li>
                            <a href="/static/search/#">运动户外</a>
                        </li>
                        <li>
                            <a href="/static/search/#">农资频道</a>
                        </li>
                        <li>
                            <a href="/static/search/#">整车</a>
                        </li>
                        <li>
                            <a href="/static/search/#">图书</a>
                        </li>
                    </ul>
                    <ul style="width: 21%;">
                        <p style="width:100%;">生活服务</p>
                        <li>
                            <a href="/static/search/#">白条</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城金融App</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城小金库</a>
                        </li>
                        <li>
                            <a href="/static/search/#">理财</a>
                        </li>
                        <li>
                            <a href="/static/search/#">智能家电</a>
                        </li>
                        <li>
                            <a href="/static/search/#">话费</a>
                        </li>
                        <li>
                            <a href="/static/search/#">水电煤</a>
                        </li>
                        <li>
                            <a href="/static/search/#">彩票</a>
                        </li>
                        <li>
                            <a href="/static/search/#">旅行</a>
                        </li>
                        <li>
                            <a href="/static/search/#">机票酒店</a>
                        </li>
                        <li>
                            <a href="/static/search/#">电影票</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城到家</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城众测</a>
                        </li>
                        <li>
                            <a href="/static/search/#">游戏</a>
                        </li>
                    </ul>
                    <ul style="width: 23%; border-right: 0;">
                        <p style="width:100%;">更多精选</p>
                        <li>
                            <a href="/static/search/#">合作招商</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城通信</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城E卡</a>
                        </li>
                        <li>
                            <a href="/static/search/#">企业采购</a>
                        </li>
                        <li>
                            <a href="/static/search/#">服务市场</a>
                        </li>
                        <li>
                            <a href="/static/search/#">办公生活馆</a>
                        </li>
                        <li>
                            <a href="/static/search/#">乡村招募</a>
                        </li>
                        <li>
                            <a href="/static/search/#">校园加盟</a>
                        </li>
                        <li>
                            <a href="/static/search/#">京友帮</a>
                        </li>
                        <li>
                            <a href="/static/search/#">谷粒商城社区</a>
                        </li>
                        <li>
                            <a href="/static/search/#">智能社区</a>
                        </li>
                        <li>
                            <a href="/static/search/#">游戏社区</a>
                        </li>
                        <li>
                            <a href="/static/search/#">知识产权维权</a>
                        </li>
                    </ul>
                </div>
            </li>
            <span>|</span>
            <li class="header_sjjd">
                <a href="/static/search/#">手机谷粒商城</a>
                <div class="header_sjjd_div">
                    <img src="/static/search/img/01.png" />
                </div>
            </li>
        </ul>
    </div>
</div>

<!--搜索导航-->
<div class="header_sous">
    <div class="logo">
        <a href="http://yjlmall.com"><img src="/static/search/./image/logo1.jpg" alt=""></a>
    </div>
    <div class="header_form">
        <input id="keyword_input" type="text" placeholder="手机" th:value="${param.keyword}"/>
        <a href="javascript:searchByKeyword();">搜索</a>
    </div>
    <div class="header_ico">
        <div class="header_gw">
            <span><a href="/static/search/#">我的购物车</a></span>
            <img src="/static/search/image/settleup-@1x.png" />
            <span>0</span>
        </div>
        <div class="header_ko">
            <p>购物车中还没有商品,赶紧选购吧!</p>
        </div>
    </div>
    <div class="header_form_nav">
        <ul>
            <li>
                <a href="/static/search/#">谷粒商城之家</a>
            </li>
            <li>
                <a href="/static/search/#">谷粒商城专卖店</a>
            </li>
            <li>
                <a href="/static/search/#">平板</a>
            </li>
            <li>
                <a href="/static/search/#">电脑</a>
            </li>
            <li>
                <a href="/static/search/#">ipad</a>
            </li>
        </ul>
    </div>
    <nav>
        <ul>
            <li class="nav_li1">
                <a href="/static/search/#">全部商品分类</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">服装城</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">没装馆</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">超市</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">生鲜</a>
            </li>
        </ul>
        <div class="spacer">|</div>
        <ul>
            <li class="nav_li">
                <a href="/static/search/#">全球购</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">闪购</a>
            </li>
            <li class="nav_li">
                <a href="/static/search/#">拍卖</a>
            </li>
        </ul>
        <div class="spacer">|</div>
        <ul>
            <li class="nav_li">
                <a href="/static/search/#">金融</a>
            </li>
        </ul>

    </nav>
    <div class="header_main_left">
        <ul>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>家用电器</b></a>
            </li>
            <li class="header_li2">
                <a href="/static/search/#" class="header_main_left_a"><b>手机</b> / <b>运营商</b> / <b>数码</b></a>
                <div class="header_main_left_main">
                    <div class="header_sj">
                        <a href="/static/search/#" class="header_sj_a">玩3c</a>
                        <a href="/static/search/#" class="header_sj_a">手机频道</a>
                        <a href="/static/search/#" class="header_sj_a">网上营业厅</a>
                        <a href="/static/search/#" class="header_sj_a">配件选购中心</a>
                        <a href="/static/search/#" class="header_sj_a">企业购</a>
                        <a href="/static/search/#" class="header_sj_a">以旧换新</a>
                    </div>
                    <ol class="header_ol">
                        <a href="/static/search/#" style="color: #111;" class="aaa">手机通讯 ></a>
                        <li>
                            <a href="/static/search/#" style="color: #999;">手机</a>
                            <a href="/static/search/#" style="color: #999;">对讲机</a>
                            <a href="/static/search/#" style="color: #999;">手机维修</a>
                            <a href="/static/search/#" style="color: #999;">以旧换新</a>
                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">运营商 ></a>
                        <li>
                            <a href="/static/search/#" style="color: #999;">合约机</a>
                            <a href="/static/search/#" style="color: #999;">固话宽带</a>
                            <a href="/static/search/#" style="color: #999;">办套餐</a>
                            <a href="/static/search/#" style="color: #999;">从话费/流量</a>
                            <a href="/static/search/#" style="color: #999;">中国电信</a>
                            <a href="/static/search/#" style="color: #999;">中国移动</a>
                            <a href="/static/search/#" style="color: #999;">中国联通</a>
                            <a href="/static/search/#" style="color: #999;">谷粒商城通信</a>
                            <a href="/static/search/#" style="color: #999;">170选号</a>
                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">手机配件 ></a>
                        <li style="height: 60px;">

                            <a href="/static/search/#" style="color: #999;">手机壳</a>
                            <a href="/static/search/#" style="color: #999;">贴膜</a>
                            <a href="/static/search/#" style="color: #999;">手机储存卡</a>
                            <a href="/static/search/#" style="color: #999;">数据线</a>
                            <a href="/static/search/#" style="color: #999;">存电器</a>
                            <a href="/static/search/#" style="color: #999;">手机耳机</a>
                            <a href="/static/search/#" style="color: #999;">创业配件</a>
                            <a href="/static/search/#" style="color: #999;">手机饰品</a>
                            <a href="/static/search/#" style="color: #999;">手机电池</a>
                            <a href="/static/search/#" style="color: #999;">苹果周边</a>
                            <a href="/static/search/#" style="color: #999;">移动电源</a>
                            <a href="/static/search/#" style="color: #999;">蓝牙耳机</a>
                            <a href="/static/search/#" style="color: #999;">手机支架</a>
                            <a href="/static/search/#" style="color: #999;">车载配件</a>
                            <a href="/static/search/#" style="color: #999;">拍照配件</a>

                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">摄影摄像 ></a>
                        <li style="height: 60px;">

                            <a href="/static/search/#" style="color: #999;">数码相机</a>
                            <a href="/static/search/#" style="color: #999;">单电/微单相机</a>
                            <a href="/static/search/#" style="color: #999;">单反相机</a>
                            <a href="/static/search/#" style="color: #999;">拍立得</a>
                            <a href="/static/search/#" style="color: #999;">运动相机</a>
                            <a href="/static/search/#" style="color: #999;">摄像机</a>
                            <a href="/static/search/#" style="color: #999;">镜头</a>
                            <a href="/static/search/#" style="color: #999;">户外器材</a>
                            <a href="/static/search/#" style="color: #999;">影棚器材</a>
                            <a href="/static/search/#" style="color: #999;">冲印服务</a>
                            <a href="/static/search/#" style="color: #999;">数码相框</a>
                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">数码配件 ></a>
                        <li style="height: 60px;">

                            <a href="/static/search/#" style="color: #999;">三脚架/云台</a>
                            <a href="/static/search/#" style="color: #999;">相机包</a>
                            <a href="/static/search/#" style="color: #999;">滤镜</a>
                            <a href="/static/search/#" style="color: #999;">散光灯/手柄</a>
                            <a href="/static/search/#" style="color: #999;">相机清洁</a>
                            <a href="/static/search/#" style="color: #999;">机身附件</a>
                            <a href="/static/search/#" style="color: #999;">镜头附件</a>
                            <a href="/static/search/#" style="color: #999;">读卡器</a>
                            <a href="/static/search/#" style="color: #999;">支架</a>
                            <a href="/static/search/#" style="color: #999;">电池/存电器</a>

                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">影音娱乐 ></a>
                        <li>

                            <a href="/static/search/#" style="color: #999;">耳机/耳麦</a>
                            <a href="/static/search/#" style="color: #999;">音箱/音响</a>
                            <a href="/static/search/#" style="color: #999;">智能音箱</a>
                            <a href="/static/search/#" style="color: #999;">便携/无线音箱</a>
                            <a href="/static/search/#" style="color: #999;">收音机</a>
                            <a href="/static/search/#" style="color: #999;">麦克风</a>
                            <a href="/static/search/#" style="color: #999;">MP3/MP4</a>
                            <a href="/static/search/#" style="color: #999;">专业音频</a>
                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">智能设备 ></a>
                        <li style="height: 60px;">

                            <a href="/static/search/#" style="color: #999;">智能手环</a>
                            <a href="/static/search/#" style="color: #999;">智能手表</a>
                            <a href="/static/search/#" style="color: #999;">智能眼镜</a>
                            <a href="/static/search/#" style="color: #999;">智能机器人</a>
                            <a href="/static/search/#" style="color: #999;">运动跟踪器</a>
                            <a href="/static/search/#" style="color: #999;">健康监测</a>
                            <a href="/static/search/#" style="color: #999;">智能配饰</a>
                            <a href="/static/search/#" style="color: #999;">智能家居</a>
                            <a href="/static/search/#" style="color: #999;">体感车</a>
                            <a href="/static/search/#" style="color: #999;">无人机</a>
                            <a href="/static/search/#" style="color: #999;">其他配件</a>
                        </li>
                        <a href="/static/search/#" style="color: #111;" class="aaa">电子教育 ></a>
                        <li>
                            <a href="/static/search/#" style="color: #999;">学生平板</a>
                            <a href="/static/search/#" style="color: #999;">点读机</a>
                            <a href="/static/search/#" style="color: #999;">早教益智</a>
                            <a href="/static/search/#" style="color: #999;">录音笔</a>
                            <a href="/static/search/#" style="color: #999;">电纸书</a>
                            <a href="/static/search/#" style="color: #999;">电子词典</a>
                            <a href="/static/search/#" style="color: #999;">复读机</a>
                        </li>
                    </ol>
                    <div class="header_r">
                        <div class="header_r_tu">
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/56b2f385n8e4eb051.jpg" /></a>
                        </div>
                        <div class="header_r_tu1">
                            <a href="/static/search/#"><img src="/static/search/img/JD_ash7 - 副本.png" /></a>
                            <a href="/static/search/#"><img src="/static/search/img/JD_ash6.png" /></a>
                        </div>
                    </div>
                </div>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>电脑</b> / <b>办公</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>家居</b> / <b>家具</b> / <b>家装</b> / <b>厨具</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>男装</b> / <b>女装</b> / <b>童装</b> / <b>内衣</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>美妆个护 </b>/ <b>宠物</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>女鞋</b> / <b>箱包</b> / <b>钟表</b> / <b>珠宝</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>男鞋</b> / <b>运动</b> / <b>户外</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>汽车</b> / <b>汽车用品</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>母婴</b> / <b>玩具乐器</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>食品</b> / <b>酒类</b> / <b>生鲜</b> / <b>特产</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>礼品鲜花</b> / <b>农资绿植</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>医药保健</b> / <b>计生情趣</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>图书</b> / <b>音箱</b>/ <b>电子书</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>机票</b> / <b>酒店</b> / <b>旅游</b> / <b>生活</b></a>
            </li>
            <li>
                <a href="/static/search/#" class="header_main_left_a"><b>理财</b> / <b>众筹</b> / <b>白条</b> / <b>保险</b></a>
            </li>
        </ul>

    </div>
</div>

<hr style="border: 1px solid red;margin-top: -7px;">

<!--热卖促销-->
<div class="JD_temai">
    <div class="JD_main">
        <div class="JD_left">
            <div class="hd">
                热卖推荐
            </div>
            <div class="bd mc">
                <ul class="mc">
                    <li>
                        <a href="/static/search/#" class="mc_a"><img src="/static/search/./img/5a28b5a1n8a5c095f.jpg" alt=""></a>
                        <div class="mc_div">
                            <a href="/static/search/#" class="mc_div_a1">
                                <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                            </a>
                            <p>
                                <strong>
                                    <em class="number J-p-5963064">¥2999.00</em>
                                </strong>
                            </p>
                            <a href="/static/search/#" class="mc_div_a2">立即抢购</a>
                        </div>
                    </li>
                    <li>
                        <a href="/static/search/#" class="mc_a"><img src="/static/search/./img/59f5eef1n99542494.jpg" alt=""></a>
                        <div class="mc_div">
                            <a href="/static/search/#" class="mc_div_a1">
                                <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                            </a>
                            <p>
                                <strong>
                                    <em class="number J-p-5963064">¥1699.00</em>
                                </strong>
                            </p>
                            <a href="/static/search/#" class="mc_div_a2">立即抢购</a>
                        </div>
                    </li>
                    <li style="margin-right: 0">
                        <a href="/static/search/#" class="mc_a"><img src="/static/search/./img/59f5eef1n99542494.jpg" alt=""></a>
                        <div class="mc_div">
                            <a href="/static/search/#" class="mc_div_a1">
                                <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                            </a>
                            <p>
                                <strong>
                                    <em class="number J-p-5963064">¥2999.00</em>
                                </strong>
                            </p>
                            <a href="/static/search/#" class="mc_div_a2">立即抢购</a>
                        </div>
                    </li>
                </ul>
            </div>
        </div>
        <div class="JD_right">
            <div class="hd"> 促销活动</div>
            <div class="bd">
                <ul>
                    <li> . <a href="/static/search/#">红米千元全面屏手机上市</a></li>
                    <li> . <a href="/static/search/#">锤子坚果Pro2火爆预约中</a></li>
                    <li> . <a href="/static/search/#">大牌新品 疯狂抢购</a></li>
                    <li> . <a href="/static/search/#">X20 vivo蓝新色上市</a></li>
                    <li> . <a href="/static/search/#">荣耀畅玩7X新品上市</a></li>
                </ul>
            </div>
        </div>
    </div>
</div>

<!--手机-->
<div class="JD_ipone">
    <div class="JD_ipone_bar">
        <div class="JD_ipone_one a">
            <a href="/static/search/#">手机</a>
        </div>
        <i><img src="/static/search/image/right-@1x.png" alt=""></i>
        <div class="JD_ipone_one b">
            <a href="/static/search/#" class="qqq">手机通讯录 <img src="/static/search/image/down-@1x.png" alt=""></a>
            <div>
                <a href="/static/search/#">手机通讯</a>
                <a href="/static/search/#">运营商</a>
                <a href="/static/search/#">手机配件</a>
                <a href="/static/search/#">手机服务</a>
            </div>
        </div>
        <i><img src="/static/search/image/right-@1x.png" alt=""></i>
        <div class="JD_ipone_one c">
            <a href="/static/search/#" class="qqq">手机 <img src="/static/search/image/down-@1x.png" alt=""></a>
            <div>
                <a href="/static/search/#">手机</a>
                <a href="/static/search/#">老人机</a>
                <a href="/static/search/#">对讲机</a>
                <a href="/static/search/#">女性手机</a>
                <a href="/static/search/#">超续航手机</a>
                <a href="/static/search/#">全面屏手机</a>
                <a href="/static/search/#">拍照手机</a>
                <a href="/static/search/#">游戏手机</a>
            </div>
        </div>
        <div class="JD_ipone_one c">
            <!--遍历面包屑功能-->
            <a th:href="${nav.link}" th:each="nav:${result.navs}"><span th:text="${nav.navName}"></span>:<span th:text="${nav.navValue}"></span> ×</a>
        </div>
        <i><img src="/static/search/image/right-@1x.png" alt=""></i>
    </div>
</div>

<!--商品筛选和排序-->
<div class="JD_banner w">
    <div class="JD_nav">
        <div class="JD_selector">
            <!--手机商品筛选-->
            <div class="title">
                <h3><b>手机</b><em>商品筛选</em></h3>
                <div class="st-ext">共&nbsp;<span>10135</span>个商品 </div>
            </div>
            <div class="JD_nav_logo" th:with="brandid= ${param.brandId}">
                <!--品牌-->
                <div th:if="${#strings.isEmpty(brandid)}" class="JD_nav_wrap">
                    <div class="sl_key">
                        <span><b>品牌:</b></span>
                    </div>
                    <div class="sl_value">
                        <div class="sl_value_logo">
                            <ul>
                                <li th:each="brand:${result.brands}">
                                    <a href="/static/search/#" th:href="${'javascript:searchProducts(&quot;brandId&quot;,'+brand.brandId+')'}">
                                        <img th:src="${brand.brandImg}" alt="">
                                        <div th:text="${brand.brandName}">
                                            华为(HUAWEI)
                                        </div>
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="sl_ext">
                        <a href="/static/search/#">
                            更多
                            <i style='background: url("image/search.ele.png")no-repeat 3px 7px'></i>
                            <b style='background: url("image/search.ele.png")no-repeat 3px -44px'></b>
                        </a>
                        <a href="/static/search/#">
                            多选
                            <i>+</i>
                            <span>+</span>
                        </a>
                    </div>
                </div>
                <!--分类-->
                <div class="JD_pre">
                    <div class="sl_key">
                        <span><b>分类:</b></span>
                    </div>
                    <div class="sl_value">
                        <ul>
                            <li th:each="catalog:${result.catalogs}">
                                <a href="/static/search/#"
                                   th:href="${'javascript:searchProducts(&quot;catalog3Id&quot;,'+catalog.catalogId+')'}"
                                   th:text="${catalog.catalogName}">5.56英寸及以上</a></li>
                        </ul>
                    </div>
                    <div class="sl_ext">
                        <a href="/static/search/#">
                            更多
                            <i style='background: url("image/search.ele.png")no-repeat 3px 7px'></i>
                            <b style='background: url("image/search.ele.png")no-repeat 3px -44px'></b>
                        </a>
                        <a href="/static/search/#">
                            多选
                            <i>+</i>
                            <span>+</span>
                        </a>
                    </div>
                </div>
                <!--其他的所有属性-->
                <div class="JD_pre" th:each="attr:${result.attrs}" th:if="${!#lists.contains(result.attrIds, attr.attrId)}">
                    <div class="sl_key">
                        <span th:text="${attr.attrName}">屏幕尺寸:</span>
                    </div>
                    <div class="sl_value">
                        <ul>
                            <li th:each="val:${attr.attrValue}">
                                <a href="/static/search/#"
                                   th:href="${'javascript:searchProducts(&quot;attrs&quot;,&quot;'+attr.attrId+'_'+val+'&quot;)'}"
                                   th:text="${val}">5.56英寸及以上</a></li>
                        </ul>
                    </div>
                </div>
            </div>
            <div class="JD_show">
                <a href="/static/search/#">
                    <span>
                        更多选项( CPU核数、网络、机身颜色 等)
                    </span>
                </a>
            </div>
        </div>
        <!--排序-->
        <div class="JD_banner_main">
            <!--商品精选-->
            <div class="JD_con_left">
                <div class="JD_con_left_bar">
                    <div class="JD_con_one">
                        <div class="mt">
                            <h3>商品精选</h3>
                            <span>广告</span>
                        </div>
                        <div class="mc">
                            <ul>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/59bf3c47n91d65c73.jpg" alt=""></a>
                                    <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                                        <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥2999.00</span>
                                        </strong>
                                        <span class="mc-ico" title="购买本商品送赠品">
                                            <i class="goods-icons">赠品</i>
                                        </span>
                                    </div>
                                    <div class="mc_rev">
                                        已有
                                        <a href="/static/search/#" class="number">12466</a>
                                        人评价
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/59bf3c47n91d65c73.jpg" alt=""></a>
                                    <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                                        <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥2999.00</span>
                                        </strong>
                                        <span class="mc-ico" title="购买本商品送赠品">
                                            <i class="goods-icons">赠品</i>
                                        </span>
                                    </div>
                                    <div class="mc_rev">
                                        已有
                                        <a href="/static/search/#" class="number">12466</a>
                                        人评价
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/593ba628n8794c6a6.jpg" alt=""></a>
                                    <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                                        <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥1799.00</span>
                                        </strong>
                                        <span class="mc-ico" title="购买本商品送赠品">
                                            <i class="goods-icons">赠品</i>
                                        </span>
                                    </div>
                                    <div class="mc_rev">
                                        已有
                                        <a href="/static/search/#" class="number">15600</a>
                                        人评价
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/5919637an271a1301.jpg" alt=""></a>
                                    <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                                        <em>vivo Xplay6 全网通 6GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥3498.00</span>
                                        </strong>
                                        <span class="mc-ico" title="购买本商品送赠品">
                                            <i class="goods-icons">赠品</i>
                                        </span>
                                    </div>
                                    <div class="mc_rev">
                                        已有
                                        <a href="/static/search/#" class="number">5369</a>
                                        人评价
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="JD_con_one">
                        <div class="mt">
                            <h3>达人选购</h3>
                        </div>
                        <div class="mc">
                            <ul>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/59bf3c47n91d65c73.jpg" alt=""></a>
                                    <a href="/static/search/#">
                                        <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥2999.00</span>
                                        </strong>
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/59bf3c47n91d65c73.jpg" alt=""></a>
                                    <a href="/static/search/#">
                                        <em>华为 HUAWEI nova 2S 全面屏四摄 6GB +64GB 曜石黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥2999.00</span>
                                        </strong>
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/593ba628n8794c6a6.jpg" alt=""></a>
                                    <a href="/static/search/#">
                                        <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥1799.00</span>
                                        </strong>
                                    </div>
                                </li>
                                <li>
                                    <a href="/static/search/#" title="vivo X9s 全网通 4GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待"><img src="/static/search/img/5919637an271a1301.jpg" alt=""></a>
                                    <a href="/static/search/#">
                                        <em>vivo Xplay6 全网通 6GB+64GB 磨砂黑 移动联通电信4G手机 双卡双待</em>
                                    </a>
                                    <div class="mc_price">
                                        <strong class="price">
                                            <span class="J-p-5963064">¥3498.00</span>
                                        </strong>
                                    </div>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="JD_con_one" style="border:none;">
                        <div class="mt">
                            <h3>商品精选</h3>
                            <span>广告</span>
                        </div>
                        <div class="mc">
                            <ul>
                                <li>
                                    <a href="/static/search/#"><img src="/static/search/img/599a806bn9d829c1c.jpg" alt=""></a>
                                </li>
                                <li>
                                    <a href="/static/search/#"><img src="/static/search/img/593e4de0n5ff878a4.jpg" alt=""></a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
            <!--综合排序-->
            <div class="JD_con_right">
                <div class="filter">
                    <!--综合排序-->
                    <div class="filter_top">
                        <div class="filter_top_left" th:with="p = ${param.sort},priceRange = ${param.skuPrice}">
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(#strings.isEmpty(p) || #strings.startsWith(p,'hotScore'))?'color: #FFF;border-color: #e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="hotScore" href="/static/search/#">综合排序 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'hotScore') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount'))?'color: #FFF;border-color:#e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="saleCount" href="/static/search/#">销量 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'saleCount') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a th:class="${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice') && #strings.endsWith(p,'desc'))?'sort_a desc':'sort_a'}"
                               th:attr="style=${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice'))?'color: #FFF;border-color:#e4393c;background: #e4393c':'color: #333;border-color: #CCC;background #fff'}"
                               sort="skuPrice" href="/static/search/#">价格 [[${(!#strings.isEmpty(p) && #strings.startsWith(p,'skuPrice') && #strings.endsWith(p,'desc'))?'↓':'↑'}]]</a>
                            <a class="sort_a" href="/static/search/#">评论分</a>
                            <a class="sort_a" href="/static/search/#">上架时间</a>
                            <input id="skuPriceFrom" type="number" style="width: 100px;margin-left: 30px;" th:value="${#strings.isEmpty(priceRange)?'':#strings.substringBefore(priceRange,'_')}"> -
                            <input id="skuPriceTo" type="number" style="width: 100px;" th:value="${#strings.isEmpty(priceRange)?'':#strings.substringAfter(priceRange,'_')}"><button id="skuPriceSearchBtn">确定</button>
                        </div>
                        <div class="filter_top_right">
                            <span class="fp-text">
                               <b>1</b><em>/</em><i>169</i>
                           </span>
                            <a href="/static/search/#" class="prev"><</a>
                            <a href="/static/search/#" class="next"> > </a>
                        </div>
                    </div>
                    <!--收货地址-->
                    <div class="filter_bottom">
                        <div class="filter_bottom_left">
                            <div class="fs-cell">收货地</div>
                            <div class="dizhi">
                                <div class="dizhi_show">
                                    <em>北京朝阳区三环以内</em>
                                    <b></b>
                                </div>
                            </div>
                            <div class="dizhi_con">
                                <ul id="tab">
                                    <li id="tab1" value="1">北京 <img src="/static/search/image/down-@1x.png" alt=""></li>
                                    <li id="tab2" value="2">朝阳 <img src="/static/search/image/down-@1x.png" alt=""></li>
                                    <li id="tab3" value="3">三环以内 <img src="/static/search/image/down-@1x.png" alt=""></li>
                                </ul>
                                <div id="container">
                                    <div id="content1" style="z-index: 1;">
                                        <a href="/static/search/#">北京</a>
                                        <a href="/static/search/#">上海</a>
                                        <a href="/static/search/#">天津</a>
                                        <a href="/static/search/#">重庆</a>
                                        <a href="/static/search/#">河北</a>
                                        <a href="/static/search/#">山西</a>
                                        <a href="/static/search/#">河南</a>
                                        <a href="/static/search/#">辽宁</a>
                                        <a href="/static/search/#">吉林</a>
                                        <a href="/static/search/#">黑龙江</a>
                                        <a href="/static/search/#">内蒙古</a>
                                        <a href="/static/search/#">江苏</a>
                                        <a href="/static/search/#">山东</a>
                                        <a href="/static/search/#">安徽</a>
                                        <a href="/static/search/#">浙江</a>
                                        <a href="/static/search/#">福建</a>
                                        <a href="/static/search/#">湖北</a>
                                        <a href="/static/search/#">湖南</a>
                                        <a href="/static/search/#">广东</a>
                                        <a href="/static/search/#">广西</a>
                                        <a href="/static/search/#">江西</a>
                                        <a href="/static/search/#">四川</a>
                                        <a href="/static/search/#">海南</a>
                                        <a href="/static/search/#">贵州</a>
                                        <a href="/static/search/#">云南</a>
                                        <a href="/static/search/#">西藏</a>
                                        <a href="/static/search/#">陕西</a>
                                        <a href="/static/search/#">甘肃</a>
                                        <a href="/static/search/#">青海</a>
                                        <a href="/static/search/#">宁夏</a>
                                        <a href="/static/search/#">新疆</a>
                                        <a href="/static/search/#">港澳</a>
                                        <a href="/static/search/#">台湾</a>
                                        <a href="/static/search/#">钓鱼岛</a>
                                        <a href="/static/search/#">海外</a>

                                    </div>
                                    <div id="content2">
                                        <a href="/static/search/#">朝阳区</a>
                                        <a href="/static/search/#">海淀区</a>
                                        <a href="/static/search/#">西城区</a>
                                        <a href="/static/search/#">东城区</a>
                                        <a href="/static/search/#">大兴区</a>
                                        <a href="/static/search/#">丰台区</a>
                                        <a href="/static/search/#">昌平区</a>
                                        <a href="/static/search/#">顺义区</a>

                                    </div>
                                    <div id="content3">
                                        <a href="/static/search/#">三环以内</a>
                                        <a href="/static/search/#">管庄</a>
                                        <a href="/static/search/#">北苑</a>
                                        <a href="/static/search/#">定福庄</a>
                                        <a href="/static/search/#">三环到四环之间</a>
                                        <a href="/static/search/#">四环到五环之间</a>
                                        <a href="/static/search/#">五环到六环之间</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="filter_bottom_right">
                            <ul>
                                <li>
                                    <a href="/static/search/#">
                                        <i></i>
                                        谷粒商城配送
                                    </a>
                                </li>
                                <li>
                                    <a href="/static/search/#">
                                        <i></i>
                                        京尊达                                    </a>
                                </li>
                                <li>
                                    <a href="/static/search/#">
                                        <i></i>
                                        货到付款
                                    </a>
                                </li>
                                <li>
                                    <a href="/static/search/#">
                                        <i></i>
                                        仅显示有货
                                    </a>
                                </li>
                                <li>
                                    <a href="/static/search/#">
                                        <i></i>
                                        可配送全球
                                    </a>
                                </li>
                            </ul>
                        </div>

                    </div>
                    <!--排序内容: 商品每四个为一组-->
                    <div class="rig_tab">
                        <div th:each="product:${result.getProducts()}">
                            <div class="ico">
                                <i class="iconfont icon-weiguanzhu"></i>
                                <a href="/static/search/#">关注</a>
                            </div>
                            <p class="da">
                                <a href="/static/search/#">
                                    <img th:src="${product.skuImg}" class="dim">
                                </a>
                            </p>
                            <ul class="tab_im">
                                <li><a href="/static/search/#" title="黑色">
                                    <img th:src="${product.skuImg}"></a></li>
                            </ul>
                            <p class="tab_R">
                                <span th:text="'¥'+${product.skuPrice}">¥5199.00</span>
                            </p>
                            <p class="tab_JE">
                                <a href="/static/search/#" th:utext="${product.skuTitle}">
                                    Apple iPhone 7 Plus (A1661) 32G 黑色 移动联通电信4G手机
                                </a>
                            </p>
                            <p class="tab_PI">已有<span>11万+</span>热门评价
                                <a href="/static/search/#">二手有售</a>
                            </p>
                            <p class="tab_CP"><a href="/static/search/#" title="谷粒商城Apple产品专营店">谷粒商城Apple产品...</a>
                                <a href='#' title="联系供应商进行咨询">
                                    <img src="/static/search/img/xcxc.png">
                                </a>
                            </p>
                            <div class="tab_FO">
                                <div class="FO_one">
                                    <p>自营
                                        <span>谷粒商城自营,品质保证</span>
                                    </p>
                                    <p>满赠
                                        <span>该商品参加满赠活动</span>
                                    </p>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!--分页-->
                    <div class="filter_page">
                        <div class="page_wrap">
                            <span class="page_span1">
                                <a class="page_a" th:attr="pn=${result.pageNum+1}"
                                   th:if="${result.pageNum>1}">
                                    < 上一页
                                </a>
                                <a class="page_a"
                                   th:attr="pn=${nav},style=${nav == result.pageNum?'border: 0;color:#ee2222;background: #fff':''}"
                                   th:each="nav:${result.pageNavs}">[[${nav}]]</a>
                                <a class="page_a" th:attr="pn=${result.pageNum+1}"
                                   th:if="${result.pageNum<result.totalPages}">
                                    下一页 >
                                </a>
                            </span>
                            <span class="page_span2">
                                <em>共<b>[[${result.totalPages}]]</b>页&nbsp;&nbsp;到第</em>
                                <input type="number" value="1">
                                <em>页</em>
                                <a >确定</a>
                            </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

<!--商品精选-->
<div class="JD_jx">
    <div class="JD_jx_title">
        <div class="mt">
            <strong class="mt-title">商品精选</strong>
            <img src="/static/search/image/u-ad.gif" alt="">
        </div>
        <div class="mc">
            <ul>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <img src="/static/search/img/5a25ffc7N98b35d49.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                        <span class="mc_ico" title="购买本商品送赠品">赠品</span>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">15930</a>
                        <span>人好评</span>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <img src="/static/search/img/5a25ffc7N98b35d49.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                        <span class="mc_ico" title="购买本商品送赠品">赠品</span>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">15930</a>
                        <span>人好评</span>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <img src="/static/search/img/5a25ffc7N98b35d49.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                        <span class="mc_ico" title="购买本商品送赠品">赠品</span>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">15930</a>
                        <span>人好评</span>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <img src="/static/search/img/5a25ffc7N98b35d49.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                        <span class="mc_ico" title="购买本商品送赠品">赠品</span>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">15930</a>
                        <span>人好评</span>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <img src="/static/search/img/5a25ffc7N98b35d49.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待">
                            <em>【预约版】华为 HUAWEI 畅享7S 全面屏双摄 4GB +64GB 黑色 移动联通电信4G手机 双卡双待</em>
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                        <span class="mc_ico" title="购买本商品送赠品">赠品</span>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">15930</a>
                        <span>人好评</span>
                    </div>
                </li>
            </ul>


        </div>
    </div>
</div>

<!--猜你喜欢-->
<div class="JD_cnxh">
    <div class="JD_jx_title">
        <div class="mt">
            <strong class="mt-title">猜你喜欢</strong>
            <a href="/static/search/#">
                <img src="/static/search/image/update.png" alt="">
                换一批
            </a>
        </div>
        <div class="mc">
            <ul>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/59bf3c47n91d65c73.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a28b5c6Ndec5088f.jpg" alt=""></a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机"><img src="/static/search/img/593e4de0n5ff878a4.jpg" alt=""></a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机"><img src="/static/search/img/593e4de0n5ff878a4.jpg" alt=""></a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机"><img src="/static/search/img/59c493a7N3f9b9c85 (1).jpg" alt=""></a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机"><img src="/static/search/img/59c493a7N3f9b9c85 (1).jpg" alt=""></a>
                    </div>
                    <div class="mc_name">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <em>诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机</em>
                        </a>
                    </div>
                    <div class="mc_rev">
                        <a href="/static/search/#">已有80万+人评价</a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥1999.00</span>
                        </strong>
                    </div>

                </li>
            </ul>


        </div>
    </div>
</div>

<!--我的足迹-->
<div class="JD_zuji">
    <div class="JD_jx_title">
        <div class="mt">
            <strong class="mt-title">我的足迹</strong>
            <a href="/static/search/#">
                更多浏览记录
            </a>
        </div>
        <div class="mc">
            <ul>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/59e58a11Nc38676d5.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥2998.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a28acccN73689386.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥88.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a1690ddN441b5dce.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥199.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a02bde7N7d4453b1.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥799.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a122dbeN044ebf19.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥599.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/59c493a7N3f9b9c85.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥699.00</span>
                        </strong>
                    </div>
                </li>
                <li>
                    <div class="mc_img">
                        <a href="/static/search/#" title="诺基亚 7 (Nokia 7) 4GB+64GB 黑色 全网通 双卡双待 移动联通电信4G手机">
                            <img src="/static/search/img/5a08f6f6N5bab2c1c.jpg" alt="">
                        </a>
                    </div>
                    <div class="mc_price">
                        <strong>
                            <span>¥715.00</span>
                        </strong>
                    </div>
                </li>
            </ul>


        </div>
    </div>
</div>

<div style="width: 1210px;margin: 0 auto;margin-bottom: 10px"><img src="/static/search/img/5a33a2e0N9a04b4af.jpg" alt=""></div>
<!--底部-->
<footer class="footer">
    <div class="footer_top">
        <ul>
            <li>
                <span></span>
                <h3>品类齐全,轻松购物</h3>
            </li>
            <li>
                <span></span>
                <h3>多仓直发,极速配发</h3>
            </li>
            <li>
                <span></span>
                <h3>正品行货,精致服务</h3>
            </li>
            <li>
                <span></span>
                <h3>天天低价,畅选无忧</h3>
            </li>
        </ul>
    </div>
    <div class="footer_center">
        <ol>
            <li>购物指南</li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">购物流程</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">会员介绍</a>
            </li>
            <li><a href="/static/search/#">生活旅行</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">常见问题</a>
            </li>
            <li><a href="/static/search/#">大家电</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">联系客服</a>
            </li>
        </ol>
        <ol>
            <li>配送方式</li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">上门自提</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">211限时达</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">配送服务查询</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">配送费收取标准</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">海外配送</a>
            </li>
        </ol>
        <ol>
            <li>支付方式</li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">货到付款</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">在线支付</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">分期付款</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">邮局汇款</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">公司转账</a>

            </li>
        </ol>
        <ol>
            <li>售后服务</li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">售后政策</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">价格保护</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">退款说明</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">返修/退换货</a>
            </li>
            <li><a href="/static/search/#">取消订单</a>
            </li>
        </ol>
        <ol>
            <li>特色服务</li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">夺宝岛</a>
            </li>
            <li><a href="/static/search/#">DIY装机</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">延保服务</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">谷粒商城E卡</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">谷粒商城通信</a>
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">谷粒商城gulimall+</a>
            </li>
        </ol>
        <ol>
            <li>谷粒商城自营覆盖区域</li>
            <li>
                谷粒商城已向全国2661个区县提供自<br> 营配送服务,支持货到付款、
                <br> POS机刷卡和售后上门服务。
            </li>
            <li><a href="/static/search/#" style="color: rgb(114, 114, 114);">查看详情&gt;</a>
            </li>
        </ol>
    </div>
    <div class="footer_foot">
        <p class="footer_p p1">
            <a href="/static/search/#">关于我们</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">联系我们</a>
            <span></span>
            <a href="/static/search/#">联系客服</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">合作招商</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">商家帮助</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">营销中心</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">手机谷粒商城</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">友情链接</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">销售联盟</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">谷粒商城社区</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">风险监测</a>
            <span></span>
            <a href="/static/search/#">隐私政策</a>
            <span></span>
            <a href="/static/search/#">谷粒商城公益</a>
            <span></span>
            <a href="/static/search/#" style="color: rgb(114, 114, 114);">English Site</a>
            <span></span>
            <a href="/static/search/#">media &amp; IR</a>
        </p>
        <p class="footer_p">
            <a href="/static/search/#">京公网安备 11000002000088号</a>
            <span></span>
            <a href="/static/search/#">京ICP证070359号</a>
            <span></span>
            <a href="/static/search/#">互联网药品信息服务资格证编号(京)-经营性-2014-0008</a>
            <span></span>
            <a href="/static/search/#">新出发京零 字第大120007号</a>
        </p>
        <p class="footer_p">
            <a href="/static/search/#">互联网出版许可证编号新出网证(京)字150号</a>
            <span></span>
            <a href="/static/search/#">出版物经营许可证</a>
            <span></span>
            <a href="/static/search/#">网络文化经营许可证京网文[2014]2148-348号</a>
            <span></span>
            <a href="/static/search/#">违法和不良信息举报电话:4006561155</a>
        </p>
        <p class="footer_p">
            <a href="/static/search/#">Copyright © 2004 - 2017  谷粒商城JD.com 版权所有</a>
            <span></span>
            <a href="/static/search/#">消费者维权热线:4006067733</a>
            <a href="/static/search/#">经营证照</a>
        </p>
        <p class="footer_p">
            <a href="/static/search/#">谷粒商城旗下网站:</a>
            <a href="/static/search/#">谷粒商城支付</a>
            <span></span>
            <a href="/static/search/#">谷粒商城云</a>
        </p>
        <ul>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</footer>

<!--右侧侧边栏-->
<div class="header_bar">
    <div class="header_bar_box">
        <ul>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/wo.png" /></a>
                <div class="div">
                    <a href="/static/search/#">谷粒商城会员</a>
                </div>
            </li>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/gouwuche.png" /></a>
                <div class="div">
                    <a href="/static/search/#">购物车</a>
                </div>
            </li>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/taoxin.png" /></a>
                <div class="div">
                    <a href="/static/search/#">我的关注</a>
                </div>
            </li>

            <li>
                <a href="/static/search/#"><img src="/static/search/img/shi.png" /></a>
                <div class="div">
                    <a href="/static/search/#">我的足迹</a>
                </div>
            </li>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/xinxi.png" /></a>
                <div class="div">
                    <a href="/static/search/#">我的消息</a>
                </div>
            </li>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/qianbao.png" /></a>
                <div class="div">
                    <a href="/static/search/#">资讯JIMI</a>
                </div>
            </li>
        </ul>
        <ul>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/fa3f24a70d38bd439261cb7439e517a5.png" /></a>
                <div class="div">
                    <a href="/static/search/#">顶部</a>
                </div>
            </li>
            <li>
                <a href="/static/search/#"><img src="/static/search/img/xinxi.png" /></a>
                <div class="div">
                    <a href="/static/search/#">反馈</a>
                </div>
            </li>
        </ul>
    </div>
</div>

<script>
    $(".sl_ext a:nth-child(1)").hover(function(){
        $(this).children("b").stop(true).animate({top:"3px"},50);
        $(this).children("i").stop(true).animate({top:"-23px"},50)
    },function(){
        $(this).children("b").stop(true).animate({top:"24px"},50);
        $(this).children("i").stop(true).animate({top:"3px"},50)
    });
    $(".sl_ext a:nth-child(2)").hover(function(){
        $(this).children("span").stop(true).animate({top:"-1px"},100);
        $(this).children("i").stop(true).animate({top:"-14px"},100).css({display:"none"})
    },function(){
        $(this).children("span").stop(true).animate({top:"14px"},100);
        $(this).children("i").stop(true).animate({top:"-1px"},100).css({display:"block"})
    });
    $('.tab_im img').hover(function(){
        var a=$(this).prop('src');
        var index=$(this).parents('li').index();
        $(this).parents('li').css('border','2px solid red').siblings('li').css('border','1px solid #ccc');
        $(this).parents('ul').prev().find('img').prop('src',a);
        $(this).parents('ul').siblings('.tab_JE').find('a').eq(list).css('display','block').siblings('a').css('display','none');
        $(this).parents('ul').siblings('.tab_R').find('span').eq(list).css('display','block').siblings('span').css('display','none')
    });

    $(".JD_ipone_one").hover(function(){
        $(this).children("div").css({display:"block"})
    },function(){
        $(this).children("div").css({display:"none"})
    });

    $("#tab>li").click(function() {
        var i = $(this).index();
        $("#container>div").hide().eq(i).show()
    });
    $(".dizhi_show").hover(function(){
        $(".dizhi_con").css({display:"block"})
    },function(){
        $(".dizhi_con").css({display:"none"})
    });
    $(".dizhi_con").hover(function(){
        $(this).css({display:"block"})
    },function(){
        $(this).css({display:"none"})
    });
    //显示隐藏
    var $li = $(".JD_nav_logo>div:gt(3)").hide();
      $('.JD_show span').click(function(){
          if($li.is(':hidden')){
              $li.show();
              $(this).css({width:"86px"}).text('收起 ^');
          }else{
              $li.hide();
              $('.JD_show span').css({width:"291px"}).text('更多选项( CPU核数、网络、机身颜色 等)');
          }
          return false;
      });



    $(".rig_tab>div").hover(function(){
        var i = $(this).index();
        $(this).find('.ico').css({display:'block'}).stop(true).animate({top:"190px"},300)
    },function(){
        var i = $(this).index();
        $(this).find('.ico').css({display:'none'}).stop(true).animate({top:"230px"})
    });

    $('.header_main_left>ul>li').hover(function() {
        $(this).css({
            background: "#f0f0f0"
        }).find('.header_main_left_main').stop(true).fadeIn(300)
    }, function() {
        $(this).css({
            background: "#fff"
        }).find(".header_main_left_a").css({
            color: "#000"
        });
        $(this).find('.header_main_left_main').stop(true).fadeOut(100)
    });
    $(".header_sj a").hover(function() {
        $(this).css({
            background: "#444"
        })
    }, function() {
        $(this).css({
            background: "#6e6568"
        })
    });


    $(".nav_li1 a").hover(function(){
        $(".header_main_left").stop(true).fadeIn()
    },function(){
        $(".header_main_left").stop(true).fadeOut()
    });
    $(".header_main_left").hover(function(){
        $(this).stop(true).fadeIn()
    },function(){
        $(this).stop(true).fadeOut()
    });


    //右侧侧边栏
    $(".header_bar_box ul li").hover(function() {
        $(this).css({
            background: "#7A6E6E"
        }).children(".div").css({
            display: "block"
        }).stop(true).animate({
            left: "-60px"
        }, 300)
    }, function() {
        $(this).css({
            background: "#7A6E6E"
        }).children(".div").css({
            display: "none"
        }).stop(true).animate({
            left: "0"
        }, 300)
    });


    //底部
    $(".footer_foot .p1 a").hover(function(){
        $(this).css("color","#D70B1C")
    },function(){
        $(this).css("color","#727272")
    });

    $(".footer .footer_center ol li a").hover(function(){
        $(this).css("color","#D70B1C")
    },function(){
        $(this).css("color","#727272")
    })

    function searchProducts(name,value) {
        //原来的页面
        location.href = replaceAndParamVal(location.href,name,value,true);
    }

    function searchByKeyword(){
        searchProducts("keyword",$("#keyword_input").val());
    }

    $(".page_a").click(function (){
       var pn = $(this).attr("pn");
       var href = location.href;
       if(href.indexOf("pageNum") != -1){
           //替换pagenum的值
           location.href = replaceAndParamVal(href,"pageNum",pn)
       }else if(href.indexOf("?") != -1){
           location.href = location.href + "&pageNum="+pn;
       }else {
           location.href = location.href + "?pageNum="+pn;
       }
       return false;
    });

    function replaceAndParamVal(url,paramName,replaceVal,forceAdd){
        var oUrl = url.toString();
        //1.如果没有就添加,有就替换
        if(oUrl.indexOf(paramName) != -1) {
            if(forceAdd){
                var nUrl = "";
                if(oUrl.indexOf("?") != -1){
                    nUrl = oUrl +"&"+paramName + '=' + replaceVal;
                }else{
                    nUrl = oUrl +"?"+paramName + '=' + replaceVal;
                }
                return nUrl;
            }else {
                var re = eval('/(' + paramName + '=)([^&]*)/gi');
                var nUrl = oUrl.replace(re, paramName + '=' + replaceVal);
                return nUrl;
            }
        }else {
            var nUrl = "";
            if(oUrl.indexOf("?") != -1){
                nUrl = oUrl +"&"+paramName + '=' + replaceVal;
            }else{
                nUrl = oUrl +"?"+paramName + '=' + replaceVal;
            }
            return nUrl;
        }
    }

    $(".sort_a").click(function (){
        //1.当前被点击的元素变为选中状态
        // 改变当前元素以及兄弟元素的样式
        // changeStyle(this);
        $(this).toggleClass("desc");
        //2.跳转到指定位置 sort=skuPrice_asc/desc
        var sort = $(this).attr("sort");
        sort = $(this).hasClass("desc")?sort+"_desc":sort+"_asc";
        location.href = replaceAndParamVal(location.href,"sort",sort);
        //禁用默认行为
        return false;
    });

    function changeStyle(ele){
        $(".sort_a").css({"color":"#333","border-color":"#CCC","background":"#FFF"});
        $(".sort_a").each(function(){
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬇";
            $(ele).text(text);
        });
        $(ele).css({"color":"#FFF","border-color":"#e4393c","background":"#e4393c"});
        //改变升降序
        $(ele).toggleClass("desc");//加上就是降序,不加就是升序
        if($(ele).hasClass("desc")){
            //降序
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬇";
            $(ele).text(text);
        }else{
            var text = $(ele).text().replace("⬇","").replace("⬆","");
            text = text + "⬆";
            $(ele).text(text);
        }
    };

    $("#skuPriceSearchBtn").click(function (){
        //1.拼上价格区间的查询条件
        var from = $("#skuPriceFrom").val();
        var to = $("#skuPriceTo").val();
        var query = from + "_" + to;
        location.href = replaceAndParamVal(location.href,"skuPrice",query);
    });
</script>
</body>
</html>

2、search模块下的远程调用方法

package com.atguigu.gulimall.search.feign;


import com.atguigu.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

@FeignClient("gulimall-product")
public interface ProductFeignService {

    @GetMapping("/product/attr/info/{attrId}")
    public R attrInfo(@PathVariable("attrId") Long attrId);

    @GetMapping("/product/brand/infos")
    public R brandsInfo(@RequestParam("brandIds") List<Long> brandIds);
}

3、search模块下的controller类

package com.atguigu.gulimall.search.controller;


import com.atguigu.gulimall.search.service.MallSearchService;
import com.atguigu.gulimall.search.vo.SearchParam;
import com.atguigu.gulimall.search.vo.SearchResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class SearchController {

    @Autowired
    MallSearchService mallSearchService;

    @GetMapping("/list.html")
    public String listPage(SearchParam param, Model model, HttpServletRequest request){
        param.set_queryString(request.getQueryString());
        //1.根据传递过来的页面查询参数,去es中检索商品
        SearchResult result = mallSearchService.search(param);
        model.addAttribute("result", result);
        return "list";
    }
}

4、Impl实现类

package com.atguigu.gulimall.search.service.Impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.common.to.es.SkuEsModel;
import com.atguigu.common.utils.R;
import com.atguigu.gulimall.search.config.GulimallElasticSearchConfig;
import com.atguigu.gulimall.search.constant.EsConstant;
import com.atguigu.gulimall.search.feign.ProductFeignService;
import com.atguigu.gulimall.search.service.MallSearchService;
import com.atguigu.gulimall.search.vo.AttrResponseVo;
import com.atguigu.gulimall.search.vo.BrandVo;
import com.atguigu.gulimall.search.vo.SearchParam;
import com.atguigu.gulimall.search.vo.SearchResult;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.nested.NestedAggregationBuilder;
import org.elasticsearch.search.aggregations.bucket.nested.ParsedNested;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedStringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.swing.*;
import javax.swing.text.Highlighter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@Service
public class MallSearchServiceImpl implements MallSearchService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    ProductFeignService productFeignService;

    @Override
    public SearchResult search(SearchParam param) {
        //1.动态构建出查询需要的DSL语句
        SearchResult result = null;
        //1.准备检索请求
        SearchRequest searchRequest = buildSearchRequrest(param);

        try {
            //2.执行检索请求
            SearchResponse response = client.search(searchRequest, GulimallElasticSearchConfig.COMMON_OPTIONS);

            //3.分析相应数据封装成我们需要的格式
            result = buildSearchResult(response, param);

        }catch (IOException e){
            e.printStackTrace();
        }

        return result;
    }

    /**
     * 准备检索请求
     * #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
     * @return
     */
    private SearchRequest buildSearchRequrest(SearchParam param) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();//构建DSL语句的
        /**
         * 查询: 过滤(按照属性,分类,品牌,价格区间,库存)
         */
        //1. 构建bool-query
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //1.1 must-模糊查询
        if(!StringUtils.isEmpty(param.getKeyword())){
            boolQuery.must(QueryBuilders.matchQuery("skuTitle",param.getKeyword()));
        }
        //1.2 bool-filter- 按照三级分类id查询
        if(param.getCatalog3Id()!=null){
            boolQuery.filter(QueryBuilders.termQuery("catalogId",param.getCatalog3Id()));
        }
        //1.2 bool-filter- 按照品牌id查询
        if(param.getBrandId()!=null && param.getBrandId().size()>0){
            boolQuery.filter(QueryBuilders.termsQuery("brandId", param.getBrandId()));
        }
        //1.2 bool-filter- 按照所有指定的属性进行查询
        if(param.getAttrs()!=null && param.getAttrs().size()>0){
            for(String attrStr : param.getAttrs()){
                //attrs=1_5寸:8寸&attrs=2_16g:8g
                BoolQueryBuilder nestedboolQuery = QueryBuilders.boolQuery();
                //attrs= 1_5寸:8寸
                String[] s = attrStr.split("_");
                String attrId = s[0];//检索的属性id
                String[] attrValue = s[1].split(":");//用这个属性的检索用值
                nestedboolQuery.must(QueryBuilders.termQuery("attrs.attrId", attrId));
                nestedboolQuery.must(QueryBuilders.termsQuery("attrs.attrValue", attrValue));
                //每一个必须都得生成一个nested查询
                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs",nestedboolQuery, ScoreMode.None);
                boolQuery.filter(nestedQuery);
            }
        }


        //1.2 bool-filter- 按照库存是否有进行查询
        if(param.getHasStock() != null) {
            boolQuery.filter(QueryBuilders.termsQuery("hasStock", param.getHasStock() == 1));
        }

        //1.2 bool-filter- 按照价格区间
        if(!StringUtils.isEmpty(param.getSkuPrice())){
            //1_500 _500 500_
            //gte上区间
            //lte下区间
            RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("skuPrice");
            String[] s = param.getSkuPrice().split("_");
            if(s.length == 2){
                rangeQuery.gte(s[0]).lte(s[1]);
            }else if(s.length == 1){
                if(param.getSkuPrice().startsWith("_")){
                    rangeQuery.lte(s[0]);
                }
                if(param.getSkuPrice().endsWith("_")){
                    rangeQuery.gte(s[0]);
                }
            }
            boolQuery.filter(rangeQuery);
        }
        //把以前的所有条件都拿来进行封装
        sourceBuilder.query(boolQuery);

        /**
         * 排序,分页,高亮
         */

        //2.1 排序
        if(!StringUtils.isEmpty(param.getSort())){
            String sort = param.getSort();
            //sort = hotScore_asc/desc
            String[] s = sort.split("_");
            SortOrder order = s[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
            sourceBuilder.sort(s[0], order);
        }
        //2.2 分页 pageSize:5
        //pageNum:1 from:0 size:5 [0.1.2.3.4]
        //pageNum:2 from:5 size:5
        //from = (pageNum - 1)*size
        sourceBuilder.from((param.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
        sourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);

        //2.3 高亮
        if(!StringUtils.isEmpty(param.getKeyword())){
            HighlightBuilder builder = new HighlightBuilder();
            builder.field("skuTitle");
            builder.preTags("<b style='color:red'>");
            builder.postTags("</b>");
            sourceBuilder.highlighter(builder);
        }
        /**
         * 聚合分析
         */
        //1.品牌聚合
        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
        brand_agg.field("brandId").size(50);
        //品牌聚合的子聚合
        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
        sourceBuilder.aggregation(brand_agg);

        //2.分类聚合
        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
        sourceBuilder.aggregation(catalog_agg);

        //3.属性聚合
        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg","attrs");
        //聚合分析出当前attr_id
        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId");
        //聚合分析出当前attr_id对应的名字
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
        //聚合分析出当前attr_id对应的所有可能的属性值attrValue
        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
        attr_agg.subAggregation(attr_id_agg);
        sourceBuilder.aggregation(attr_agg);

        String s = sourceBuilder.toString();
        System.out.println("构建DSL" + s);
        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, sourceBuilder);

        return searchRequest;
    }
    /**
     * 构建检索请求:
     * #模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存),排序,分页,高亮,聚合分析
     * */
//    private SearchRequest buildSearchRequrest(SearchParam searchParam) {
//        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();//构建DSL语句
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//        /**
//         * 模糊匹配,过滤(按照属性,分类,品牌,价格区间,库存)
//         * */
//        //1.构建bool-query
//        //1.1 模糊匹配 bool - must
//        if (!StringUtils.isEmpty(searchParam.getKeyword())){
//            boolQueryBuilder.must(QueryBuilders.matchQuery("skuTitle",searchParam.getKeyword()));
//        }
//        //1.2 bool - filter 按照三级分类id查询
//        if (searchParam.getCatalog3Id()!=null){
//            boolQueryBuilder.filter(QueryBuilders.termQuery("catalogId",searchParam.getCatalog3Id()));
//        }
//        //1.3 bool -filter  按照品牌id查询
//        if (searchParam.getBrandId()!=null&&searchParam.getBrandId().size()>0){
//            boolQueryBuilder.filter(QueryBuilders.termsQuery("brandId",searchParam.getBrandId()));
//        }
//        //1.4 bool -filter - nested  按照指定的属性查询
//        if (searchParam.getAttrs()!=null&&searchParam.getAttrs().size()>0){
//            //每一个属性查询必须都得生成一个nested查询
//            for (String attr : searchParam.getAttrs()) {
//                BoolQueryBuilder nestedBoolQuery = QueryBuilders.boolQuery();
//                //attrs=1_5寸:8寸&attrs=2_16G:8G
//                String[] attrSplit = attr.split("_");
//                String attrId = attrSplit[0];
//                String[] attrValues = attrSplit[1].split(":");
//                nestedBoolQuery.must(QueryBuilders.termQuery("attrs.attrId",attrId));
//                nestedBoolQuery.must(QueryBuilders.termsQuery("attrs.attrValue",attrValues));
//                //每一个必须都得生成一个nested查询
//                NestedQueryBuilder nestedQuery = QueryBuilders.nestedQuery("attrs", nestedBoolQuery, ScoreMode.None);
//                boolQueryBuilder.filter(nestedQuery);
//            }
//        }
//        //1.5 bool -filter 是否有库存查询
//        if (searchParam.getHasStock()==null){
//            //如果没有传输是否有库存这个参数,默认查找有库存的
//            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",true));
//        }else {
//            boolQueryBuilder.filter(QueryBuilders.termQuery("hasStock",searchParam.getHasStock()==0));
//        }
//
//        //1.6按照价格区间
//        if (!StringUtils.isEmpty(searchParam.getSkuPrice())){
//            RangeQueryBuilder skuPriceRangeQuery = QueryBuilders.rangeQuery("skuPrice");
//            String[] s = searchParam.getSkuPrice().split("_");
//            if (s.length == 2 ){
//                //区间
//                skuPriceRangeQuery.gte(s[0]).lte(s[1]);
//            }else if (s.length==1){
//                if (searchParam.getSkuPrice().startsWith("_")){
//                    skuPriceRangeQuery.lte(s[0]);
//                }
//                if (searchParam.getSkuPrice().endsWith("_")){
//                    skuPriceRangeQuery.gte(s[0]);
//                }
//            }
//            boolQueryBuilder.filter(skuPriceRangeQuery);
//        }
//        searchSourceBuilder.query(boolQueryBuilder);
//
//        /**
//         * 排序,分页,
//         *       sort=saleCount_asc/desc
//         *       sort=skuPrice_asc/desc
//         *       sort= hotScore_asc/desc
//         * */
//        if (!StringUtils.isEmpty(searchParam.getSort())){
//            String sort = searchParam.getSort();
//            String[] sortSplit = sort.split("_");
//            SortOrder sortOrder = sortSplit[1].equalsIgnoreCase("asc")?SortOrder.ASC:SortOrder.DESC;
//            searchSourceBuilder.sort(sortSplit[0],sortOrder);
//        }
//        //分页
//        if (searchParam.getPageNum()==null){
//            //如果没有传输pagenum参数,默认为第一页
//            searchSourceBuilder.from(((1-1)*EsConstant.PRODUCT_PAGESIZE));
//            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
//        }else {
//            searchSourceBuilder.from((searchParam.getPageNum()-1)*EsConstant.PRODUCT_PAGESIZE);
//            searchSourceBuilder.size(EsConstant.PRODUCT_PAGESIZE);
//        }
//
//        /**
//         * 高亮
//         * */
//        if (!StringUtils.isEmpty(searchParam.getKeyword())){
//            HighlightBuilder highlightBuilder=new HighlightBuilder();
//            highlightBuilder.field("skuTitle");
//            highlightBuilder.preTags("<b style= 'color:red'>");
//            highlightBuilder.postTags("</b>");
//            searchSourceBuilder.highlighter(highlightBuilder);
//        }
//        /**
//         * 聚合分析
//         * */
//
//        //1.品牌的聚合
//        TermsAggregationBuilder brand_agg = AggregationBuilders.terms("brand_agg");
//        brand_agg.field("brandId");
//        //品牌的子聚合
//        brand_agg.subAggregation(AggregationBuilders.terms("brand_name_agg").field("brandName").size(1));
//        brand_agg.subAggregation(AggregationBuilders.terms("brand_img_agg").field("brandImg").size(1));
//        //TODO 1. 品牌的聚合
//        searchSourceBuilder.aggregation(brand_agg);
//        //2.分类聚合 catalog_agg
//        TermsAggregationBuilder catalog_agg = AggregationBuilders.terms("catalog_agg").field("catalogId").size(20);
//        catalog_agg.subAggregation(AggregationBuilders.terms("catalog_name_agg").field("catalogName").size(1));
//        //TODO 2. 分类的聚合
//        searchSourceBuilder.aggregation(catalog_agg);
//        //3.属性聚合 attr_agg
//        NestedAggregationBuilder attr_agg = AggregationBuilders.nested("attr_agg", "attrs");
//        //3.1聚合当前所有的attrId
//        TermsAggregationBuilder attr_id_agg = AggregationBuilders.terms("attr_id_agg").field("attrs.attrId").size(10);
//        //3.2聚合分析出当前attr_id对应的名字
//        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_name_agg").field("attrs.attrName").size(1));
//        //3.3聚合分析出当前attr_id对应的所有可能的属性值attrValue
//        attr_id_agg.subAggregation(AggregationBuilders.terms("attr_value_agg").field("attrs.attrValue").size(50));
//        attr_agg.subAggregation(attr_id_agg);
//        //TODO 3. 属性的聚合
//        searchSourceBuilder.aggregation(attr_agg);
//        //打印构造的DSL
//        String s = searchSourceBuilder.toString();
//        System.out.println("构建的DSL:"+s);
//
//        SearchRequest searchRequest = new SearchRequest(new String[]{EsConstant.PRODUCT_INDEX}, searchSourceBuilder);
//        return searchRequest;
//    }

    /**
     * 构建结果
     */
    private SearchResult buildSearchResult(SearchResponse response,SearchParam param){

        SearchResult result = new SearchResult();
        //1. 返回所有查询到的商品
        SearchHits hits = response.getHits();
        List<SkuEsModel> esModels = new ArrayList<>();
        if(hits.getHits() != null && hits.getHits().length > 0){
            for(SearchHit hit : hits.getHits()){
                String sourceAsString = hit.getSourceAsString();
                SkuEsModel esModel = JSON.parseObject(sourceAsString, SkuEsModel.class);
                if(!StringUtils.isEmpty(param.getKeyword())){
                    HighlightField skuTitle = hit.getHighlightFields().get("skuTitle");
                    String string =  skuTitle.getFragments()[0].string();
                    esModel.setSkuTitle(string);
                }
                esModels.add(esModel);
            }
        }
        result.setProducts(esModels);
        //2. 当前所有商品涉及到的所有属性信息
        List<SearchResult.AttrVo> attrVos = new ArrayList<>();
        ParsedNested attr_agg = response.getAggregations().get("attr_agg");
        ParsedLongTerms attr_id_agg = attr_agg.getAggregations().get("attr_id_agg");
        for(Terms.Bucket bucket : attr_id_agg.getBuckets()){
            SearchResult.AttrVo attrVo = new SearchResult.AttrVo();
            //1.得到属性的id
            long attrId = bucket.getKeyAsNumber().longValue();
            //2.得到属性的名字
            String attrName = ((ParsedStringTerms) bucket.getAggregations().get("attr_name_agg")).getBuckets().get(0).getKeyAsString();
            //3.得到属性的所有值
            List<String> attrValues = ((ParsedStringTerms) bucket.getAggregations().get("attr_value_agg")).getBuckets().stream().map(item->{
                String keyAsString = ((Terms.Bucket) item).getKeyAsString();
                return keyAsString;
            }).collect(Collectors.toList());
            attrVo.setAttrId(attrId);
            attrVo.setAttrName(attrName);
            attrVo.setAttrValue(attrValues);

            attrVos.add(attrVo);
        }
        result.setAttrs(attrVos);
        //3. 当前所有商品涉及到的所有品牌信息
        List<SearchResult.BrandVo> brandVos = new ArrayList<>();
        ParsedLongTerms brand_agg = response.getAggregations().get("brand_agg");
        for(Terms.Bucket bucket : brand_agg.getBuckets()){
            SearchResult.BrandVo brandVo = new SearchResult.BrandVo();
            //1. 得到品牌id
            long brandId = bucket.getKeyAsNumber().longValue();
            //2. 得到品牌名
            String brandName = ((ParsedStringTerms)bucket.getAggregations().get("brand_name_agg")).getBuckets().get(0).getKeyAsString();
            //3. 得到品牌的图片
            String brandImg = ((ParsedStringTerms)bucket.getAggregations().get("brand_img_agg")).getBuckets().get(0).getKeyAsString();
            brandVo.setBrandId(brandId);
            brandVo.setBrandName(brandName);
            brandVo.setBrandImg(brandImg);
            brandVos.add(brandVo);
        }
        result.setBrands(brandVos);
        //4. 当前所有商品涉及到的所有分类信息
        ParsedLongTerms catalog_agg = response.getAggregations().get("catalog_agg");

        List<SearchResult.CatalogVo> catalogVos = new ArrayList<>();
        List<? extends Terms.Bucket> buckets = catalog_agg.getBuckets();
        for(Terms.Bucket bucket : buckets){
            SearchResult.CatalogVo catalogVo = new SearchResult.CatalogVo();
            //得到分类id
            String keyAsString = bucket.getKeyAsString();
            catalogVo.setCatalogId(Long.parseLong(keyAsString));

            //得到分类名
            ParsedStringTerms catalog_name_agg = bucket.getAggregations().get("catalog_name_agg");
            String catalog_name = catalog_name_agg.getBuckets().get(0).getKeyAsString();
            catalogVo.setCatalogName(catalog_name);
            catalogVos.add(catalogVo);
        }
        result.setCatalogs(catalogVos);
//==========以上从聚合信息中获取==============


        //5. 分页信息-页码
        result.setPageNum(param.getPageNum());
        //5. 分页信息-总记录数
        long total = hits.getTotalHits().value;
        result.setTotal(total);

        //5. 分页信息-总页码
        int totalPages = (int)total%EsConstant.PRODUCT_PAGESIZE == 0?(int)total/EsConstant.PRODUCT_PAGESIZE:((int)total/EsConstant.PRODUCT_PAGESIZE + 1);
        result.setTotalPages(totalPages);

        List<Integer> pageNavs = new ArrayList<>();
        for(int i = 1; i <= totalPages; i++){
            pageNavs.add(i);
        }
        result.setPageNavs(pageNavs);

        //6.构建面包屑导航功能
        if(param.getAttrs() != null && param.getAttrs().size()>0){
            List<SearchResult.NavVo> collect = param.getAttrs().stream().map(attr -> {
                //1.分析每个attrs传过来的查询参数值
                SearchResult.NavVo navVo = new SearchResult.NavVo();
                String[] s = attr.split("_");
                navVo.setNavValue(s[1]);
                R r = productFeignService.attrInfo(Long.parseLong(s[0]));
                result.getAttrIds().add(Long.parseLong(s[0]));
                if(r.getCode() == 0){
                    AttrResponseVo data = r.getData("attr", new TypeReference<AttrResponseVo>(){
                    });
                    navVo.setNavName(data.getAttrName());
                }else{
                    navVo.setNavName(s[0]);
                }
                //2.取消面包屑后,跳转剩下条件的页面
                //将请求地址的url清空
                //拿到所有的查询条件,去掉当前
                String replace = replaceQueryString(param, attr, "attrs");
                navVo.setLink("http://search.yjlmall.com/list.html?"+replace);
                return navVo;
            }).collect(Collectors.toList());

            result.setNavs(collect);
        }

        //品牌 分类
        if(param.getBrandId() != null && param.getBrandId().size() > 0){
            List<SearchResult.NavVo> navs = result.getNavs();
            SearchResult.NavVo navVo = new SearchResult.NavVo();
            navVo.setNavName("品牌");
            //TODO 远程查询所有品牌
            R r = productFeignService.brandsInfo(param.getBrandId());
            if(r.getCode() == 0){
                List<BrandVo> brand = r.getData("brand", new TypeReference<List<BrandVo>>() {});
                StringBuffer buffer = new StringBuffer();
                String replace = "";
                for (BrandVo brandVo : brand){
                    buffer.append(brandVo.getBrandName()+";");
                    replace = replaceQueryString(param,brandVo.getBrandId()+"","brandId");
                }
                navVo.setNavValue(buffer.toString());
                navVo.setLink("http://search.yjlmall.com/list.html?"+replace);
            }
            navs.add(navVo);
        }
        //TODO 分类:不需要导航取消
        return result;
    }

    private String replaceQueryString(SearchParam param, String value, String key){
        String encode = null;
        try{
            encode = URLEncoder.encode(value, "UTF-8");
            encode = encode.replace("+","%20");
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
        }
        return param.get_queryString().replace("&"+key+"=" + encode, "");
    }
}

5、实体类

在这里插入图片描述

package com.atguigu.gulimall.search.vo;

import lombok.Data;

@Data
public class BrandVo {
    private Long brandId;
    private String brandName;
}

package com.atguigu.gulimall.search.vo;

import lombok.Data;

@Data
public class AttrResponseVo {
    /**
     * 属性id
     */
    private Long attrId;
    /**
     * 属性名
     */
    private String attrName;
    /**
     * 是否需要检索[0-不需要,1-需要]
     */
    private Integer searchType;

    private Integer valueType;
    /**
     * 属性图标
     */
    private String icon;
    /**
     * 可选值列表[用逗号分隔]
     */
    private String valueSelect;
    /**
     * 属性类型[0-销售属性,1-基本属性,2-既是销售属性又是基本属性]
     */
    private Integer attrType;
    /**
     * 启用状态[0 - 禁用,1 - 启用]
     */
    private Long enable;
    /**
     * 所属分类
     */
    private Long catelogId;
    /**
     * 快速展示【是否展示在介绍上;0-否 1-是】,在sku中仍然可以调整
     */
    private Integer showDesc;

    private Long attrGroupId;

    /**
     * 			"catelogName": "手机/数码/手机", //所属分类名字
     * 			"groupName": "主体", //所属分组名字
     *
     */
    private String catelogName;
    private String groupName;

    private Long[] catelogPath;
}

package com.atguigu.gulimall.search.vo;


import lombok.Data;

import java.util.List;

/**
 * 封装页面所有可能传递过来的查询条件
 *
 *
 */
@Data
public class SearchParam {

    private String keyword; //页面传递过来的全文匹配关键字
    private Long catalog3Id; //三级分类id

    private String sort; //排序条件

    private Integer hasStock;//是否有货
    private String skuPrice;//价格区间查询
    private List<Long> brandId;//根据品牌进行查询,可以多选
    private List<String> attrs;//按照属性进行筛选
    private Integer pageNum = 1;//页码

    private String _queryString;//原生的所有查询条件
}

package com.atguigu.gulimall.search.vo;


import com.atguigu.common.to.es.SkuEsModel;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;

@Data
public class SearchResult {
    //查询到的所有商品信息
    private List<SkuEsModel> products;
    /**
     * 以下是分页信息
     */
    private Integer pageNum; //当前页码
    private Long total; //总记录数
    private Integer totalPages; //总页码
    private List<Integer> pageNavs;

    private List<BrandVo> brands; //当前查询到的结果,所有设计到的品牌
    private List<AttrVo> attrs; //所有涉及到的所有属性
    private List<CatalogVo> catalogs; //所有涉及到的所有分类

    //======================以上是返回给页面的所有信息=============================
    @Data
    public static class BrandVo{
        private Long brandId;
        private String brandName;
        private String brandImg;
    }

    @Data
    public static class AttrVo{
        private Long attrId;
        private String attrName;
        private List<String> attrValue;
    }

    @Data
    public static class CatalogVo{
        private Long catalogId;
        private String catalogName;
    }

    //面包屑导航数据
    private List<NavVo> navs = new ArrayList<>();
    private List<Long> attrIds = new ArrayList<>();

    @Data
    public static class NavVo{
        private String navName;
        private String navValue;
        private String link;
    }
}

6、主要问题

1、数据一致性

一定要坚持之前商品上传的数据是否正确,有缺失,我就因为之前SkuTitle拷贝字段时,名称写错了,导致丢失这一字段,在搜索功能中,keyword查询就不能成功

2、为什么当list.html查询所有数据时,我返回的DSL只能查询出部分数据:

GET gulimall_product/_search
查询时,我是有返回苹果的数据
在这里插入图片描述

在这里插入图片描述
但输入DSL:全局查询的list.html
也有八个数据,但为什么没有苹果这个品牌,只有华为的,导致后面返回结果就没有封装苹果,主页面就只有两个华为信息
在这里插入图片描述
求解答!!!!!!!呜呜呜呜呜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值