/** * 逛处理类 */ 'use strict'; const _ = require('lodash'); const helpers = global.yoho.helpers; const productPrcs = require('./product-process'); const mipUtils = require('../apps/mip/mip-utils'); /** * 将商品转化成以 product_skn 为键名的对象 * @param {*} goodsArray */ const _goodsArrayToObj = (goodsArray) => { return _.keyBy(goodsArray, value => { return value.product_skn; }); }; /** * [将首字符为//的url转换为http://] * @param {[string]} url [需要转换的url] * @return {[string]} [description] */ const transHttpsUrl = (url) => { return url.replace(/^\/\//g, 'http://'); }; /** * [过滤app查询字符串] * @param {[string]} url [url地址] * @return {[strng]} */ const getFilterUrl = (url) => { url = url && url.replace('.m.yohobuy.com', global.yoho.config.subDomains.host) .replace('www.yohobuy.com', global.yoho.config.siteUrl); const whiteDomains = ['m.yohobuy.com', 'cdn.yoho.cn/myohobuy']; const blackDomains = ['sale.m.yohobuy.com', 'cuxiao.m.yohobuy.com', 'activity.m.yohobuy.com', 'huodong.m.yohobuy.com', '/home/orders/pay']; if (whiteDomains.every(item => url && url.includes(item)) && blackDomains.every(item => !url.includes(item))) { url = url.replace('http://', '//'); } if (url && url.includes('feature.yoho.cn')) { url = transHttpsUrl(url); } if (url && url.includes('openby:yohobuy=')) { let filters = ['openby:yohobuy=', '&', '?']; filters.forEach(item => { url = url.subString(0, url.lastIndexOf(item)); }); return url.replace(/(^\s*)|(\s*$)/g, ''); } else { return url; } }; /** * [格式化资讯文章] * @param {[array]} articleData [需要格式化的资讯数据]] * @param {[Boolean]} showTag [是否显示左上角标签]] * @param {Boolean} isApp [是否显示分享,在APP客户端里嵌入需要传url链接] * @param {[Boolean]} showAuthor [控制是否显示作者信息] * @param {[int]} uid [当前登录的用户ID] * @param {[int]} top [是否是列表置顶文章] * @return {[array | false]} */ const formatArticle = (articleData, showTag, isApp, showAuthor, uid, top) => { // 资讯ID不存在,则不显示 if (!articleData.id) { return false; } let result = { id: articleData.id, showTags: showTag, img: articleData.src ? helpers.image(articleData.src, 640, 640) : '', title: articleData.title, text: articleData.intro, publishTime: articleData.publish_time, publishTimeLong: articleData.publish_time_long, pageView: articleData.views_num }; if (isApp) { if (articleData.url.indexOf('guang.m.yohobuy.com') < 0) { result.url = `${helpers.https(articleData.url)}?openby:yohobuy={"url":"${articleData.url}","islogin":"N"}}`; } else { result.url = `//m.yohobuy.com/guang/${articleData.id}.html?openby:yohobuy={"action":"go.h5","params":{"param":{"id":"${articleData.id}"},"shareparam":{"id":"${articleData.id}"},"share":"/guang/api/v1/share/guang","id":${articleData.id},"type":1,"url":"http://m.yohobuy.com/guang/${articleData.id}.html","islogin":"N"}}`; } } else { if (articleData.url.indexOf('guang.m.yohobuy.com') < 0) { result.url = articleData.url; } else { result.url = `//m.yohobuy.com/guang/${articleData.id}.html`; } } if (result.url.includes('feature.yoho.cn') || result.url.includes('cdn.yoho.cn')) { result.url = transHttpsUrl(result.url); } // 收藏 if (isApp) { result.collect = {}; result.collect.isCollected = articleData.isFavor === true; let colparam = articleData.colparam || { urlpath: '', param: '' }; let originUrl = helpers.urlFormat(colparam.urlpath || '/author/index', null, 'guang'); // 跳转回的链接 // 根据用户是否登录做处理的链接 let collectUrl = 'javascript:;'; // eslint-disable-line if (!uid) { let playUrlEncode = `${originUrl}${colparam.param}`.replace(/\//g, '\\\/'); collectUrl = `${originUrl}?openby:yohobuy={"action":"go.weblogin","params":{"jumpurl":{"url":"${playUrlEncode}","param":{"from":"app"}},"requesturl":{"url":"","param":{}},"priority":"N"}}`; //eslint-disable-line } result.collect.url = collectUrl; } else { // 点赞 result.like = {}; result.like.count = articleData.praise_num; result.like.isLiked = articleData.isPraise === 'Y'; } if (isApp && articleData.share.url) { // 分享链接 result.share = `${articleData.share.url}?openby:yohobuy={"action":"go.share","params":{"title":"${articleData.title}","content":"${articleData.intro}","url":"${articleData.share.url}","pic":"https:${result.img}"}}`; //eslint-disable-line } // 判断是否显示作者信息 if (showAuthor && articleData.author) { if (!isApp) { articleData.author.url = getFilterUrl(articleData.author.url); } else { // 编辑人员 app跳转url处理 20160601 let isLogin = uid ? true : false; articleData.author.url = `${helpers.https(articleData.author.url)}&openby:yohobuy={"action":"go.h5","params":{"param":{},"share":"","id":${articleData.author.author_id},"type":0,"islogin":"${isLogin}","url":"${articleData.author.url}"}}`; //eslint-disable-line } result.author = articleData.author; if (result.author.avatar) { let avatarUrl = result.author.avatar.replace('http://', '//'); avatarUrl = avatarUrl.split('?')[0]; result.author.avatar = avatarUrl; result.author.minCategory = articleData.min_category_name; } } // 模板中需要的标签标识 if (showTag && articleData.category_id) { switch (articleData.category_id) { case '1': // 话题 result.isTopic = true; break; case '2': // 搭配 result.isCollocation = true; break; case '3': // 潮人 result.isFashionMan = true; break; case '4': // 潮品 result.isFashionGood = true; break; case '5': // 小贴士 result.isTip = true; break; case '19': // 专题 result.isSpecialTopic = true; break; case '22': // 视频 result.isVideo = true; break; case '24': // Show case '9999': // Show result.isShow = true; break; default: break; } } // 170503 新添加商品列表模块 if (articleData && articleData.product_list) { result.productList = []; _.forEach(articleData.product_list, value => { result.productList.push(_.assign(value, { price: parseFloat(value.sales_price).toFixed(2), href: `//m.yohobuy.com/product/${value.product_skn}.html`, only: articleData.product_list.length === 1 })); }); } // 170609 置顶 if (top) { result.top = true; } return result; }; /** * [获取商品的ICON] * @param {[int]} type [类型] * @return {[type]} */ const getProductIcon = (type) => { const icons = { 1: 'cloth', 3: 'pants', 4: 'dress', 6: 'shoe', 7: 'bag', 10: 'lamp', 241: 'headset', 8: 'watch', 360: 'swim-suit', 308: 'under' }; return icons[type] || ''; }; /** * 逛详情页数据处理 */ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isWeibo, isMip) => { let finalDetail = []; let allgoods = ''; let localStyle = []; _.forEach(articleContent, (value, index) => { // 文字 if (_.get(value, 'text.data.text', false)) { let newText = ''; if (isMip) { let mipHtml = mipUtils.process(value.text.data.text, {prefix: index}); newText = mipHtml.mipHtml; localStyle.push(mipHtml.css); } else { newText = value.text.data.text; } finalDetail.push({ text: newText.replace(/www.yohobuy.com\/chanpin\//ig, 'm.yohobuy.com/chanpin/') }); } // 一张图片 if (_.get(value, 'singleImage.data.length', false)) { let tagList = _.get(value, 'singleImage.data[0].tagList', []); let tagListGlobal = _.get(value, 'singleImage.data[0].tagListGlobal', []); let tagListLimit = _.get(value, 'singleImage.data[0].tagListLimit', []); // 普通商品 if (tagList.length > 0) { _.forEach(tagList, (tag, tagIndex) => { tagList[tagIndex].href = '//m.yohobuy.com/product/' + tag.product_skn + '.html'; tagList[tagIndex].isApp = isApp; }); } // 全球购商品 if (tagListGlobal.length > 0) { _.forEach(tagListGlobal, tagGlobal => { tagList.push(Object.assign(tagGlobal, { href: '//m.yohobuy.com/product/global/' + tagGlobal.product_skn + '.html', isApp: isApp, noCart: true })); }); } // 限定商品 if (tagListLimit.length > 0) { _.forEach(tagListLimit, tagLimit => { tagList.push(Object.assign(tagLimit, { href: '//m.yohobuy.com/product/' + tagLimit.product_skn + '.html', isApp: isApp, noCart: true })); }); } finalDetail.push({ bigImage: helpers.image(_.get(value, 'singleImage.data[0].src', ''), 640, 640), noLazy: index <= 3, tagList: tagList, isGif: /\.gif/i.test(_.get(value, 'singleImage.data[0].src', '')), width: 320, height: _.get(value, 'singleImage.data[0].height', 0) / _.get(value, 'singleImage.data[0].width', 1) * 320 // eslint-disable-line }); } // 两张小图 if (_.get(value, 'smallPic.data.length', 0) > 1) { finalDetail.push({ smallImage: [ { src: helpers.image(_.get(value, 'smallPic.data[0].src', ''), 315, 420), isGif: /\.gif/i.test(_.get(value, 'smallPic.data[0].src', '')), }, { src: helpers.image(_.get(value, 'smallPic.data[1].src', ''), 315, 420), isGif: /\.gif/i.test(_.get(value, 'smallPic.data[0].src', '')), } ] }); } // 微信公众号? if (_.get(value, 'weixinPublic', false)) { finalDetail.push({ weixinPublic: _.get(value, 'weixinPublic', '') }); } // 分享? if (_.get(value, 'shareCode', false)) { let shareCode = false; if (isWeixin) { shareCode = _.get(value, 'shareCode.wechatShareImgUrl', false); } if (isqq) { shareCode = _.get(value, 'shareCode.qqShareImgUrl', false); } if (isWeibo) { shareCode = _.get(value, 'shareCode.showShareImgUrl', false); } if (shareCode) { finalDetail.push({ shareCode: [{ codeShare: shareCode }] }); } } // 改变关联商品显示形式,false:默认单列多行,true:改成俩列多行 let changeDisplayType = _.get(value, 'goods.display_template') === '2'; // 相关商品 if (_.get(value, 'goods.data', false) || _.get(value, 'goods.dataGlobal', false) || _.get(value, 'goods.dataLimit', false)) { let goodsData = _.get(value, 'goods.data', []); let goodsDataGlobal = _.get(value, 'goods.dataGlobal', []); let goodsDataLimit = _.get(value, 'goods.dataLimit', []); // 普通商品 _.forEach(goodsData, item => { allgoods += item.id + ','; }); // 全球购商品 _.forEach(goodsDataGlobal, item => { allgoods += item.id + ','; goodsData.push(item); }); // 限定商品 _.forEach(goodsDataLimit, item => { allgoods += item.id + ','; goodsData.push(item); }); finalDetail.push({ relatedReco: { isApp: isApp, goods: goodsData, changeDisplayType: changeDisplayType } }); } // 悬停浮动商品 170505 后面版本不支持配置此资源,重构可忽略此部分 if (_.get(value, 'goodsGroup.data', false)) { let collocation = []; _.forEach(_.get(value, 'goodsGroup.data', []), item => { let cover = _.get(item, 'cover', ''); _.forEach(_.get(item, 'list', []), item2 => { let goodId = _.get(item2, 'id'); if (goodId) { allgoods += goodId + ','; } }); collocation.push({ thumb: cover ? helpers.image(cover.cover, 235, 314) : '', type: cover ? getProductIcon(cover.maxSortId) : '', goods: _.get(item, 'list', []) }); }); finalDetail.push({ collocation: collocation }); } // 更多商品链接 if (_.get(value, 'link', false)) { finalDetail.push({ moreLink: _.get(value, 'link.data[0].url', '') }); } // 推荐商品 if (_.get(value, 'recommend_products', false)) { let recommendProducts = _.get(value, 'recommend_products.data', []); let recommendProductsGlobal = _.get(value, 'recommend_products.dataGlobal', []); let recommendProductsLimit = _.get(value, 'recommend_products.dataLimit', []); // 普通商品 _.forEach(recommendProducts, (goods, goodsKey) => { recommendProducts[goodsKey].price = parseFloat(goods.sales_price).toFixed(2); recommendProducts[goodsKey].href = isApp ? `http://m.yohobuy.com/product/${goods.product_skn}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${goods.product_skn}"}}` : `//m.yohobuy.com/product/${goods.product_skn}.html`; }); // 全球购商品 _.forEach(recommendProductsGlobal, goodsGlobal => { recommendProducts.push(Object.assign(goodsGlobal, { price: parseFloat(goodsGlobal.sales_price).toFixed(2), href: isApp ? `http://m.yohobuy.com/product/${goodsGlobal.product_skn}.html?openby:yohobuy={"action":"go.globalpurchase","params":{"skn":"${goodsGlobal.product_skn}"}}` : `//m.yohobuy.com/product/global/${goodsGlobal.product_skn}.html` })); }); // 限定商品 _.forEach(recommendProductsLimit, goodsLimit => { recommendProducts.push(Object.assign(goodsLimit, { price: parseFloat(goodsLimit.sales_price).toFixed(2), href: isApp ? `http://m.yohobuy.com/product/${goodsLimit.product_skn}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${goodsLimit.product_skn}"}}` : `//m.yohobuy.com/product/${goodsLimit.product_skn}.html` })); }); finalDetail.push({ recommendProducts: _.get(value, 'recommend_products.data', []) }); } // 视频 if (_.get(value, 'video', false)) { let src = _.get(value, 'video.data.src', ''); if (src.indexOf('http:') === 0) { src = src.replace('http:', ''); } finalDetail.push({ video: { src: src, cover_image: _.get(value, 'video.data.cover_image', '') } }); } }); return { finalDetail: finalDetail, allgoods: allgoods, css: localStyle.join('') }; }; /** * 重新获取商品数据 */ const pushGoodsInfo = (finalDetail, goodsList, isApp) => { let goodsObj = _goodsArrayToObj(productPrcs.processProductList(goodsList, { isApp: isApp })); _.forEach(finalDetail, (value, key) => { if (value.relatedReco) { let goodsIds = []; _.forEach(value.relatedReco.goods, relatedGoods => { goodsIds.push(relatedGoods.id); }); goodsIds = _.uniq(goodsIds); finalDetail[key].relatedReco.goods = []; _.forEach(goodsIds, (item, subKey) => { if (goodsObj[item]) { finalDetail[key].relatedReco.goods[subKey] = goodsObj[item]; } else { delete finalDetail[key].relatedReco.goods[subKey]; } }); finalDetail[key].relatedReco.goods = _.remove(finalDetail[key].relatedReco.goods, (obj) => { return obj; }); let moreNum = _.get(finalDetail[key], 'relatedReco.goods.length', 0); finalDetail[key].relatedReco.moreNum = moreNum - 4 > 0 ? moreNum - 4 : 0; // 改成第一屏幕最多展示4个 } if (value.collocation) { _.forEach(value.collocation, (item, subKey) => { _.forEach(item.goods, (thItem, thKey) => { if (thItem) { finalDetail[key].collocation[subKey].goods[thKey] = goodsObj[thItem.id]; } }); }); } }); return finalDetail; }; module.exports = { formatArticle, transHttpsUrl, getFilterUrl, getProductIcon, processArticleDetail, pushGoodsInfo };