cart-service.js 10.1 KB
/**
 * 商品详情models
 * @author: xuqi<qi.xu@yoho.cn>
 * @date: 2016/5/6
 */

'use strict';

const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;

const productAPI = require('./product-api');

const _getProductIntroAsync = (productSkn) => {
    return co(function * () {
        let result = yield Promise.props({
            sizeInfo: productAPI.sizeInfoAsync(productSkn)
        });

        return result;
    })();
};

/**
 * 获得sku商品数据
 */
const _getSkuDataByProductBaseInfo = (data) => {
    let totalStorageNum = 0;
    let skuGoods = null;// sku商品
    let defaultImage = '';// 默认图
    let chooseSkuFlag = false; // 选中状态

    if (_.isEmpty(_.get(data, 'goods_list', []))) {
        return {
            totalStorageNum,
            skuGoods,
            defaultImage
        };
    }

    skuGoods = _.get(data, 'goods_list', []).reduce((acc, cur, pos)=> {

        // 如果status为0,即skc下架时就跳过该商品$value['status'] === 0
        let goodsGroup = {};

        if (_.isEmpty(cur.color_image)) {
            return acc;
        }

        if (cur.images_list) {
            // 商品列表
            goodsGroup.productSkc = cur.product_skc;
            goodsGroup.src = helpers.image(cur.color_image, 40, 40);
            goodsGroup.title = `${_.trim(data.product_name)} ${cur.color_name}`;
            goodsGroup.name = cur.factory_goods_name;
            goodsGroup.focus = false;
            goodsGroup.total = 0;
            goodsGroup.thumbs = [];
            goodsGroup.size = [];
        }

        _.get(cur, 'images_list', []).forEach((good) => {
            if (good.image_url) {
                goodsGroup.thumbs.push({
                    url: '',
                    shower: helpers.image(good.image_url, 420, 560),
                    img: helpers.image(good.image_url, 75, 100)
                });
            }
        });

        // 缩略图空,不显示
        if (_.isEmpty(goodsGroup.thumbs)) {
            return acc;
        }

        // 默认第一张图片
        if (pos === 0) {
            defaultImage = helpers.image(cur.color_image, 420, 560);
        }

        // 商品的尺码列表
        _.get(cur, 'size_list', []).forEach((size) => {
            if (data.attribute === 3) {
                // 虚拟商品,门票默认最大为4,
                size.storage_number = size.storage_number > 4 ? 4 : size.storage_number;
            }

            // 如果status为0,即skc下架时就跳过该商品
            if (cur.status === 0) {
                size.storage_number = 0;
            }

            goodsGroup.size.push({
                name: size.size_name,
                sku: size.product_sku,
                num: _.parseInt(size.storage_number),
                goodsId: size.size_id
            });

            // 单个sku商品的总数
            goodsGroup.total += _.parseInt(size.storage_number);

            if (goodsGroup.total > 0 && !chooseSkuFlag) { // 默认选中该sku商品
                goodsGroup.focus = true;
                chooseSkuFlag = true;// 选中sku商品
            }

            totalStorageNum += _.parseInt(size.storage_number);

        });

        acc.push(goodsGroup);
        return acc;
    }, []);

    if (!_.isEmpty(skuGoods) && !chooseSkuFlag) { // 没有选中一个sku商品,默认选中第一个sku商品
        _.head(skuGoods).focus = true;
    }

    return {
        defaultImage: defaultImage,
        skuGoods: skuGoods,
        totalStorageNum: totalStorageNum
    };
};

/**
 * 使sizeBoList id以 sizeAttributeBos id顺序一样
 * @param sizeInfoBo
 */
const _sizeInfoBoSort = (sizeInfoBo) => {
    if (!sizeInfoBo.sizeBoList || !sizeInfoBo.sizeAttributeBos) {
        return {};
    }

    _.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
        let sortAttr = {};

        sizeBoList.sortAttributes.forEach(sortAttributes => {
            sortAttr[sortAttributes.id] = sortAttributes;
        });

        sizeInfoBo.sizeBoList[sizek].sortAttributes = sortAttr;
    });

    _.get(sizeInfoBo, 'sizeBoList', []).forEach((sizeBoList, sizek)=> {
        let sortAttr = [];

        sizeInfoBo.sizeAttributeBos.forEach(val => {
            if (sizeBoList.sortAttributes[val.id]) {
                sortAttr.push(sizeBoList.sortAttributes[val.id]);
            }
        });

        sizeInfoBo.sizeBoList[sizek].sortAttributes = sortAttr;

    });

    return sizeInfoBo;
};

/**
 * 获取尺寸信息
 * @param sizeInfo
 * @returns {{}}
 */
const _getSizeData = (sizeInfo) => {

    // 尺码信息
    if (!_.has(sizeInfo, 'sizeInfoBo')) {
        return {};
    }

    sizeInfo.sizeInfoBo = _sizeInfoBoSort(sizeInfo.sizeInfoBo);

    let boyReference = _.get(sizeInfo, 'productExtra.boyReference', false);
    let girlReference = _.get(sizeInfo, 'productExtra.girlReference', false);
    let gender = _.get(sizeInfo, 'productDescBo.gender', 3);
    let referenceName = (function() {
        if (gender === 3 && boyReference) {
            return '参考尺码(男)';
        } else if (gender === 3 && girlReference) {
            return '参考尺码(女)';
        } else {
            return '参考尺码';
        }
    }());

    // 判断是否显示参考尺码
    let showReference = (boyReference && _.get(sizeInfo, 'sizeInfoBo.sizeBoList[0].boyReferSize', false)) ||
        (girlReference && _.get(sizeInfo, 'sizeInfoBo.sizeBoList[0].girlReferSize', false));

    if (!_.has(sizeInfo, 'sizeInfoBo.sizeAttributeBos')) {
        return {};
    }

    // 尺码信息头部
    let size = {
        thead: [{name: '吊牌尺码', id: ''}],
        tbody: []
    };

    // 显示参考尺码
    if (showReference) {
        size.thead[1] = {name: referenceName, id: ''};
    }

    _.get(sizeInfo, 'sizeInfoBo.sizeAttributeBos', []).forEach((value) => {
        size.thead.push({
            name: value.attributeName || ' ',
            id: value.id
        });
    });

    _.get(sizeInfo, 'sizeInfoBo.sizeBoList', []).forEach((value) => {
        let sizes = [];

        // 吊牌尺码
        sizes.push(value.sizeName);

        // 判断是否显示参考尺码
        if (boyReference && (gender === 1 || gender === 3) && showReference) {
            sizes.push(_.get(value, 'boyReferSize.referenceName', ' '));
        } else if (girlReference && (gender === 2 || gender === 3) && showReference) {
            sizes.push(_.get(value, 'girlReferSize.referenceName', ' '));
        } else {
            if (size.thead[1] && showReference) {
                size.thead[1] = {};
            }
        }

        // 其他尺码信息
        _.get(value, 'sortAttributes', []).forEach(attr => {
            sizes.push(_.get(attr, 'sizeValue', ' '));
        });

        // 尺码信息
        size.tbody.push(sizes);
    });

    // 参考尺码为空
    if (_.isEmpty(size.thead[1]) && showReference) {
        // 移除这个值
        size.thead.splice(1, 1);
    }

    // 测量方式
    if (sizeInfo.sizeImage) {
        size.sizeImg = sizeInfo.sizeImage;
    }

    return size;
};

/**
 * 商品尺码信息
 *
 * @param productSkn
 * @param maxSortId
 * @return object
 */
const _getIntroInfo = (productSkn, additionalData)=> {
    if (!productSkn) {
        return {};
    }

    let sizeInfo = additionalData.sizeInfo;

    if (_.isEmpty(sizeInfo)) {
        return {};
    }

    let result = {};

    // 尺寸数据
    result.size = _getSizeData(sizeInfo);

    return result;
};

/**
 * 详情页数据格式化
 * @param origin Object 原始数据
 * @return result Object 格式化数据
 */
const _detailDataPkg = (origin) => {
    return co(function*() {
        if (_.isEmpty(origin) || _.isEmpty(origin)) {
            return {};
        }

        let result = {};

        let propOrigin = _.partial(_.get, origin);

        // 商品名称
        if (!propOrigin('product_name')) {
            return result;
        }

        result.name = propOrigin('product_name');
        result.skn = propOrigin('product_skn');
        result.productId = propOrigin('product_id');

        // 商品价格
        result.marketPrice = propOrigin('format_market_price');
        result.salePrice = propOrigin('format_sales_price');
        result.hasOtherPrice = true;

        if (result.salePrice === '0') {
            delete result.salePrice;
            result.hasOtherPrice = false;
        }

        // 上市期
        if (propOrigin('expect_arrival_time')) {
            result.arrivalDate = `${propOrigin('expect_arrival_time')}月`;
            result.presalePrice = propOrigin('format_sales_price');
            delete result.salePrice;
            result.hasOtherPrice = false;
        }

        // sku商品信息
        let skuData = _getSkuDataByProductBaseInfo(origin);

        // 商品购买状态
        let soldOut = !!(propOrigin('status') === 0 || skuData.totalStorageNum === 0);
        let virtualGoods = propOrigin('attribute') === 3; // 虚拟商品

        if (!soldOut && !virtualGoods) {
            result.addToCart = 1;
        }

        result.colors = skuData.skuGoods;

        return result;
    })();
};

/**
 *  获取某一个商品详情主页面
 */
const getProductInfoAsync = (pid) => {
    return co(function * () {
        if (!pid) {
            return {};
        }

        // 获取商品基本信息
        let productData = yield productAPI.getProductAsync(pid);

        if (_.isEmpty(productData.data)) {
            return Promise.reject({
                code: 404,
                message: 'app.product.data api wrong'
            });
        }

        let productSkn = _.get(productData, 'data.product_skn');

        let requestData = yield Promise.all([
            _getProductIntroAsync(productSkn),  // 商品详细介绍
            _detailDataPkg(productData.data)               // 商品详细价格
        ]);

        let productDescription = requestData[0];
        let productInfo = requestData[1];

        let intro = _getIntroInfo(productSkn, productDescription);

        return Object.assign(productInfo, intro);
    })();
};

module.exports = {
    getProductInfoAsync // 获取某一个商品详情主页面
};