chao 4 vuotta sitten
vanhempi
commit
f41a85c8d0

+ 30 - 0
src/main/java/com/caimei365/commodity/controller/SearchProductApi.java

@@ -29,6 +29,8 @@ public class SearchProductApi {
     /**
      * 根据关键词搜索商品
      *
+     * spi旧接口:/search/query/product
+     *
      * @param keyword 搜索关键字
      * @return JsonStr(list)
      */
@@ -49,4 +51,32 @@ public class SearchProductApi {
                                                       String sortField, Integer sortType) {
         return searchProductService.queryProductByKeyword(keyword, identity, pageNum, pageSize, sortField, sortType);
     }
+
+    /**
+     * 根据分类Id搜索商品
+     *
+     * spi旧接口:/search/query/product/type
+     *
+     * @param id     bigTypeID/smallTypeID/tinyTypeID
+     * @param idType id类型:1一级分类,2二级分类,3三级分类
+     */
+    @ApiOperation("根据分类Id搜索商品")
+    @ApiImplicitParams({
+        @ApiImplicitParam(required = false, name = "id", value = "bigTypeID/smallTypeID/tinyTypeID"),
+        @ApiImplicitParam(required = false, name = "idType", value = "id类型:1一级分类,2二级分类,3三级分类"),
+        @ApiImplicitParam(required = false, name = "identity", value = "用户身份: 0个人,1协销,2会员机构,3供应商,4普通机构"),
+        @ApiImplicitParam(required = false, name = "pageNum", value = "页码"),
+        @ApiImplicitParam(required = false, name = "pageSize", value = "每页数量"),
+        @ApiImplicitParam(required = false, name = "sortField", value = "排序字段:价格price,销量sales,人气favorite"),
+        @ApiImplicitParam(required = false, name = "sortType", value = "排序规则:1降序,其他升序")
+    })
+    @GetMapping("product/type")
+    public ResponseJson<String>  queryProductByType(Integer id, Integer idType,
+                                            @RequestParam(value = "identity", defaultValue = "0") Integer identity,
+                                            @RequestParam(value = "pageNum", defaultValue = "1") int pageNum,
+                                            @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
+                                            String sortField, Integer sortType) {
+        return searchProductService.queryProductByType(id, idType, identity, pageNum, pageSize, sortField, sortType);
+    }
+
 }

+ 11 - 12
src/main/java/com/caimei365/commodity/mapper/SearchMapper.java

@@ -134,22 +134,21 @@ public interface SearchMapper {
      * @param identity  用户身份
      * @param keyword   关键词
      * @param shopId    供应商id
-     *
-     * @param typeId    分类id
-     * @param idType    分类类型(1一级分类,2二级分类,3三级分类)
-     *
+     * @param bigTypeId 一级分类id
+     * @param smallTypeId 二级分类id
+     * @param tinyTypeId 三级分类id
      * @param sortField 排序类型
      * @param sortType  排序顺序
      * @return
      */
-    List<ProductListVo> queryProductFromDb(@Param("identity") Integer identity,
-                                           @Param("keyword") String keyword,
-                                           @Param("shopId") Integer shopId,
-                                           @Param("bigTypeId") Integer bigTypeId,
-                                           @Param("smallTypeId") Integer smallTypeId,
-                                           @Param("tinyTypeId") Integer tinyTypeId,
-                                           @Param("sortField") String sortField,
-                                           @Param("sortType") Integer sortType);
+    List<ProductListVo> queryProduct(@Param("identity") Integer identity,
+                                     @Param("keyword") String keyword,
+                                     @Param("shopId") Integer shopId,
+                                     @Param("bigTypeId") Integer bigTypeId,
+                                     @Param("smallTypeId") Integer smallTypeId,
+                                     @Param("tinyTypeId") Integer tinyTypeId,
+                                     @Param("sortField") String sortField,
+                                     @Param("sortType") Integer sortType);
 
 
 

+ 19 - 1
src/main/java/com/caimei365/commodity/service/SearchProductService.java

@@ -12,9 +12,27 @@ public interface SearchProductService {
     /**
      * 根据关键词搜索商品
      *
-     * @param keyword 关键字
+     * @param keyword   搜索关键字
+     * @param identity: 0个人,1协销,2会员机构,3供应商,4普通机构
+     * @param pageNum   页码
+     * @param pageSize  每页数量
+     * @param sortField 排序字段
+     * @param sortType  升降序0/1
      * @return JsonStr(list)
      */
     ResponseJson<String> queryProductByKeyword(String keyword, Integer identity, int pageNum, int pageSize, String sortField, Integer sortType);
 
+    /**
+     * 根据分类Id搜索商品
+     *
+     * @param id     bigTypeID/smallTypeID/tinyTypeID
+     * @param idType id类型:1一级分类,2二级分类,3三级分类
+     * @param identity: 0个人,1协销,2会员机构,3供应商,4普通机构
+     * @param pageNum   页码
+     * @param pageSize  每页数量
+     * @param sortField 排序字段
+     * @param sortType  升降序0/1
+     * @return JsonStr(list)
+     */
+    ResponseJson<String> queryProductByType(Integer id, Integer idType, Integer identity, int pageNum, int pageSize, String sortField, Integer sortType);
 }

+ 178 - 22
src/main/java/com/caimei365/commodity/service/impl/SearchProductServiceImpl.java

@@ -5,17 +5,16 @@ import com.aliyun.opensearch.sdk.dependencies.org.json.JSONException;
 import com.aliyun.opensearch.sdk.dependencies.org.json.JSONObject;
 import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
 import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
+import com.aliyun.opensearch.sdk.generated.search.DeepPaging;
 import com.aliyun.opensearch.sdk.generated.search.SearchParams;
 import com.caimei365.commodity.components.SearchOpenService;
 import com.caimei365.commodity.mapper.SearchMapper;
 import com.caimei365.commodity.model.ResponseJson;
-import com.caimei365.commodity.model.search.ProductDO;
 import com.caimei365.commodity.model.vo.PageVo;
 import com.caimei365.commodity.model.vo.ProductListVo;
 import com.caimei365.commodity.service.SearchProductService;
 import com.caimei365.commodity.utils.Json2PojoUtil;
 import com.caimei365.commodity.utils.PriceUtil;
-import com.github.pagehelper.Page;
 import com.github.pagehelper.PageHelper;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.StringUtils;
@@ -65,37 +64,59 @@ public class SearchProductServiceImpl implements SearchProductService {
             return result;
         } else {
             // 阿里云搜索失败,再次从数据库搜索
-            PageHelper.startPage(pageNum, pageSize);
-            List<ProductListVo> productList = searchMapper.queryProductFromDb(identity, keyword, null, null, null, null, sortField, sortType);
-            productList.forEach(product -> {
-                product.setPriceGrade(PriceUtil.getpriceGrade(product.getPrice()));
-                product.setPrice(0d);
-            });
-            PageVo<ProductListVo> pageData = new PageVo<>(productList);
-            int total = pageData.getTotalRecord();
-            JSONObject pageObj = new JSONObject();
-            pageObj.put("total", total);
-            pageObj.put("items", productList);
-            log.info(">>>>>>数据库容错查询("+queryStr+"): pageSize(" + pageNum +"),pageNum("+pageSize+"),total("+total+")");
-            if (productList.size()>0) {
-                return ResponseJson.success(pageObj.toString());
-            } else {
-                return ResponseJson.error("未查询到文档记录(数据库)", null);
-            }
+            return queryProductFromDatabase(pageNum, pageSize, identity, keyword, null, null, null, null, sortField, sortType);
+        }
+    }
+
+    /**
+     * 根据分类Id搜索商品
+     *
+     * @param id        bigTypeID/smallTypeID/tinyTypeID
+     * @param idType    id类型:1一级分类,2二级分类,3三级分类
+     * @param identity  : 0个人,1协销,2会员机构,3供应商,4普通机构
+     * @param pageNum   页码
+     * @param pageSize  每页数量
+     * @param sortField 排序字段
+     * @param sortType  升降序0/1
+     * @return JsonStr(list)
+     */
+    @Override
+    public ResponseJson<String> queryProductByType(Integer id, Integer idType, Integer identity, int pageNum, int pageSize, String sortField, Integer sortType) {
+        String queryStr = "";
+        if (idType == 1) {
+            queryStr = "p_bigtype:'" + id + "'";
+        } else if (idType == 2) {
+            queryStr = "p_smalltype:'" + id + "'";
+        } else if (idType == 3) {
+            queryStr = "p_tinytype:'" + id + "'";
+        }
+        int requestSize = pageNum*pageSize;
+        int requestPageSize = requestSize;
+        if (requestSize > SEARCH_MAX_NUM){
+            requestPageSize = (int) Math.floor(SEARCH_MAX_NUM/pageSize) * pageSize;
+        }
+        SearchParams searchParams = searchOpenService.getScrollProductParams(queryStr, identity, requestPageSize, sortField, sortType);
+        // 阿里云搜索(滚动查询)
+        ResponseJson<String> result = deepPagingForParams(searchParams, queryStr, pageNum, pageSize, requestSize, requestPageSize);
+        if (0 == result.getCode()) {
+            return result;
+        } else {
+            // 阿里云搜索失败,再次从数据库搜索
+            //return queryProductFromDatabase(pageNum, pageSize, identity, keyword, null, null, null, null, sortField, sortType);
+            return null;
         }
     }
 
     /**
-     * 查询商品
+     * 查询商品(阿里云搜索)
      *
      * @param queryStr  查询类型及参数
      * @param num       页码
      * @param size      每页数量
      * @param sortField 排序字段
      * @param sortType  升降序
-     * @return JsonStr(list)
      */
-    public ResponseJson<String> queryProduct(String queryStr, String filter, Integer identity, int num, int size, String sortField, Integer sortType) {
+    private ResponseJson<String> queryProduct(String queryStr, String filter, Integer identity, int num, int size, String sortField, Integer sortType) {
         SearchParams searchParams;
         int requestSize = num*size;
         if (requestSize > SEARCH_MAX_NUM){
@@ -156,4 +177,139 @@ public class SearchProductServiceImpl implements SearchProductService {
         }
     }
 
+    /**
+     * 获取数据库商品
+     *
+     * @param num       页码
+     * @param size      每页数量
+     * @param identity  用户身份
+     * @param keyword   关键词
+     * @param shopId    供应商id
+     * @param bigTypeId 一级分类id
+     * @param smallTypeId 二级分类id
+     * @param tinyTypeId 三级分类id
+     * @param sortField 排序类型
+     * @param sortType  排序顺序
+     */
+    private ResponseJson<String> queryProductFromDatabase(int num, int size, Integer identity, String keyword, Integer shopId,
+                             Integer bigTypeId, Integer smallTypeId, Integer tinyTypeId, String sortField, Integer sortType){
+        PageHelper.startPage(num, size);
+        List<ProductListVo> productList = searchMapper.queryProduct(identity, keyword, shopId, bigTypeId, smallTypeId, tinyTypeId, sortField, sortType);
+        productList.forEach(product -> {
+            product.setPriceGrade(PriceUtil.getpriceGrade(product.getPrice()));
+            product.setPrice(0d);
+        });
+        PageVo<ProductListVo> pageData = new PageVo<>(productList);
+        int total = pageData.getTotalRecord();
+        JSONObject pageObj = new JSONObject();
+        pageObj.put("total", total);
+        pageObj.put("items", productList);
+        log.info(">>>>>>数据库容错查询: pageSize(" + size +"),pageNum("+size+"),total("+total+")");
+        if (productList.size()>0) {
+            return ResponseJson.success(pageObj.toString());
+        } else {
+            return ResponseJson.error("未查询到文档记录(数据库)", null);
+        }
+    }
+
+    /**
+     * 滚动查询
+     *
+     * @param searchParams  查询参数对象
+     * @param queryStr 查询类型及参数串
+     * @param pageNum       页码
+     * @param pageSize      每页数量
+     * @param requestSize   请求总数量
+     * @param requestPageSize  每次scroll数量
+     * @return list
+     */
+    private ResponseJson<String> deepPagingForParams(SearchParams searchParams, String queryStr, int pageNum, int pageSize, int requestSize, int requestPageSize) {
+        //设置scroll方式查询
+        DeepPaging deep =new DeepPaging();
+        //不设置默认为1m表示1分钟,该参数表示本次返回的scrollid的有效期
+        deep.setScrollExpire("3m");
+        //添加DeepPaging对象参数
+        searchParams.setDeepPaging(deep);
+        // 查询推送
+        try {
+            String jsonStr = searchOpenService.pushQueryDocument(searchParams);
+            // 处理查询结果
+            JSONObject jsonObj = new JSONObject(jsonStr);
+            String status = jsonObj.getString("status");
+            String requestId = jsonObj.getString("request_id");
+            String tracer = jsonObj.getString("tracer");
+            JSONObject result = jsonObj.getJSONObject("result");
+            JSONArray errors = jsonObj.getJSONArray("errors");
+            log.info(">>>>>>query("+queryStr+"): " + status + ",request_id=" +requestId+ ",errors=" + errors.toString() + ",tracer="+tracer);
+            if ("OK".equals(status)) {
+                int total = result.getInt("total");
+                int totalPage = (int) Math.ceil( (double)total/pageSize);
+                JSONArray pageData = new JSONArray();
+                int loop = (int)Math.ceil((double) requestSize / requestPageSize);
+                for (int l=1; l<=loop; l++) {
+                    //第一次执行不返回数据,主要返回scroll_id值,第二次调用查询时设置scroll_id
+                    deep.setScrollId(result.getString("scroll_id"));
+                    //不设置默认为1m表示1分钟,如不想使用默认值,每次重新调用前必须要重新设置下
+                    deep.setScrollExpire("3m");
+                    jsonStr = searchOpenService.pushQueryDocument(searchParams);
+                    // 处理查询结果
+                    jsonObj = new JSONObject(jsonStr);
+                    status = jsonObj.getString("status");
+                    requestId = jsonObj.getString("request_id");
+                    tracer = jsonObj.getString("tracer");
+                    result = jsonObj.getJSONObject("result");
+                    errors = jsonObj.getJSONArray("errors");
+                    log.info(">>>>>>query("+queryStr+"): " + status + ",request_id=" +requestId+ ",errors=" + errors.toString() + ",tracer="+tracer);
+                    if ("OK".equals(status)) {
+                        JSONArray resultArr = result.getJSONArray("items");
+                        if (resultArr.length()>0){
+                            if (requestSize > SEARCH_MAX_NUM){
+                                if (l==loop) {
+                                    int baseSize = Math.min(requestSize - (requestPageSize*(loop-1)), resultArr.length());
+                                    // 上一页数量往前总数量 - 上一轮循环后总数量 = 当前循环的上一页之前数量
+                                    int baseNum = pageSize*(pageNum-1) - requestPageSize*(loop-1);
+                                    for (int i=0; i<pageSize; i++) {
+                                        int index = baseNum + i;
+                                        if (index<baseSize){
+                                            JSONObject item = resultArr.getJSONObject(index);
+                                            pageData.put(i, item);
+                                        } else {
+                                            break;
+                                        }
+                                    }
+                                }
+                            } else {
+                                int baseNum = (pageNum-1)*pageSize;
+                                int currentTotal = requestSize;
+                                if (totalPage == pageNum){
+                                    currentTotal = total;
+                                }
+                                for (int i=0; i<pageSize; i++) {
+                                    int index = baseNum + i;
+                                    if (index<currentTotal){
+                                        JSONObject item = resultArr.getJSONObject(index);
+                                        pageData.put(i, item);
+                                    } else {
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+                JSONObject pageObj = new JSONObject();
+                pageObj.put("total", total);
+                pageObj.put("items", pageData);
+                log.info(">>>>>>pageResult("+queryStr+"): pageSize(" + pageSize +"),pageNum("+pageNum+"),total("+total+")");
+                return ResponseJson.success(pageObj.toString());
+            } else {
+                return ResponseJson.error("未查询到文档记录", null);
+            }
+        } catch (OpenSearchClientException | OpenSearchException | JSONException e) {
+            log.error("查询文档异常:" + e.getMessage());
+            return ResponseJson.error("查询文档异常:" + e.getMessage(), null);
+        }
+    }
+
+
 }

+ 4 - 4
src/main/resources/mapper/SearchMapper.xml

@@ -261,7 +261,7 @@
     </select>
 
     <!-- 搜索容错 商品列表 -->
-    <select id="queryProductFromDb" resultType="com.caimei365.commodity.model.vo.ProductListVo">
+    <select id="queryProduct" resultType="com.caimei365.commodity.model.vo.ProductListVo">
         select
             p.productID as productId,
             p.`name` as name,
@@ -309,13 +309,13 @@
         <choose>
             <when test="sortField != null and sortField != ''">
                 <choose>
-                    <when test="sortField == 'p_price'">
+                    <when test="sortField == 'price'">
                         order by p.price1
                     </when>
-                    <when test="sortField == 'p_sales'">
+                    <when test="sortField == 'sales'">
                         order by p.sellNumber
                     </when>
-                    <when test="sortField == 'p_favorite'">
+                    <when test="sortField == 'favorite'">
                         order by p.favoriteTimes
                     </when>
                     <otherwise>