seo-service.js 5.99 KB


const redis = global.yoho.redis;
const helpers = global.yoho.helpers;
const logger = global.yoho.logger;

const _ = require('lodash');
const HeaderModel = require('../../../doraemon/models/header');

const SearchApi = require('./search-api');
const searchHandler = require('./search-handler');
const seoHandler = require('./seo-handler');
const utils = '../../../utils';
const productProcess = require(`${utils}/product-process-simple`);

const _handleImageUrl = (url) => {
    if (url) {
        let imgArr = _.split(url, '?', 1);

        imgArr.push('imageView2/1/w/{width}/h/{height}/q/90');
        url = imgArr.join('?');
    }

    return url;
};

const _setHotKeywordData = (result, params, channel) => {
    let changeQuery = Object.assign({}, params);
    let finalResult = {
        headerData: Object.assign(result[0].headerData, {
            header: true
        })
    };

    _.unset(changeQuery, 'query');

    // 获取商品数据和顶部筛选条件
    if (result[1].code === 200) {
        let data = result[1].data;
        let goodsList = productProcess.processProductList(data.product_list,
            Object.assign({showDiscount: false, from: {type: 'hot', params: params}}, params));

        goodsList.map(goods => {
            goods.productTitle = `${params.query}|${goods.product_name}`;
            return goods;
        });

        Object.assign(finalResult,
            searchHandler.handlePathNavData({total: data.total}, params, 'search', channel),
            {
                product: {
                    opts: searchHandler.handleOptsData(changeQuery, data.total),
                    totalCount: data.total,
                    footPager: searchHandler.handlePagerData(data.total, changeQuery),
                    goods: goodsList,
                    hasNextPage: searchHandler.handleNextPage(changeQuery, data.total)
                }
            }
        );

        finalResult.hotBrands = _.get(data, 'filter.brand', []);

        finalResult.hotBrands.forEach((val) => {
            val.href = helpers.urlFormat(`/list/bd${val.id}.html`);

            return val;
        });

        finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))};
    }


    if (result[2].code === 200) {
        let data = result[2].data;

        finalResult.latestWalkExtra = [{
            extraTabName: '相关推荐',
            active: true,
            extraGoodsList: productProcess.processProductList(data.product_list,
                Object.assign({showDiscount: false, from: {type: 'hot', params: params}}, params))
        }, {
            extraTabName: '最近预览',
            latestWalk: 5
        }];
    }

    return finalResult;
};

module.exports = class extends global.yoho.BaseModel {
    constructor(ctx) {
        super(ctx);

        this.searchApi = new SearchApi(ctx);
    }

    getSearchProduct(params, channel, sort) {
        let searchParams = searchHandler.getSearchParams(params);

        switch (channel) {
            case 'boys':
                searchParams.physical_channel = 1;
                break;
            case 'girls':
                searchParams.physical_channel = 2;
                break;
            case 'kids':
                searchParams.physical_channel = 3;
                break;
            case 'lifestyle':
                searchParams.physical_channel = 4;
                break;
            default:
                break;
        }

        searchParams.need_filter = 'yes';

        let headerModelCtx = new HeaderModel(this.ctx);

        return Promise.all([
            headerModelCtx.requestHeaderData(channel, true),
            this.searchApi.getSeoProductList(searchParams, 'fuzzySearch'),
            this.searchApi.getSeoProductList(Object.assign({}, searchParams, {
                order: 's_n_desc',
                limit: 5
            }), 'fuzzySearch'),
        ]).then(result => {
            if (!sort || _.get(result[1], 'data.total') > 0) {
                return result;
            }

            delete searchParams.query;
            searchParams.sort = sort;

            return this.searchApi.getSeoProductList(searchParams,
                'fuzzySearch').then(subRes => {
                result[1] = subRes;

                return result;
            });
        }).then(result => {
            return _setHotKeywordData(result, params, channel);
        });
    }

    getHotKeywordData(id, params, channel) {
        return redis.all([
            ['get', `global:yoho:seo:hot:keywords:id:${id}`]
        ]).then(redisData => {
            let keyword = redisData[0];

            try {
                keyword = JSON.parse(keyword);
            } catch (e) {
                logger.debug('getProductList cache data parse fail.');
            }

            if (!_.get(keyword, 'name')) {
                logger.error(`cannot find hot keywords by id(${id})`);
                return false;
            }

            params.query = keyword.name;

            return this.getSearchProduct(params, channel, keyword.sort_id).then(result => {
                const keyNum = 10;
                let hotKeys = (keyword.data || []).map(val => {
                    val.href = helpers.urlFormat(`/hot/${val.id}.html`);
                    return val;
                });
                let seoTDK = seoHandler.getHotKeywordsSeo(keyword.name, _.get(result, 'product.totalCount', '多'));

                if (keyword.goods_img) {
                    keyword.goods_img = _handleImageUrl(keyword.goods_img);
                } else {
                    let goods = _.last(_.get(result, 'product.goods', []));

                    keyword.goods_img = _handleImageUrl(_.get(goods, 'thumb', ''));
                }
                keyword.list = _.take(hotKeys, keyNum);
                keyword.describe = keyword.describe || seoTDK.description;

                Object.assign(result, {
                    hotKeys: _.drop(hotKeys, keyNum),
                    keyword: keyword
                }, seoTDK);

                return result;
            });
        });
    }
};