RecallResultController.java 11.5 KB
package com.yoho.search.restapi.tools;

import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.*;
import com.yoho.search.common.SearchCommonService;
import com.yoho.search.common.SearchRequestParams;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.common.utils.SearchKeyWordUtils;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.recall.beans.requests.UserRecallRequestBuilder;
import com.yoho.search.service.base.SknReturnInfoBaseService;
import com.yoho.search.service.recall.UserRecallRequestResponseService;
import com.yoho.search.service.recall.strategy.StrategyEnum;
import com.yoho.search.models.recall.RecallSknInfo;
import com.yoho.search.models.recall.UserRecallRequest;
import com.yoho.search.models.recall.UserRecallResponse;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping(value = "/tools")
public class RecallResultController {

    private static final Logger LOGGER = LoggerFactory.getLogger(RecallResultController.class.getSimpleName());

    @Autowired
    private UserRecallRequestBuilder userRecallRequestBuilder;
    @Autowired
    private UserRecallRequestResponseService userRecallRequestResponseService;
    @Autowired
    private SknReturnInfoBaseService sknReturnInfoBaseService;
    @Autowired
    private SearchCommonService searchCommonService;

    private List<String> supportPageIdList = Arrays.asList(SearchPageIdDefine.PAGE_ID_SORT, SearchPageIdDefine.PAGE_ID_NEW, SearchPageIdDefine.PAGE_ID_ZQ, SearchPageIdDefine.PAGE_ID_POOL);

    @RequestMapping(method = RequestMethod.GET, value = "/getRecallResult")
    public SearchApiResult userVectorSortBrand(HttpServletRequest request) {
        Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
        if (paramMap.get("pageId") == null || !supportPageIdList.contains(paramMap.get("pageId"))) {
            return new SearchApiResult().setCode(400).setMessage("不支持的pageId");
        }
        switch (paramMap.get("pageId")) {
            case SearchPageIdDefine.PAGE_ID_SORT:
                if (!checkSortParam(paramMap)) {
                    return new SearchApiResult().setCode(400).setMessage("缺少品类参数");
                }
                addSortParams(paramMap);
                break;
            case SearchPageIdDefine.PAGE_ID_NEW:
                addNewParams(paramMap);
                break;
            case SearchPageIdDefine.PAGE_ID_ZQ:
                if (!checkZqParam(paramMap)) {
                    return new SearchApiResult().setCode(400).setMessage("缺少专区ID");
                }
                addDefaultParamsToParamMap(paramMap);
                break;
            case SearchPageIdDefine.PAGE_ID_POOL:
                if (!checkPoolParam(paramMap)) {
                    return new SearchApiResult().setCode(400).setMessage("缺少商品池ID");
                }
                addDefaultParamsToParamMap(paramMap);
                break;
        }
        return recallProductList(paramMap);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/querySknInfo")
    public SearchApiResult querySknInfo(HttpServletRequest request) {
        Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
        if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN))) {
            return new SearchApiResult().setCode(400).setMessage("缺少skn");
        }
        SearchParam searchParam = new SearchParam();
        BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
        boolFilter.filter(QueryBuilders.termQuery(ProductIndexEsField.productSkn, paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN)));
        searchParam.setFiter(boolFilter);
        searchParam.setSize(1);
        searchParam.setQuery(QueryBuilders.matchAllQuery());
        SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
        if (searchResult != null && searchResult.getResultList() != null && !searchResult.getResultList().isEmpty()) {
            return new SearchApiResult().setData(searchResult.getResultList().get(0));
        }
        return new SearchApiResult().setData(null);
    }

    @RequestMapping(method = RequestMethod.GET, value = "/getSknFlow")
    public SearchApiResult getSknFlow(HttpServletRequest request) {
        Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
        if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN))) {
            return new SearchApiResult().setCode(400).setMessage("缺少skn");
        }
        SearchParam searchParam = new SearchParam();
        BoolQueryBuilder boolFilter = QueryBuilders.boolQuery();
        boolFilter.filter(QueryBuilders.termQuery(ProductIndexEsField.productSkn, paramMap.get(SearchRequestParams.PARAM_SEARCH_PRODUCT_SKN)));
        searchParam.setFiter(boolFilter);
        searchParam.setSize(100);
        searchParam.setQuery(QueryBuilders.matchAllQuery());
        SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_SKN_FLOW, searchParam);
        if (searchResult != null && searchResult.getResultList() != null && !searchResult.getResultList().isEmpty()) {
            return new SearchApiResult().setData(searchResult.getResultList());
        }
        return new SearchApiResult().setData(null);
    }

    private boolean checkSortParam(Map<String, String> paramMap) {
        if (StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_MAXSORT))) {
            return true;
        }
        if (StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_MIDDLESORT))) {
            return true;
        }
        if (StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_SMALLSORT))) {
            return true;
        }
        if (StringUtils.isNotBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_COMMONSORT))) {
            return true;
        }
        return false;
    }

    private void addSortParams(Map<String, String> paramMap) {
        addDefaultParamsToParamMap(paramMap);
        paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_GLOBAL, "Y");// 包含全球购
        paramMap.put(SearchRequestParams.PARAM_SEARCH_CONTAIN_UFO, "Y");// 包含全球购
    }

    private void addNewParams(Map<String, String> paramMap) {
        addDefaultParamsToParamMap(paramMap);
        // 默认30天内假上新
        long end = DateUtil.getLastTimeSecond(new Date());
        long begin = DateUtil.getFirstTimeSecond(DateUtil.addDay(new Date(), -30));
        paramMap.put(SearchRequestParams.PARAM_SEARCH_SHELVETIME, begin + "," + end);
    }

    private boolean checkZqParam(Map<String, String> paramMap) {
        if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_ISPROMOTION))) {
            return false;
        }
        return true;
    }

    private boolean checkPoolParam(Map<String, String> paramMap) {
        if (StringUtils.isBlank(paramMap.get(SearchRequestParams.PARAM_SEARCH_FILTER_POOLID))) {
            return false;
        }
        return true;
    }

    private void addDefaultParamsToParamMap(Map<String, String> paramMap) {
        paramMap.put(SearchRequestParams.PARAM_SEARCH_PAGEID, paramMap.get("pageId"));// 根据场景划分的页面id
        paramMap.put(SearchRequestParams.PARAM_SEARCH_GLOBAL_FILTER_BRAND, "Y");// 页面屏蔽
        paramMap.put(SearchRequestParams.PARAM_SEARCH_STATUS, "1");// 上架
        paramMap.put(SearchRequestParams.PARAM_SEARCH_STOCKNUM, "1");// 有库存
        paramMap.put(SearchRequestParams.PARAM_SEARCH_SHOWSOLDOUT, "1");// 显示延期显示的商品
        paramMap.put(SearchRequestParams.PARAM_SEARCH_ISOUTLETS, "2");// 非奥莱
        paramMap.put(SearchRequestParams.PARAM_SEARCH_ATTRIBUTE_NOT, "2");// 非赠品
        paramMap.put(SearchRequestParams.PARAM_SEARCH_NEEDSMALLSORT, "1");// 品类聚合时带上小分类
        paramMap.put(SearchRequestParams.PARAM_SEARCH_AGG_WITH_PARAM_BRAND, "Y");// 聚合时使用参数中自带的参数
        // 关键词反转码
        String keyword = SearchKeyWordUtils.getParamKeyword(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY);// 转码
        if (!StringUtils.isBlank(keyword)) {
            paramMap.put(SearchRequestParams.PARAM_SEARCH_QUERY, keyword);
            paramMap.put("is_encode", "0");
        }
    }

    private SearchApiResult recallProductList(Map<String, String> paramMap) {
        try {
            UserRecallRequest userRecallRequest = userRecallRequestBuilder.buildUserRecallRequest(paramMap, 300);
            UserRecallResponse userRecallResponse = userRecallRequestResponseService.queryRecallResult(userRecallRequest, false);
            List<RecallSknInfo> recallSknInfos = userRecallResponse.getSknList();
            List<Integer> productSknList = recallSknInfos.stream().map(RecallSknInfo::getProductSkn).collect(Collectors.toList());
            List<Map<String, Object>> productInfoList = sknReturnInfoBaseService.queryProductListBySkn(productSknList, productSknList.size());
            Map<Integer, RecallSknInfo> sknRecallTypeMap = SearchCollectionUtils.toMap(recallSknInfos, (Transfer<RecallSknInfo, Integer>) (recallSknInfo) -> {
                return recallSknInfo.getProductSkn();
            });


            List<Map<String, Object>> briefProductInfoList = new ArrayList<>();
            for (Map<String, Object> productInfo : productInfoList) {
                Map<String, Object> briefProductInfo = new HashMap<>();
                briefProductInfo.put("product_skn", productInfo.get("product_skn"));
                briefProductInfo.put("brand_name", productInfo.get("brand_name"));
                briefProductInfo.put("small_sort_name", productInfo.get("small_sort_name"));
                briefProductInfo.put("middle_sort_name", productInfo.get("middle_sort_name"));
                briefProductInfo.put("product_name", productInfo.get("product_name"));
                int productSkn = MapUtils.getIntValue(productInfo, "product_skn", 0);
                RecallSknInfo recallSknInfo = sknRecallTypeMap.get(productSkn);
                if (recallSknInfo == null || recallSknInfo.getRecallType() == null) {
                    briefProductInfo.put("recall_type", StrategyEnum.DEFAULT_HEAT_VALUE.name());
                } else {
                    briefProductInfo.put("recall_type", recallSknInfo.getRecallType());
                }
                briefProductInfoList.add(briefProductInfo);
            }
            //4、构造返回结果
            JSONObject dataMap = new JSONObject();
            dataMap.put("product_list", briefProductInfoList);
            return new SearchApiResult().setData(dataMap);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return new SearchApiResult().setData(null).setCode(500).setMessage("Exception");
        }
    }

}