Authored by 李靖

完成80%

... ... @@ -12,6 +12,7 @@ const star = require(cRoot + '/star');
const homeController = require(`${cRoot}/index`);
const plusstar = require(cRoot + '/plusstar');
const rewrite = require('../../doraemon/middleware/rewrite');
const mip = require('../../doraemon/middleware/mip');
const index = require(cRoot + '/index');
const opt = require(cRoot + '/opt');
... ... @@ -52,7 +53,7 @@ router.post('/opt/collectArticle', opt.collectArticle); // 资讯文章收藏 (H
router.post('/opt/favoriteBrand', opt.favoriteBrand); // 品牌收藏
router.get('/info/index', rewrite.channel, detail.indexRedirect); // 逛详情页
router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, detail.index); // 逛详情页 SEO优化
router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, mip, detail.index); // 逛详情页 SEO优化
router.get('/:id.html', detail.index); // 逛详情页(兼容 PC 跳转过来的链接)
router.get('/info/mini', detail.mini); // 逛mini内容页
... ...
'use strict';
const css = require('../css');
// const mipUtils = require('../mip-utils');
const helpers = global.yoho.helpers;
const _ = require('lodash');
const co = require('bluebird').coroutine;
const stringProcess = require(`${global.utils}/string-process`);
const guangProcess = require(`${global.utils}/guang-process`);
const mRoot = '../models';
const DetailModel = require(`${mRoot}/guang`);
const aboutModel = require('../../../doraemon/models/about');
const typeLib = require('../../../config/type-lib');
const channels = {
boys: 1,
girl: 2,
kids: 3,
lifestyle: 4
};
// const testStr = '';
/**
* [处理品牌数据]
* @param {[array]} getBrand [品牌原数据]
*/
const _relatedBrand = (getBrand, isApp) => {
let relatedBrand = getBrand;
relatedBrand.forEach(brand => {
brand.thumb = brand.thumb.replace('http://', '//');
if (isApp) {
brand.url = brand.url + '?openby:yohobuy={"action":"go.brand","params":{"brand_id":"' + brand.id + '"}}';
}
});
return relatedBrand;
};
/**
* [处理标签数据]
* @param {[array]} tags [标签原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedTag = (tags, isApp) => {
let relatedTag = [];
let tagUrl;
tags.forEach(value => {
tagUrl = helpers.urlFormat('/tags/index', {query: value.name}, 'guang');
if (!isApp) {
value.url = tagUrl;
} else {
if (value.url.indexOf('openby') >= 0) {
value.url = value.url;
} else {
value.url = tagUrl + '&openby:yohobuy={"action":"go.h5","params":{"query":"' + value.name + '","type":0,"title":"' + value.name + '","url":"http://guang.m.yohobuy.com/tags/index","islogin":"N"}}';
}
}
relatedTag.push(value);
});
return relatedTag;
};
/**
* [处理相关文章数据]
* @param {[array]} getOtherArticle [相关文章原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedInfo = (getOtherArticle, isApp) => {
let relatedInfo = [];
let articleUrl;
getOtherArticle.forEach(value => {
articleUrl = helpers.urlFormat('/info/index', {
id: value.id
}, 'guang');
if (isApp) {
value.url = articleUrl + '&openby:yohobuy={"action":"go.h5","params":{"id":"' + value.id + '","shareparam":{"id":"' + value.id + '"},"islogin":"N","type":1,"url":"http://guang.m.yohobuy.com/info/index","param":{"id":"' + value.id + '"}}}';
} else {
value.url = articleUrl;
}
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 detailIndex = (req, res, next) => {
let id = req.query.id || req.params[0] || req.params.id,
gender = req.query.gender ||
req.query.channel && typeLib.channels[req.query.channel] ||
req.cookies._Channel && channels[req.cookies._Channel] ||
1,
isApp = req.query.app_version || req.query.appVersion || false, // 标识是不是APP访问的
isWeixin = req.yoho.isWechat,
channel = req.query.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}"}}}`;
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
isShare = isWeixin || isqq || isWeibo ? true : false;
const detail = (req, res, next) => {
co(function* () {
return res.render('guang/detail', {
// let mipData = mipUtils.process(testStr, 0);
let detail = yield req.ctx(DetailModel).packageData(id, isApp, isWeixin, channel, isShare);
let data = {
guangDetail: true,
guang: {}
};
data.guang.isWeixin = isWeixin;
data.guang.channel = channel;
data.guang.isShare = isShare;
if (detail.code === 400) {
return next();
}
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
let url = `${detail.getAuthor.url}&openby:yohobuy={"action":"go.h5","params":{"param":{},"share":"","id":${detail.getAuthor.author_id},"type":0,"islogin":"N","url":"${detail.getAuthor.url}"}}`; // eslint-disable-line
data.guang.author.url = helpers.https(url);
}
let guang = data.guang;
guang.detail = {
id: _.get(detail, 'getArticle.id'),
title: detail.getArticle.article_title,
publishTime: detail.getArticle.publishTime,
pageView: detail.getArticle.pageViews,
content: []
};
if (!detail.getArticleContent) {
return next();
}
let processContents = guangProcess.processArticleDetail(detail.getArticleContent,
isApp,
gender,
isWeixin,
isqq,
isWeibo);
let goodsList = yield req.ctx(DetailModel).productInfoBySkns(processContents.allgoods);
guang.detail.content = guangProcess.pushGoodsInfo(processContents.finalDetail, goodsList, isApp);
// 相关品牌
if (detail.getBrand && detail.getBrand.length) {
guang.relatedBrand = _relatedBrand(detail.getBrand, isApp);
}
// 相关标签
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;
let resu = yield aboutModel.about(req.yoho.isApp);
data.guang.wxFooter = resu;
return res.render('guang/detail', Object.assign({
css: yield css('guang/detail.css'),
width750: true
});
width750: true,
title: '逛',
gender: gender,
wechatShare: true,
isWeixin: isWeixin,
isShare: isShare
// localStyle: mipData.css,
// msg: mipData.mipHtml,
}, data));
})().catch(next);
};
module.exports = {
detail
detailIndex
};
... ...
.guang-detail-c {
width: 100%;
overflow: hidden;
padding-bottom: 30px;
background-color: #f0f0f0;
}
.clearfix:after {
content: '';
display: block;
clear: both;
}
.guang-detail-c .editor-info {
width: 100%;
height: 65px;
border-bottom: 1px solid #e0e0e0;
padding: 0 20px;
background-color: #fff;
}
.editor-info .pic {
padding-top: 10px;
border-radius: 50%;
overflow: hidden;
margin-top: 10px;
width: 45px;
height: 45px;
float: left;
... ... @@ -31,6 +39,7 @@
}
.article-info {
padding: 10px 20px;
background-color: #fff;
}
.article-info .name {
line-height: 30px;
... ... @@ -45,18 +54,23 @@
}
.guang-content {
padding: 0 20px 20px;
background-color: #fff;
float: left;
margin-bottom: 20px;
}
.guang-content p {
padding: 5px 0;
}
.guang-content img {
.guang-content .pic {
clear: both;
width: 100%;
}
.related-goods {
padding: 0 20px;
float: left;
background-color: #fff;
}
.related-goods .good-item {
width: 100%;
border-top: 1px solid #e0e0e0;
float: left;
padding: 20px 0;
... ... @@ -92,22 +106,29 @@
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
font-size: 16px;
margin: 0 20px;
background-color: #fff;
padding: 0 20px;
display: block;
}
.recommend-goods {
width: 100%;
height: 133px;
overflow-x: scroll;
overflow-y: hidden;
margin: 20px 0;
background-color: #fff;
}
.good-scroll {
height: 133px;
width: 20000px;
margin: 20px 0;
overflow: hidden;
display: inline-flex;
padding-right: 20px;
}
.recommend-goods .good-item {
float: left;
position: relative;
width: 100px;
margin-left: 20px;
}
.recommend-goods .good-item .price{
width: 100px;
... ... @@ -121,8 +142,122 @@
background-color: #000;
opacity: 0.7;
}
.related-brand {
background-color: #fff;
}
.brand-c {
width: 100%;
float: left;
background-color: #fff;
}
.related-brand .title {
line-height: 60px;
text-align: center;
color: #000;
font-size: 18px;
background-color: #fff;
}
.brand-item {
width: 20%;
margin: 10px 2.5%;
float: left;
}
.brand-item p {
font-size: 13px;
color: #babac2;
line-height: 20px;
text-align: center;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.brand-tag {
border-top: 1px solid #e0e0e0;
float: left;
background-color: #fff;
width: 100%;
padding-bottom: 20px;
}
.brand-tag .tag{
background-color: #444;
float: left;
color: #fff;
line-height: 30px;
padding: 0 10px;
margin: 20px 0 0 20px;
}
.related-info {
margin: 20px 0;
padding: 20px;
background-color: #fff;
float: left;
padding-bottom: 0;
}
.related-info .info-item {
width: 100%;
float: left;
margin-bottom: 20px;
}
.related-info .info-item .pic {
width: 35%;
float: left;
}
.related-info .info-item .info {
width: 60%;
margin-left: 5%;
float: left;
}
.related-info .info-item .title{
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
word-break: break-all;
overflow: hidden;
line-height: 20px;
}
.related-info .info-item .time {
color: #b0b0b0;
line-height: 22px;
}
.big-pic {
position: relative;
margin-bottom: 3px;
}
.small-pic {
position: relative;
margin-bottom: 3px;
width: 100%;
}
.small-pic .pic {
float: left;
width: 50%;
clear: none;
}
.tag-list-box {
width: 100%;
left: 0;
bottom: 0;
position: absolute;
padding: 10px;
}
.lable-info-box {
background-color: rgba(0, 0, 0, 0.6);
color: #fff;
padding: 0 5px;
border-radius: 15px;
float: left;
line-height: 30px;
width: 60%;
height: 30px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-top: 5px;
}
.lable-info-box a {
color: #fff;
}
... ...
const cheerio = require('cheerio');
module.exports = {
/**
* 分离 CSS
* @param {*} $
* @param {*} prefix
*/
processStyle($, prefix) {
let css = [];
$('*').each(function(index) {
let $this = $(this);
let localStyle = $this.attr('style');
let className = `data-yoho-style-${prefix}-${index}`;
if (localStyle) {
css.push(`.${className}{${localStyle}}`);
$this.removeAttr('style');
$this.addClass(className);
}
});
return css.join('');
},
/**
* 替换标签
* @param {*} $
*/
processTag($) {
$('img').each(function() {
let $this = $(this);
let mipImg = `<mip-img layout="responsive" popup width="350" height="263" src="${$this.attr('src')}" alt="${$this.attr('alt') || ''}" class="${$this.attr('class') || ''}"></mip-img>`; // eslint-disable-line
$this.replaceWith(mipImg);
});
$('a').each(function() {
let $this = $(this);
let mipLink = `<mip-link layout="responsive">${$this.html()}</mip-link>`; // eslint-disable-line
$this.replaceWith(mipLink);
});
return $.html();
},
/**
* 处理 HTML 为 MIP 所需要的格式
* @param {*} html HTML
* @param {*} prefix CSS 前缀
*/
process(html, prefix) {
html = html || '';
prefix = prefix || 0;
let mipData = {};
let $ = cheerio.load(html, {
decodeEntities: false
});
mipData.css = this.processStyle($, prefix);
mipData.mipHtml = this.processTag($);
return mipData;
}
};
... ...
/**
* 逛详情models
* @author: chenfeng<feng.chen@yoho.cn>
* @date: 2016/09/07
*/
'use strict';
const serviceAPI = global.yoho.ServiceAPI;
const api = global.yoho.API;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const URI_PACKAGE_ARTICLE = 'guang/service/v2/article/';
const URI_PACKAGE_AUTHOR = 'guang/service/v1/author/';
class DetailModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 获取二级菜单顶部颜色
* @param {[string]} choosed
* @return {[string]}
*/
_getSidebarColor(choosed) {
let color = false;
if (choosed === 'girls') {
color = '#FF88AE';
} else if (choosed === 'kids') {
color = '#7ad9f9';
} else if (choosed === 'lifestyle') {
color = '#4f4138';
}
return color;
}
/**
* 微信侧边栏导航数据
* @param {*} list
* @param {*} choosed
*/
_processSideBar(list, choosed) {
const formatData = [];
let offset = 0; // 分割数组用到的游标
list = list || [];
_.forEach(list, (item, i) => {
if (item.sub) {
item.sub.unshift({
sort_name: item.sort_name,
sort_name_en: item.sort_name_en,
back: true,
isSelect: false,
bgColor: this._getSidebarColor(choosed)
});
}
// 如果有分隔符,分割数组
if (item.separative_sign === 'Y') {
formatData.push(list.slice(offset, i));
offset = i;
}
});
// 数组被分割剩余的部分
formatData.push(list.slice(offset));
return formatData;
}
_getLeftNav(choosed) {
choosed = choosed || 'all';
return serviceAPI.get('operations/api/v6/category/getCategory', {}, {
cache: true
}).then(result => {
if (result && result.code === 200) {
return this._processSideBar(result.data, choosed);
}
});
}
_getShareData(id) {
return serviceAPI.get('guang/api/v6/share/guang', {
id: id
}).then(result => {
if (result && result.code === 200) {
return result.data;
}
});
}
/**
* 获取文章接口调用
* @param {*} articleId
*/
_getArticle(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticle`, {
article_id: articleId
}, {
cache: true
});
}
/**
* 获取作者接口调用
* @param {*} authorId
*/
_getAuthor(authorId) {
return serviceAPI.get(`${URI_PACKAGE_AUTHOR}getAuthor`, {
author_id: authorId
}, {
cache: true
});
}
/**
* 获取文章详情接口调用
* @param {*} articleId
*/
_getArticleContent(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, {
article_id: articleId
}, {
cache: true
});
}
/**
* 获取文章相关品牌接口调用
* @param {*} articleId
*/
_getBrand(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getBrand`, {
article_id: articleId
}, {
cache: true
});
}
/**
* 获取资讯相关的其它资讯接口调用
* @param {*} articleId
* @param {*} tag
*/
_getOtherArticle(articleId, tag) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getOtherArticle`, {
article_id: articleId,
tags: tag,
offset: 0,
limit: 3
}, {
cache: true
});
}
/**
* APP 获取微信模块
*/
_getSingleTemplateWechat() {
return api.get('', {
method: 'app.resources.getSingleTemplate',
module: 'wechat',
key: 'guang_detail_wechat'
});
}
/**
* [逛资讯详情页数据封装]
* @param {[int]} id [内容ID]
* @param {Boolean} isApp [标识是否是APP访问]
* @return {[array]}
*/
packageData(id, isApp, isWeixin, channel, isShare) {
let result = {
getAuthor: {},
getArticle: {},
getArticleContent: {},
getBrand: {},
getOtherArticle: {}
};
// 获取资讯
return this._getArticle(id).then(data => {
// 调用接口失败
if (!data || data.code !== 200) {
result.code = 400;
return result;
}
let article = result.getArticle = data && data.data || {};
let promises = [
this._getAuthor(article.author_id),
this._getArticleContent(id),
this._getBrand(id)
];
// 获取资讯相关的其它资讯
if (typeof article.tag !== 'undefined') {
promises.push(this._getOtherArticle(id, article.tag));
}
// APP 获取微信模块
if (isApp) {
promises.push(this._getSingleTemplateWechat());
}
if (isShare) {
let navGender = _.cloneDeep(channel);
promises.push(
this._getLeftNav(navGender),
this._getShareData(id)
);
}
return Promise.all(promises).then(datas => {
let getArticleContent = [];
if (!datas) {
return result;
}
if (datas[1]) {
result.getArticleContent = getArticleContent = datas[1].data;
}
if (isApp && datas[4] && datas[4].data) {
let preCount = 0;
let i;
for (i = 0; i < getArticleContent.length; i++) {
if (getArticleContent[i].singleImage ||
getArticleContent[i].text || getArticleContent[i].smallPic) {
preCount++;
}
}
_.forEach(datas[4].data, item => {
item.src = helpers.image(item.src, 280, 210, 1);
});
getArticleContent.splice(preCount, 0, {
weixinPublic: datas[4].data
});
}
if (isShare && datas[5]) {
if (datas[5].wechatShareImgUrl) {
datas[5].wechatShareImgUrl =
datas[5].wechatShareImgUrl.substring(datas[5].wechatShareImgUrl.indexOf('//'));
if (datas[5].wechatShareImgUrl.indexOf('?') === -1) {
datas[5].wechatShareImgUrl = datas[5].wechatShareImgUrl +
'?imageView2/2/interlace/1/q/75';
}
} else if (datas[5].qqShareImgUrl) {
datas[5].qqShareImgUrl =
datas[5].qqShareImgUrl.substring(datas[5].qqShareImgUrl.indexOf('//'));
if (datas[5].qqShareImgUrl.indexOf('?') === -1) {
datas[5].qqShareImgUrl = datas[5].wechatShareImgUrl + '?imageView2/2/interlace/1/q/75';
}
} else if (datas[5].showShareImgUrl) {
datas[5].showShareImgUrl =
datas[5].showShareImgUrl.substring(datas[5].showShareImgUrl.indexOf('//'));
if (datas[5].showShareImgUrl.indexOf('?') === -1) {
datas[5].showShareImgUrl = datas[5].showShareImgUrl + '?imageView2/2/interlace/1/q/75';
}
}
let preCount = 0;
let i;
for (i = 0; i < getArticleContent.length; i++) {
if (getArticleContent[i].singleImage ||
getArticleContent[i].text || getArticleContent[i].smallPic) {
preCount = i + 1;
}
}
getArticleContent.splice(preCount, 0, {
shareCode: datas[5]
});
}
if (datas[0]) {
result.getAuthor = datas[0].data;
}
if (datas[2]) {
result.getBrand = datas[2].data;
}
if (isShare && datas[4]) {
result.sideNav = datas[4];
}
if (datas.length === 5 && isApp || datas.length === 4 && !isApp || datas.length === 6 && isShare) {
if (datas[3]) {
result.getOtherArticle = datas[3].data;
}
}
return result;
});
});
}
/**
* [获取详情信息]
* @param {[int]} id [资讯id]
* @return {[object]}
*/
intro(id) {
let param = {
article_id: id,
client_type: 'h5'
};
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, param, {
cache: true
});
}
/**
* [根据商品SKN获取商品的简要信息]
* @param {[array]} sknString [skns]
* @return {[type]}
*/
productInfoBySkns(sknString) {
// 调用搜索接口
let param = {
method: 'h5.product.batch',
productSkn: sknString,
order: 's_t_desc'
};
return api.get('', param, {
cache: true
}).then(result => {
return _.get(result, 'data.product_list', []);
});
}
}
module.exports = DetailModel;
... ...
... ... @@ -12,8 +12,8 @@ const cRoot = './controllers';
const mip = require('../../doraemon/middleware/mip');
const guang = require(`${cRoot}/guang`);
router.use(mip());
router.use(mip);
router.get('/guang/info/:id.html', guang.detail);
router.get('/guang/info/:id.html', guang.detailIndex);
module.exports = router;
... ...
<div class="guang-detail-c">
<div class="editor-info">
<mip-img class="pic" src="http://img13.static.yhbimg.com/author/2016/04/26/11/025bce88d3e2f071cfed867cd0cc1322ce.jpg">
</mip-img>
<div class="name">章三</div>
<div class="intro">kuchuadad1</div>
{{# guang}}
{{# author}}
<div class="editor-info" data-id={{id}}>
<a href={{url}}>
<mip-img class="pic" src={{image2 avatar mode=2 q=60}}>
</mip-img>
<div class="name">{{name}}</div>
<div class="intro">{{intro}}</div>
</a>
</div>
{{/ author}}
{{# detail}}
<div class="article-info">
<p class="name">测试一下新版逛资讯</p>
<p class="name">{{title}}</p>
<div class="view-c">
<span class="iconfont">&#xe603;5月8日 10:11</span>
<span class="iconfont">&#xe603;9999</span>
<span class="iconfont">&#xe603;{{publishTime}}</span>
<span class="iconfont">&#xe603;{{pageView}}</span>
</div>
</div>
<div class="guang-content">
<p>阿三开的花镂空的卡 u 还是离开</p>
<mip-img src="//img11.static.yhbimg.com/goodsimg/2017/05/08/10/01c1a22365138c958321d7adca2a399124.png">
</mip-img>
<p>阿三开的花镂空的卡 u 还是离开</p>
</mip-img>
</div>
<div class="related-goods clearfix">
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<div class="info">
<p class="name">damao-基础店铺商品18</p>
<p class="price">¥500</p>
</div>
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
<div class="guang-content clearfix">
{{# content}}
{{#if text}}
{{{text}}}
{{/if}}
{{#if bigImage}}
<div class="big-pic">
<mip-img class="pic" src="{{image2 bigImage q=60}}">
</mip-img>
<div class="info">
<p class="name">damao-基础店铺商品18</p>
<p class="price">¥500</p>
{{#if tagList}}
<div class="tag-list-box">
{{#each tagList}}
{{#unless isApp}}
<div class="label-box" data-skn="{{product_skn}}">
<div class="lable-info-box{{#if isApp}} lable-infobox-borderadius{{/if}}"><a href="{{href}}">{{tagName}}</a></div>
<div class="lable-btn add-to-cart" data-skn="{{product_skn}}">
</div>
</div>
{{/unless}}
{{/each}}
</div>
{{/if}}
</div>
{{/if}}
{{#if smallImage}}
<div class="small-pic">
{{# smallImage}}
<mip-img class="pic" src="{{image2 src q=60}}">
</mip-img>
{{/ smallImage}}
</div>
{{/if}}
{{#if relatedReco}}
<div class="related-goods clearfix">
{{#each relatedReco.goods}}
<div class="good-item">
<a href="{{url}}">
{{#if default_images}}
<mip-img class="pic" src="{{image2 default_images w=152 h=204}}">
</mip-img>
{{/if}}
<div class="info">
<p class="name">{{product_name}}</p>
{{#if sales_price}}
<p class="price">&yen;{{sales_price}}</p>
{{/if}}
</div>
</a>
</div>
{{/each}}
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<div class="info">
<p class="name">damao-基础店铺商品18</p>
<p class="price">¥500</p>
{{/if}}
{{/ content}}
</div>
{{/ detail}}
{{#detail.content}}
{{#if moreLink}}
<a class="more-goods" href="{{moreLink}}">更多商品</a>
{{/if}}
{{#if recommendProducts}}
<div class="recommend-goods">
<div class="good-scroll">
{{#each recommendProducts}}
<div class="good-item">
<a href="{{href}}">
<mip-img class="pic" src="{{image2 pic_url w=152 h=204}}">
</mip-img>
</a>
<p class="price">&yen;{{price}}</p>
</div>
{{/each}}
</div>
</div>
{{/if}}
{{/detail.content}}
{{#if relatedBrand}}
<div class="related-brand clearfix">
<div class="title">相关品牌</div>
<div class="brand-c">
{{# relatedBrand}}
<div class="brand-item">
<a href={{url}}>
<mip-img class="pic" src="{{thumb}}">
</mip-img>
<p>{{name}}</p>
</a>
</div>
{{/ relatedBrand}}
</div>
</div>
<div class="more-goods">更多商品</div>
<div class="recommend-goods">
<div class="good-scroll">
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<p class="price">¥500</p>
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
{{/if}}
{{#if relatedInfo}}
<div class="related-info">
{{# relatedInfo}}
<div class="info-item">
<a href={{url}}>
<mip-img class="pic" src="{{thumb}}">
</mip-img>
<p class="price">¥500</p>
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<p class="price">¥500</p>
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<p class="price">¥500</p>
</div>
<div class="good-item">
<mip-img class="pic" src="http://img10.static.yhbimg.com/goodsimg/2015/11/10/15/01ca0eef0fa9c4f8f8f6e40ef8f6e34344.jpg">
</mip-img>
<p class="price">¥500</p>
</div>
<div class="info">
<p class="title">{{title}}</p>
<p class="time">{{publishTime}}</p>
</div>
</a>
</div>
{{/ relatedInfo}}
</div>
{{/if}}
{{#if relatedTag}}
<div class="brand-tag">
{{# relatedTag}}
<div class="tag">{{name}}</div>
{{/ relatedTag}}
</div>
{{/if}}
{{/ guang}}
</div>
... ...
'use strict';
module.exports = () => {
return (req, res, next) => {
Object.assign(res.locals, {
canonical: 'https://m.yohobuy.com' + req.path,
mip: 'https://mip.yohobuy.com' + req.path
});
module.exports = (req, res, next) => {
Object.assign(res.locals, {
canonical: 'https://m.yohobuy.com' + req.path,
miphtml: 'https://m.yohobuy.com/mip' + req.originalUrl
});
next();
};
next();
};
... ...
... ... @@ -12,8 +12,11 @@
<meta content="email=no" name="format-detection" />
<meta name="referrer" content="always">
{{# cononical}}
<link rel="cononical" href="{{currentHref}}"/>
<link rel="cononical" href="{{currentHref}}">
{{/ cononical}}
{{#if miphtml}}
<link rel="miphtml" href="{{miphtml}}">
{{/if}}
{{#dnsPrefetch.hosts}}
<link rel="dns-prefetch" href="{{this}}">
{{/dnsPrefetch.hosts}}
... ... @@ -74,7 +77,7 @@
{{> footer}}
{{/unless}}
</div>
{{> download-app}}
{{#ifand isProduction wap.open.bughd}}
<script type="text/javascript" src="https://dn-bughd-web.qbox.me/bughd.min.js" crossOrigin="anonymous"></script>
... ...
... ... @@ -8,6 +8,7 @@
<link rel="canonical" href="{{canonical}}">
<style mip-custom>
{{css}}
{{localStyle}}
</style>
</head>
<body>
... ...