/** * 逛详情页 * @author: chenfeng<feng.chen@yoho.cn> * @date: 2016/09/07 */ 'use strict'; const helpers = global.yoho.helpers; const mRoot = '../models'; const infoModel = require(`${mRoot}/info`); const stringProcess = require(`${global.utils}/string-process`); const guangProcess = require(`${global.utils}/guang-process`); const productDetailModel = require('../../product/models/detail'); const headerModel = require('../../../doraemon/models/header'); // 头部model const channels = { boys: 1, girl: 2, kids: 3, lifestyle: 4 }; /** * [生成逛资讯内容] * @param {[array]} articleContent [迭代内容] * @param {Boolean} isApp [是否在app] * @param {[Boolean]} gender [性别] */ const _pageArticleContent = (articleContent, isApp, gender, isWeixin, isqq, isWeibo) => { let contents = []; return new Promise((resolve) => { let joinContentFunc = (i, len) => { if (i < len) { let build = {}; let art = articleContent[i]; // 文字 if (art.text && art.text.data && art.text.data.text) { build.text = art.text.data.text; contents.push(build); joinContentFunc(++i, len); } else if (art.singleImage && art.singleImage.data && art.singleImage.data.length) { // 单张图 build.bigImage = helpers.image(art.singleImage.data[0].src, 640, 640); // 前三张图片不使用懒加载,下同 if (i <= 3) { build.noLazy = true; } contents.push(build); joinContentFunc(++i, len); } else if (art.smallPic && art.smallPic.data && art.smallPic.data.length > 1) { let imgs = art.smallPic.data; if (i <= 3) { build.noLazy = true; } build.smallImage = [{ src: helpers.image(imgs[0].src, 315, 420) }, { src: helpers.image(imgs[1].src, 315, 420) }]; contents.push(build); joinContentFunc(++i, len); } else if (art.weixinPublic) { build.weixinPublic = art.weixinPublic; contents.push(build); joinContentFunc(++i, len); } else if (art.shareCode) { let shareCode; if (art.shareCode.qqShareImgUrl || art.shareCode.wechatShareImgUrl || art.shareCode.showShareImgUrl) { if (isWeixin) { shareCode = art.shareCode.wechatShareImgUrl; } else if (isqq) { shareCode = art.shareCode.qqShareImgUrl; } else if (isWeibo) { shareCode = art.shareCode.showShareImgUrl; } } if (shareCode) { build.shareCode = [{ codeShare: shareCode }]; } else { build.shareCode = false; } contents.push(build); joinContentFunc(++i, len); } else if (art.goods && art.goods.data) { // 相关推荐 let reco = [], skns = [], arr = []; // 遍历取得SKN art.goods.data.forEach(goods => { skns.push(goods.id); arr[goods.id] = goods.src; }); // 通过SKN获取商品信息 productDetailModel.productInfoBySkns(skns).then((product) => { if (product && product.data) { if (product.data.product_list) { let d = []; for (let o = 0; o < product.data.product_list.length; o++) { let goods = product.data.product_list[o]; // 最多显示4个 if (o > 3) { break; } d.push(guangProcess.formatProduct(goods, false, true, true, 235, 314, isApp, true, gender)); } d.forEach(p => { if (arr[p.id]) { p.thumb = helpers.image(arr[p.id], 235, 314); reco.push(p); } }); } // 多个商品 if (product.data.product_list && product.data.product_list.length && (product.data.product_list.length > 1)) { build.relatedReco = reco; } else if (product.data.product_list && product.data.product_list.length === 1) { // 单个商品 build.relatedReco = reco[0]; } } contents.push(build); joinContentFunc(++i, len); }); } else if (art.goodsGroup && art.goodsGroup.data) { // 悬停浮动商品 let callArtGoodGroup = (ii, len2) => { if (ii < len2) { let goods = art.goodsGroup.data[ii]; if (goods) { let good = { thumb: goods.cover ? helpers.image(goods.cover.cover, 235, 314) : '', type: goods.cover ? guangProcess.getProductIcon(goods.cover.maxSortId) : '', goods: [] }; let skns = []; let arr = []; goods.list.forEach((mini) => { if (mini) { skns.push(mini.id); arr[mini.id] = mini.src; } }); // 通过SKN获取商品信息 productDetailModel.productInfoBySkns(skns).then((product) => { if (product && product.data && product.data.product_list) { let g = []; product.data.product_list.forEach(_ => { g.push(guangProcess.formatProduct(_, false, true, true, 235, 314, isApp, gender)); }); g.forEach(p => { if (arr[p.id]) { p.thumb = helpers.image(arr[p.id], 235, 314); good.goods.push(p); } }); if (!build.collocation) { build.collocation = []; } build.collocation.push(good); } callArtGoodGroup(++ii, len2); }); } else { callArtGoodGroup(++ii, len2); } } else { contents.push(build); joinContentFunc(++i, len); } }; callArtGoodGroup(0, art.goodsGroup.data.length); } else if (art.link) { // 更多商品链接 build.moreLink = art.link.data[0].url; contents.push(build); joinContentFunc(++i, len); } else { joinContentFunc(++i, len); } } else { resolve(contents); } }; joinContentFunc(0, articleContent.length); }); }; /** * [处理品牌数据] * @param {[array]} getBrand [品牌原数据] */ const _relatedBrand = (getBrand) => { let relatedBrand = getBrand; relatedBrand.forEach(brand => { brand.thumb = brand.thumb.replace('http://', '//'); }); return relatedBrand; }; /** * [处理标签数据] * @param {[array]} tags [标签原数据] * @param {[Boolean]} isApp [是否app] */ const _relatedTag = (tags, isApp) => { let relatedTag = []; tags.forEach(value => { if (!isApp) { value.url = helpers.urlFormat('/tags/index', { query: value.name }, 'guang'); } relatedTag.push(value); }); return relatedTag; }; /** * [处理相关文章数据] * @param {[array]} getOtherArticle [相关文章原数据] * @param {[Boolean]} isApp [是否app] */ const _relatedInfo = (getOtherArticle, isApp) => { let relatedInfo = []; getOtherArticle.forEach(value => { if (!isApp) { value.url = helpers.urlFormat('/info/index', { id: value.id }, 'guang'); } value.thumb = helpers.image(value.thumb, 279, 175); relatedInfo.push(value); }); return relatedInfo; }; /** * [处理分享内容] * @param {[int]} id [资讯id] * @param {[array]} getArticle [资讯内容] */ const _shareInfo = (id, getArticle) => { let shareInfo = {}; shareInfo.shareLink = 'http:' + helpers.urlFormat('/info/index', { id: id }, 'guang'); shareInfo.shareTitle = getArticle.article_title; shareInfo.shareDesc = getArticle.article_summary; if (getArticle.cover_image_type === 1) { shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 640); } else { shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 320); } return shareInfo; }; /** * [逛资讯详情页] */ const index = (req, res, next) => { let id = req.query.id || req.params.id, gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1, isApp = req.query.app_version || req.query.appVersion || false, // 标识是不是APP访问的 parameter = {}, title = '逛', isWeixin = req.yoho.isWechat, channel = req.cookies._Channel, isqq = req.yoho.isqq, isWeibo = req.yoho.isWeibo, isShare; res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.h5","params":{"id":"${id}","share":"/guang/api/v1/share/guang?id=${id}","shareparam":{"id":"${id}"},"islogin":"N","type":1,"url":"http://guang.m.yohobuy.com/info/index","param":{"id":"${id}"}}}`; // pagecache 前端做 // userAgent = req.get('User-Agent'), // isWeixin = userAgent.includes('MicroMessenger'); // 标识是否是微信访问 // 判断参数是否有效, 无效会跳转到错误页面 if (!stringProcess.isNumeric(id)) { res.json({ code: 400, message: '非法请求', data: '' }); return; } parameter = { pageHeader: headerModel.setNav({ navTitle: title }) }; isShare = isWeixin || isqq || isWeibo ? true : false; // WAP上设置头部导航 pagecache // if (!isApp && !isWeixin) { // parameter = { // pageHeader: headerModel.setNav({ // navTitle: title // }) // }; // } // 获取详情内容信息, 异常则跳到错误页面 return infoModel.packageData(id, isApp, isWeixin, channel, isShare).then(detail => { let data = { guangDetail: true, guang: {} }; data.guang.isWeixin = isWeixin; data.guang.channel = channel; data.guang.isShare = isShare; if (detail.code !== 400) { if (!detail.getArticle) { // TODO 跳转到逛首页 return; } if (isShare && detail && detail.sideNav) { data.sideNav = detail.sideNav; } // 作者信息数据 if (detail && detail.getAuthor && (typeof detail.getAuthor.name !== 'undefined')) { data.guang.author = { avatar: detail.getAuthor.avatar.replace('http://', '//'), name: detail.getAuthor.name, intro: detail.getAuthor.author_desc }; // guang双头部的问题 20160601 // 正确的URL data.guang.author.url = helpers.https(`${detail.getAuthor.url}&openby:yohobuy={"action":"go.h5","params":{"param":{},"share":"","id":${detail.getAuthor.author_id},"type":0,"islogin":"N","url":"${detail.getAuthor.url}"}}`); // 错误的URL // data.guang.author.url = helpers.https(`${detail.getAuthor.url}&openby:yohobuy={"action":"go.h5","params":{"param":{"id":"${detail.getAuthor.author_id}"},"share":"","id":${detail.getAuthor.author_id},"type":0,"islogin":"N","url":"${helpers.urlFormat('/author/index', {}, 'guang')}"}}`); } let guang = data.guang; guang.detail = { title: detail.getArticle.article_title, publishTime: detail.getArticle.publishTime, pageView: detail.getArticle.pageViews, content: [] }; if (detail.getArticleContent) { // 生成内容部分 return _pageArticleContent(detail.getArticleContent, isApp, gender, isWeixin, isqq, isWeibo).then((contents) => { guang.detail.content = contents; // 相关品牌 if (detail.getBrand && detail.getBrand.length) { guang.relatedBrand = _relatedBrand(detail.getBrand); } // 相关标签 if (detail.getArticle.tags && detail.getArticle.tags.length) { guang.relatedTag = _relatedTag(detail.getArticle.tags, isApp); } // 相关文章 if (detail.getOtherArticle && detail.getOtherArticle.length) { guang.relatedInfo = _relatedInfo(detail.getOtherArticle, isApp); } // 分享参数 if (detail.getArticle.cover_image) { let shareInfo = _shareInfo(id, detail.getArticle); Object.assign(guang, shareInfo); data.title = detail.getArticle.article_title + ' | Yoho!Buy有货 | 潮流购物逛不停'; data.title_more = true; data.description = detail.getArticle.article_summary; data.description_more = true; } // 标识有微信分享 data.hasWxShare = true; res.render('info/index', Object.assign({ page: 'info-index', title: '逛', gender: gender, wechatShare: true, isWeixin: isWeixin, localCss: true, isShare: isShare }, data, parameter)); }); } else { next(); return; } } }).catch(next); }; /** * [逛mini内容页] */ const mini = (req, res, next) => { let id = req.query.id, gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1, isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的 // 判断参数是否有效, 无效会跳转到错误页面 if (!stringProcess.isNumeric(id)) { res.json({ code: 400, message: '非法请求', data: '' }); return; } // 获取详情内容信息, 异常则跳到错误页面 return infoModel.packageData(id, isApp).then(detail => { let data = { guangEzine: true, guang: {} }; if (detail.code !== 400) { if (!detail.getArticle) { // TODO 跳转到逛首页 return; } let guang = data.guang; guang.detail = { title: detail.getArticle.article_title, publishTime: detail.getArticle.publishTime, pageView: detail.getArticle.pageViews, content: [] }; if (detail.getArticleContent) { // 生成内容部分 return _pageArticleContent(detail.getArticleContent, isApp, gender).then((contents) => { guang.detail.content = contents; // 相关品牌 if (detail.getBrand && detail.getBrand.length) { guang.relatedBrand = _relatedBrand(detail.getBrand); } // 分享参数 if (detail.getArticle.cover_image) { let shareInfo = _shareInfo(id, detail.getArticle); Object.assign(guang, shareInfo); } // 标识有微信分享 data.hasWxShare = true; res.render('info/index', Object.assign({ page: 'info-index', title: '逛', gender: gender, wechatShare: true }, data)); }); } else { next(); return; } } }).catch(next); }; /** * [提供给YOHO资讯站调用的接口] */ const foryoho = (req, res, next) => { let id = req.query.id, gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1, isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的 // 判断参数是否有效, 无效会跳转到错误页面 if (!stringProcess.isNumeric(id)) { res.json({ code: 400, message: '非法请求', data: '' }); return; } // 获取详情内容信息, 异常则跳到错误页面 return infoModel.packageData(id, isApp).then(detail => { let data = {}; if (detail.code !== 400) { if (!detail.getArticle) { // TODO 跳转到逛首页 return; } data.brand = detail.getBrand; if (detail.getArticleContent) { // 生成内容部分 return _pageArticleContent(detail.getArticleContent, isApp, gender).then((contents) => { data.content = contents; // 内容中的相关推荐和悬浮商品移到data层级 let relatedRecoIndex = data.content.findIndex((cont) => { return typeof cont.relatedReco !== 'undefined'; }); let collocationIndex = data.content.findIndex((cont) => { return typeof cont.collocation !== 'undefined'; }); if (relatedRecoIndex > 0) { data.goods = data.content[relatedRecoIndex].relatedReco; data.content.splice(relatedRecoIndex, 1); } if (collocationIndex > 0) { data.group = data.content[collocationIndex].collocation; data.content.splice(collocationIndex, 1); } res.json(data); }); } else { next(); return; } } }).catch(next); }; module.exports = { index, mini, foryoho };