global.js 12.5 KB
/**
 * 商品促销 model
 * @author: yyq<yanqing.yang@yoho.cn>
 * @date: 2017/4/6
 */

'use strict';

const _ = require('lodash');
const cheerio = require('cheerio');

const helpers = global.yoho.helpers;

const homeService = require('./home-service');
const headerModel = require('../../../doraemon/models/header');
const listHandler = require('./list-handler');
const searchHandler = require('./search-handler');
const seoHandler = require('./seo-handler');

const productProcess = require(`${global.utils}/product-process`);
const handleFilterUrl = require(`${global.utils}/parameter`).fullParamToMinPath;

const GlobalApiModel = require('./global-api');
const GLOBAL_LIST_URI = '/list/global';

const _handelGlobalPathNav = (data, channel, checked, page) => {
    let rootName = '首页';

    if (channel && _.isString(channel)) {
        rootName = `${channel.toUpperCase()}首页`;
    }

    let pathNav = [{
        href: channel === 'boys' ? '/' : helpers.urlFormat(`/${channel}/`),
        name: rootName,
        pathTitle: rootName
    }, {
        href: helpers.urlFormat(GLOBAL_LIST_URI),
        name: '全球购',
        pathTitle: '全球购'
    }];

    if (data.sort) {
        pathNav.push({
            href: helpers.urlFormat(handleFilterUrl(GLOBAL_LIST_URI, data.sort.params)),
            name: data.sort.name,
            pathTitle: data.sort.name
        });
    }

    if (data.brand) {
        pathNav.push({
            href: helpers.urlFormat(handleFilterUrl(GLOBAL_LIST_URI, data.brand.params)),
            name: data.brand.name,
            pathTitle: data.brand.name
        });
        page = 'global-brand';
    }

    const kd = seoHandler.getSeoCheckedParamsName([], checked);
    const lastName = `${kd.channel || ''}${kd.color || ''}${kd.size || ''}${_.get(data, 'sort.name') || ''}`; // eslint-disable-line

    if (lastName) {
        pathNav.push({
            name: `${_.get(data, 'brand.name') || ''}${lastName}`
        });
    }

    _.last(pathNav).useH1 = true;

    return {
        pathNav: pathNav,
        listType: page
    };
};

const _checkSortEqual = (rp, params) => {
    let status = true;

    _.forEach(rp, (value, key) => {
        if (status && params[key] !== value) {
            status = false;
        }
    });

    return status;
};

const _handelGlobalSort = (origin, params, originParams) => {
    let all = [{
        name: '全部品类',
        href: handleFilterUrl(GLOBAL_LIST_URI, params, {}, {msort: true, misort: true, sort: true})
    }];
    let list = [];
    let selectSort = {};

    _.forEach(origin, value => {
        let equalCategory = _checkSortEqual(value.relation_parameter, originParams);
        let category = {
            categoryId: value.category_id,
            name: value.category_name,
            num: value.node_count,
            childList: [
                {
                    categoryId: value.category_id,
                    name: `全部${value.category_name}`,
                    num: value.node_count,
                    href: handleFilterUrl(GLOBAL_LIST_URI, params, value.relation_parameter),
                    childActive: _checkSortEqual(value.relation_parameter, originParams)
                }
            ]
        };

        if (equalCategory) {
            category.active = true;
            Object.assign(selectSort, {
                name: value.category_name,
                params: value.relation_parameter
            });
        }

        if (value.sub && value.sub.length === 1) {
            category.childList.length = 0;
        }

        _.forEach(value.sub, subValue => {
            let child = {
                categoryId: subValue.category_id,
                name: subValue.category_name,
                num: subValue.node_count,
                href: handleFilterUrl(GLOBAL_LIST_URI, params, subValue.relation_parameter),
                childActive: _checkSortEqual(subValue.relation_parameter, originParams)
            };

            category.childList.push(child);

            if (child.childActive) {
                category.active = true;
                Object.assign(selectSort, {
                    name: subValue.category_name,
                    params: subValue.relation_parameter
                });
            }
        });

        list.push(category);
    });

    return {
        allSort: {
            all: all,
            list: list
        },
        selectSort: selectSort
    };
};

const _getProductSeoData = (detail) => {
    let resData = {};

    if (!_.isEmpty(detail)) {
        let gn = detail.product_name,
            bn = _.get(detail, 'brand_info.brand_name') || detail.product_source;

        resData = {
            title: `【${bn}${gn} | YOHO!BUY 有货网`,
            keywords: `${bn}${bn}价格,${bn}图片${bn}`,
            description: `${gn} 有货网仅售${detail.final_price}元,购买正品${bn},了解${bn}商品信息就上有货网!` // eslint-disable-line
        };
    }

    return resData;
};

function getGlobalProductListData(params, yoho) {
    let limitNum = params.limit ? params.limit - 1 : 59;
    let dps = {};

    params.page = params.page || 1;

    if (params.brand) {
        dps.brand = params.brand;
    }

    return Promise.props({
        header: headerModel.requestHeaderData(yoho.channel),
        fullList: this.globalApi.getGlobalProductListAsync(Object.assign({
            physical_channel: yoho.channelNum,
            limit: 1
        }, dps)),
        list: this.globalApi.getGlobalProductListAsync(Object.assign({
            physical_channel: yoho.channelNum
        }, params, {limit: limitNum})),
        brand: dps.brand ? this.globalApi.getGlobalBrandInfoAsync(dps.brand) : {}
    }).then(result => {
        let resData = {};

        Object.assign(resData, result.header);

        if (result.list.code === 200) {
            let listData = _.get(result.list, 'data', {});
            let totalNum = _.get(listData, 'total', 0);

            // opts 显示新品、折扣
            listData.filter = listData.filter || {};
            Object.assign(listData.filter, {
                new: 'Y',
                specialoffer: 'Y'
            });

            resData.list = {
                leftContent: _handelGlobalSort(_.get(result.fullList, 'data.filter.group_sort', []), dps, params),
                filters: listHandler.handleFilterData(listData, params, GLOBAL_LIST_URI),
                opts: listHandler.handleOptsData(params, totalNum, listData.filter, GLOBAL_LIST_URI),
                totalCount: totalNum,
                footPager: listHandler.handlePagerData(_.get(listData, 'total', 0), params, false, GLOBAL_LIST_URI),
                goods: productProcess.processProductList(_.get(listData, 'product_list', []),
                    Object.assign({showDiscount: false, isGlobal: true}, params)),
                hasNextPage: searchHandler.handleNextPage(params, totalNum),
                latestWalk: 6 // 最近浏览记录
            };

            if (resData.list.filters && resData.list.filters.brand) {
                _.set(resData.list, 'filters.brand.showAllBrands', true); // 设置首次展示品牌筛选所有品牌
            }

            // pathNav brand
            let pathInfo = {};
            let fillCondition = _.get(resData, 'list.filters.checkedConditions.conditions');

            if (dps.brand) {
                let brandName = _.get(result.brand, 'data.brand_name', '');

                if (brandName) {
                    pathInfo.brand = {
                        name: brandName,
                        params: {brand: _.get(result.brand, 'data.brand_id', '')}
                    };

                    // 添加品信息for seo
                    fillCondition = _.concat([{
                        name: brandName,
                        itemType: 'brand'
                    }], fillCondition);
                }
            }

            // psthNav sort
            let selectedSort = _.get(resData.list, 'leftContent.selectSort', {});

            if (!_.isEmpty(selectedSort)) {
                pathInfo.sort = selectedSort;
            }

            Object.assign(resData.list, _handelGlobalPathNav(pathInfo, yoho.channel,
                _.get(resData, 'list.filters.checkedConditions.conditions'), 'global-list'));

            let seo = seoHandler.getGlobalListSeo(_.get(resData, 'list.leftContent.allSort.list'),
                fillCondition);

            Object.assign(resData, seo);
        }

        return resData;
    });
}

function getGlobalProductDetailData(skn, channelNum, channel) {
    return Promise.props({
        header: headerModel.requestHeaderData(channel),
        detail: this.globalApi.getGlobalProductDetailAsync(skn, channelNum),
        html: this.globalApi.getGlobalProductHtmlAsync(skn, channelNum)
    }).then(result => {
        let resData = {};
        let detailInfo, html = '';

        if (+result.detail.code === 200) {
            detailInfo = _.get(result, 'detail.data', {});

            let brandInfo = detailInfo.brand_info || {};

            resData.banner = {
                bgColor: '#000',
                homeUrl: helpers.urlFormat(GLOBAL_LIST_URI, {brand: brandInfo.brand_id}),
                brandName: brandInfo.brand_name,
                logo: brandInfo.brand_ico
            };

            detailInfo.productTitle = `${brandInfo.brand_name || detailInfo.product_source}|${detailInfo.product_name}`;

            resData.pathNav = _.concat(
                homeService.getHomeChannelNav(channel),
                [
                    {name: '全球购', href: helpers.urlFormat(GLOBAL_LIST_URI)},
                    {name: detailInfo.product_name || ''}
                ]
            );

            if (detailInfo.orign_price - detailInfo.final_price === 0) {
                _.unset(detailInfo, 'formart_orign_price');
            } else {
                detailInfo.promotion = ((detailInfo.final_price / detailInfo.orign_price) * 10).toFixed(1);

                // 只显示大于1折小于9折的折扣
                if (detailInfo.promotion <= 1.0 || detailInfo.promotion >= 9.0) {
                    detailInfo.promotion = false;
                }
            }

            if (detailInfo.market_price - detailInfo.sales_price === 0) {
                _.unset(detailInfo, 'format_market_price');
            }

            if (!_.isEmpty(detailInfo.goods_list)) {
                let colors = [];

                _.forEach(detailInfo.goods_list, (value, index) => {
                    let size = [];


                    _.forEach(value.size_list || [], subVal => {
                        size.push({
                            sku: subVal.product_sku,
                            name: subVal.size_name,
                            soldOut: subVal.storage_number * 1 <= 0
                        });
                    });


                    if (_.isEmpty(value.images_list)) {
                        value.images_list = [{
                            image_url: value.color_image
                        }];
                    }

                    if (index === 0 && !detailInfo.mainThumb) {
                        value.focus = true;
                        detailInfo.mainThumb = _.get(value, 'images_list[0].image_url', value.color_image);
                    }

                    colors.push({
                        src: value.color_image,
                        name: value.color_name,
                        title: value.color_name,
                        imgList: value.images_list,
                        focus: value.focus,
                        size: size
                    });
                });

                detailInfo.colors = colors;
                _.set(detailInfo, 'bundle.count', 1); // 设置默认数量为1
            }
        }

        if (result.html && !_.get(result.html, 'code', '')) {
            let $ = cheerio.load(result.html);

            $('script').remove();
            html = $('body').html();

            if (html) {
                html = html.replace(/http:/ig, '');
                html = html.replace(/\.jpg\"/ig, '.jpg?imageslim"');
                html = html.replace(/\.png\"/ig, '.png?imageslim"');
            }
        }

        Object.assign(resData, result.header, {
            goodsInfo: detailInfo,
            detailHtml: html || ''
        }, _getProductSeoData(detailInfo));

        return resData;
    });
}

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

        this.globalApi = new GlobalApiModel(ctx);

        this.getGlobalProductListData = getGlobalProductListData.bind(this);
        this.getGlobalProductDetailData = getGlobalProductDetailData.bind(this);
    }
};