merge-master
Showing
33 changed files
with
1467 additions
and
61 deletions
@@ -23,7 +23,9 @@ exports.index = (req, res, next) => { | @@ -23,7 +23,9 @@ exports.index = (req, res, next) => { | ||
23 | module: 'activity', | 23 | module: 'activity', |
24 | page: 'coupon-floor', | 24 | page: 'coupon-floor', |
25 | wechatShare: true, | 25 | wechatShare: true, |
26 | - title: '领券中心', | 26 | + title: '有货优惠券_有货现金优惠券,全场券,品类券,品牌券_领券频道-Yoho!Buy有货', |
27 | + keywords: '有货优惠券,有货现金优惠券,全场券,品类券,品牌券', | ||
28 | + description: 'Yoho!Buy有货官网领券频道,提供有货优惠券,有货现金优惠券,有货全场券,有货品类券,品牌券免费领取,让你做网购达人,省钱又省心!', | ||
27 | pageHeader: headerModel.setNav({ | 29 | pageHeader: headerModel.setNav({ |
28 | navTitle: '领券中心' | 30 | navTitle: '领券中心' |
29 | }), | 31 | }), |
@@ -22,9 +22,9 @@ | @@ -22,9 +22,9 @@ | ||
22 | style="{{#if param.bgcolor}}background-color:{{param.bgcolor}}{{/if}}"> | 22 | style="{{#if param.bgcolor}}background-color:{{param.bgcolor}}{{/if}}"> |
23 | {{#if param.bgimg}} | 23 | {{#if param.bgimg}} |
24 | {{#isLazyLoad type @index}} | 24 | {{#isLazyLoad type @index}} |
25 | - <img class="lazy" data-original="{{image2 param.bgimg q=75}}"> | 25 | + <img class="lazy" data-original="{{imageslim param.bgimg}}"> |
26 | {{else}} | 26 | {{else}} |
27 | - <img src="{{image2 param.bgimg q=75}}"> | 27 | + <img src="{{imageslim param.bgimg}}"> |
28 | {{/isLazyLoad}} | 28 | {{/isLazyLoad}} |
29 | {{/if}} | 29 | {{/if}} |
30 | {{#component}} | 30 | {{#component}} |
@@ -34,7 +34,7 @@ | @@ -34,7 +34,7 @@ | ||
34 | {{#if modalImg}} | 34 | {{#if modalImg}} |
35 | <div class="modal"> | 35 | <div class="modal"> |
36 | <span class="modal-close"></span> | 36 | <span class="modal-close"></span> |
37 | - <img class="modal-img lazy" data-original="{{image2 modalImg q=75}}"> | 37 | + <img class="modal-img lazy" data-original="{{imageslim modalImg}}"> |
38 | </div> | 38 | </div> |
39 | {{/if}} | 39 | {{/if}} |
40 | {{/isEqualOr}} | 40 | {{/isEqualOr}} |
@@ -66,7 +66,7 @@ | @@ -66,7 +66,7 @@ | ||
66 | <div class="swiper-wrapper"> | 66 | <div class="swiper-wrapper"> |
67 | {{#list}} | 67 | {{#list}} |
68 | <div class="swiper-slide" style="{{styleFormat this percent=1}}"> | 68 | <div class="swiper-slide" style="{{styleFormat this percent=1}}"> |
69 | - <img src="{{image2 src q=75}}"> | 69 | + <img src="{{imageslim src}}"> |
70 | <a class="anchor" href="{{#if link}}{{link}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../../this @index}}"></a> | 70 | <a class="anchor" href="{{#if link}}{{link}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../../this @index}}"></a> |
71 | </div> | 71 | </div> |
72 | {{/list}} | 72 | {{/list}} |
@@ -88,7 +88,7 @@ | @@ -88,7 +88,7 @@ | ||
88 | 88 | ||
89 | {{#isEqualOr type 'productGroup'}} | 89 | {{#isEqualOr type 'productGroup'}} |
90 | {{! 商品池}} | 90 | {{! 商品池}} |
91 | - <div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{image2 proBgImg q=75}}) repeat;background-size:100%;"{{/if}}> | 91 | + <div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{imageslim proBgImg}}) repeat;background-size:100%;"{{/if}}> |
92 | <div class="product-source" condition='{{stringify searchCondition}}' fp="{{getAnalysis ../this @index}}" | 92 | <div class="product-source" condition='{{stringify searchCondition}}' fp="{{getAnalysis ../this @index}}" |
93 | {{#unless defaultPros.length}} | 93 | {{#unless defaultPros.length}} |
94 | {{#if searchCondition.item}} | 94 | {{#if searchCondition.item}} |
@@ -103,9 +103,9 @@ | @@ -103,9 +103,9 @@ | ||
103 | <div class="feature-product-info {{#if ../searchCondition}}novisible{{/if}}"> | 103 | <div class="feature-product-info {{#if ../searchCondition}}novisible{{/if}}"> |
104 | <a class="first-part product-detail" href='{{producturl}}'> | 104 | <a class="first-part product-detail" href='{{producturl}}'> |
105 | <div class="product-detail-imgbox"> | 105 | <div class="product-detail-imgbox"> |
106 | - {{#if ../lefTopImg}}<img class="leftopimg lazy" data-original="{{image2 ../lefTopImg q=75}}">{{/if}} | ||
107 | - {{#if ../rigTopImg}}<img class="rigtopimg lazy" data-original="{{image2 ../rigTopImg q=75}}">{{/if}} | ||
108 | - <img class="product-detail-img lazy" data-original="{{image2 productimg q=75}}"> | 106 | + {{#if ../lefTopImg}}<img class="leftopimg lazy" data-original="{{imageslim ../lefTopImg}}">{{/if}} |
107 | + {{#if ../rigTopImg}}<img class="rigtopimg lazy" data-original="{{imageslim ../rigTopImg}}">{{/if}} | ||
108 | + <img class="product-detail-img lazy" data-original="{{imageslim productimg}}"> | ||
109 | </div> | 109 | </div> |
110 | {{#isEqualOr ../showPrdName '1'}}<p class="product-name">{{productname}}</p>{{/isEqualOr}} | 110 | {{#isEqualOr ../showPrdName '1'}}<p class="product-name">{{productname}}</p>{{/isEqualOr}} |
111 | <div class="product-detail-text"> | 111 | <div class="product-detail-text"> |
@@ -128,7 +128,7 @@ | @@ -128,7 +128,7 @@ | ||
128 | <div class="brand-div"> | 128 | <div class="brand-div"> |
129 | <span class="brand-name"{{#if ../fontColor}}style="color:{{../fontColor}};"{{/if}}>{{brandname}}</span> | 129 | <span class="brand-name"{{#if ../fontColor}}style="color:{{../fontColor}};"{{/if}}>{{brandname}}</span> |
130 | </div> | 130 | </div> |
131 | - <img class="brand-img lazy" data-original="{{image2 ../brandImg q=75}}"> | 131 | + <img class="brand-img lazy" data-original="{{imageslim ../brandImg}}"> |
132 | </a> | 132 | </a> |
133 | {{/if}} | 133 | {{/if}} |
134 | </div> | 134 | </div> |
@@ -137,8 +137,8 @@ | @@ -137,8 +137,8 @@ | ||
137 | <div class="feature-product-info novisible"> | 137 | <div class="feature-product-info novisible"> |
138 | <a class="first-part product-detail" href=''> | 138 | <a class="first-part product-detail" href=''> |
139 | <div class="product-detail-imgbox"> | 139 | <div class="product-detail-imgbox"> |
140 | - {{#if lefTopImg}}<img class="leftopimg" src="{{image2 lefTopImg q=75}}">{{/if}} | ||
141 | - {{#if rigTopImg}}<img class="rigtopimg" src="{{image2 rigTopImg q=75}}">{{/if}} | 140 | + {{#if lefTopImg}}<img class="leftopimg" src="{{imageslim lefTopImg}}">{{/if}} |
141 | + {{#if rigTopImg}}<img class="rigtopimg" src="{{imageslim rigTopImg}}">{{/if}} | ||
142 | <img class="product-detail-img" src=""> | 142 | <img class="product-detail-img" src=""> |
143 | </div> | 143 | </div> |
144 | {{#isEqualOr showPrdName '1'}}<p class="product-name"></p>{{/isEqualOr}} | 144 | {{#isEqualOr showPrdName '1'}}<p class="product-name"></p>{{/isEqualOr}} |
@@ -161,7 +161,7 @@ | @@ -161,7 +161,7 @@ | ||
161 | <div class="brand-div"> | 161 | <div class="brand-div"> |
162 | <span class="brand-name" {{#if fontColor}}style="color:{{fontColor}};"{{/if}}></span> | 162 | <span class="brand-name" {{#if fontColor}}style="color:{{fontColor}};"{{/if}}></span> |
163 | </div> | 163 | </div> |
164 | - <img class="brand-img" src="{{image2 brandImg q=75}}"> | 164 | + <img class="brand-img" src="{{imageslim brandImg}}"> |
165 | </a> | 165 | </a> |
166 | {{/if}} | 166 | {{/if}} |
167 | </div> | 167 | </div> |
@@ -251,7 +251,6 @@ const index = (req, res, next) => { | @@ -251,7 +251,6 @@ const index = (req, res, next) => { | ||
251 | console.log(data); | 251 | console.log(data); |
252 | res.render('info/index', Object.assign({ | 252 | res.render('info/index', Object.assign({ |
253 | page: 'info-index', | 253 | page: 'info-index', |
254 | - title: '逛', | ||
255 | gender: gender, | 254 | gender: gender, |
256 | wechatShare: true, | 255 | wechatShare: true, |
257 | isWeixin: isWeixin, | 256 | isWeixin: isWeixin, |
@@ -67,7 +67,9 @@ const editor = (req, res, next) => { | @@ -67,7 +67,9 @@ const editor = (req, res, next) => { | ||
67 | 67 | ||
68 | res.render('index/list', Object.assign({ | 68 | res.render('index/list', Object.assign({ |
69 | page: 'index-editor', | 69 | page: 'index-editor', |
70 | - title: title, | 70 | + title: `潮流编辑${authorData.data.name}|YOHO!BUY有货`, |
71 | + keywords: `潮流编辑${authorData.data.name}`, | ||
72 | + description: `YOHO!BUY有货潮流编辑${authorData.data.name}!`, | ||
71 | guangList: true, | 73 | guangList: true, |
72 | gender: gender, | 74 | gender: gender, |
73 | guang: { | 75 | guang: { |
@@ -193,7 +195,9 @@ const index = (req, res, next) => { | @@ -193,7 +195,9 @@ const index = (req, res, next) => { | ||
193 | let responseData = { | 195 | let responseData = { |
194 | module: 'guang', | 196 | module: 'guang', |
195 | page: 'index', | 197 | page: 'index', |
196 | - title: '逛 | Yoho!Buy有货 | 潮流购物逛不停', | 198 | + title: '逛|逛潮流,逛购物,官方授权正品潮流购物中心|YOHO!BUY有货', |
199 | + keywords: '逛,逛潮流,逛购物', | ||
200 | + description: 'YOHO!BUY有货逛频道,来YOHO!玩潮流!潮搭大解析!年轻人潮流购物中心,中国潮流购物风向标,吴亦凡重磅代言!YOHO!BUY有货100%正品保证,支持货到付款。', | ||
197 | showFooterTab: footerModel.getUrlData('guang') | 201 | showFooterTab: footerModel.getUrlData('guang') |
198 | }; | 202 | }; |
199 | 203 | ||
@@ -238,7 +242,9 @@ const tag = (req, res, next) => { | @@ -238,7 +242,9 @@ const tag = (req, res, next) => { | ||
238 | pageHeader: headerData, | 242 | pageHeader: headerData, |
239 | module: 'guang', | 243 | module: 'guang', |
240 | page: 'index-editor', | 244 | page: 'index-editor', |
241 | - title: tagTitle + ' | Yoho!Buy有货 | 潮流购物逛不停' | 245 | + title: tagTitle + ' | Yoho!Buy有货 | 潮流购物逛不停', |
246 | + keywords: tagTitle, | ||
247 | + description: 'YOHO!BUY有货潮流' + tagTitle + '!' | ||
242 | }; | 248 | }; |
243 | 249 | ||
244 | let param = { | 250 | let param = { |
@@ -12,6 +12,7 @@ const star = require(cRoot + '/star'); | @@ -12,6 +12,7 @@ const star = require(cRoot + '/star'); | ||
12 | const homeController = require(`${cRoot}/index`); | 12 | const homeController = require(`${cRoot}/index`); |
13 | const plusstar = require(cRoot + '/plusstar'); | 13 | const plusstar = require(cRoot + '/plusstar'); |
14 | const rewrite = require('../../doraemon/middleware/rewrite'); | 14 | const rewrite = require('../../doraemon/middleware/rewrite'); |
15 | +const mip = require('../../doraemon/middleware/mip'); | ||
15 | 16 | ||
16 | const index = require(cRoot + '/index'); | 17 | const index = require(cRoot + '/index'); |
17 | const opt = require(cRoot + '/opt'); | 18 | const opt = require(cRoot + '/opt'); |
@@ -52,7 +53,7 @@ router.post('/opt/collectArticle', opt.collectArticle); // 资讯文章收藏 (H | @@ -52,7 +53,7 @@ router.post('/opt/collectArticle', opt.collectArticle); // 资讯文章收藏 (H | ||
52 | router.post('/opt/favoriteBrand', opt.favoriteBrand); // 品牌收藏 | 53 | router.post('/opt/favoriteBrand', opt.favoriteBrand); // 品牌收藏 |
53 | 54 | ||
54 | router.get('/info/index', rewrite.channel, detail.indexRedirect); // 逛详情页 | 55 | router.get('/info/index', rewrite.channel, detail.indexRedirect); // 逛详情页 |
55 | -router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, detail.index); // 逛详情页 SEO优化 | 56 | +router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, mip, detail.index); // 逛详情页 SEO优化 |
56 | 57 | ||
57 | router.get('/:id.html', detail.index); // 逛详情页(兼容 PC 跳转过来的链接) | 58 | router.get('/:id.html', detail.index); // 逛详情页(兼容 PC 跳转过来的链接) |
58 | router.get('/info/mini', detail.mini); // 逛mini内容页 | 59 | router.get('/info/mini', detail.mini); // 逛mini内容页 |
apps/mip/controllers/guang.js
0 → 100644
1 | +'use strict'; | ||
2 | +const css = require('../css'); | ||
3 | + | ||
4 | +// const mipUtils = require('../mip-utils'); | ||
5 | +const helpers = global.yoho.helpers; | ||
6 | +const _ = require('lodash'); | ||
7 | +const co = require('bluebird').coroutine; | ||
8 | +const stringProcess = require(`${global.utils}/string-process`); | ||
9 | +const guangProcess = require(`${global.utils}/guang-process`); | ||
10 | +const mRoot = '../models'; | ||
11 | +const DetailModel = require(`${mRoot}/guang`); | ||
12 | +const typeLib = require('../../../config/type-lib'); | ||
13 | +const channels = { | ||
14 | + boys: 1, | ||
15 | + girl: 2, | ||
16 | + kids: 3, | ||
17 | + lifestyle: 4 | ||
18 | +}; | ||
19 | + | ||
20 | +// const testStr = ''; | ||
21 | + | ||
22 | +/** | ||
23 | + * [处理品牌数据] | ||
24 | + * @param {[array]} getBrand [品牌原数据] | ||
25 | + */ | ||
26 | +const _relatedBrand = (getBrand, isApp) => { | ||
27 | + let relatedBrand = getBrand; | ||
28 | + | ||
29 | + relatedBrand.forEach(brand => { | ||
30 | + brand.thumb = brand.thumb.replace('http://', '//'); | ||
31 | + | ||
32 | + if (isApp) { | ||
33 | + brand.url = brand.url + '?openby:yohobuy={"action":"go.brand","params":{"brand_id":"' + brand.id + '"}}'; | ||
34 | + } | ||
35 | + }); | ||
36 | + | ||
37 | + return relatedBrand; | ||
38 | +}; | ||
39 | + | ||
40 | +/** | ||
41 | + * [处理标签数据] | ||
42 | + * @param {[array]} tags [标签原数据] | ||
43 | + * @param {[Boolean]} isApp [是否app] | ||
44 | + */ | ||
45 | +const _relatedTag = (tags, isApp) => { | ||
46 | + let relatedTag = []; | ||
47 | + let tagUrl; | ||
48 | + | ||
49 | + tags.forEach(value => { | ||
50 | + | ||
51 | + tagUrl = helpers.urlFormat('/tags/index', {query: value.name}, 'guang'); | ||
52 | + | ||
53 | + if (!isApp) { | ||
54 | + value.url = tagUrl; | ||
55 | + } else { | ||
56 | + if (value.url.indexOf('openby') >= 0) { | ||
57 | + value.url = value.url; | ||
58 | + } else { | ||
59 | + 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"}}'; | ||
60 | + } | ||
61 | + } | ||
62 | + | ||
63 | + relatedTag.push(value); | ||
64 | + }); | ||
65 | + | ||
66 | + return relatedTag; | ||
67 | +}; | ||
68 | + | ||
69 | +/** | ||
70 | + * [处理相关文章数据] | ||
71 | + * @param {[array]} getOtherArticle [相关文章原数据] | ||
72 | + * @param {[Boolean]} isApp [是否app] | ||
73 | + */ | ||
74 | +const _relatedInfo = (getOtherArticle, isApp) => { | ||
75 | + let relatedInfo = []; | ||
76 | + let articleUrl; | ||
77 | + | ||
78 | + getOtherArticle.forEach(value => { | ||
79 | + articleUrl = helpers.urlFormat('/info/index', { | ||
80 | + id: value.id | ||
81 | + }, 'guang'); | ||
82 | + | ||
83 | + if (isApp) { | ||
84 | + 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 + '"}}}'; | ||
85 | + } else { | ||
86 | + value.url = articleUrl; | ||
87 | + } | ||
88 | + | ||
89 | + value.thumb = helpers.image(value.thumb, 279, 175); | ||
90 | + relatedInfo.push(value); | ||
91 | + }); | ||
92 | + | ||
93 | + return relatedInfo; | ||
94 | +}; | ||
95 | + | ||
96 | +const detailIndex = (req, res, next) => { | ||
97 | + let id = req.query.id || req.params[0] || req.params.id, | ||
98 | + gender = req.query.gender || | ||
99 | + req.query.channel && typeLib.channels[req.query.channel] || | ||
100 | + req.cookies._Channel && channels[req.cookies._Channel] || | ||
101 | + 1, | ||
102 | + isApp = req.query.app_version || req.query.appVersion || false, // 标识是不是APP访问的 | ||
103 | + isWeixin = req.yoho.isWechat, | ||
104 | + channel = req.query.channel || req.cookies._Channel, | ||
105 | + isqq = req.yoho.isqq, | ||
106 | + isWeibo = req.yoho.isWeibo, | ||
107 | + isMip = true, | ||
108 | + isShare; | ||
109 | + | ||
110 | + 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}"}}}`; | ||
111 | + | ||
112 | + // 判断参数是否有效, 无效会跳转到错误页面 | ||
113 | + if (!stringProcess.isNumeric(id)) { | ||
114 | + res.json({ | ||
115 | + code: 400, | ||
116 | + message: '非法请求', | ||
117 | + data: '' | ||
118 | + }); | ||
119 | + return; | ||
120 | + } | ||
121 | + | ||
122 | + isShare = isWeixin || isqq || isWeibo ? true : false; | ||
123 | + | ||
124 | + co(function* () { | ||
125 | + // let mipData = mipUtils.process(testStr, 0); | ||
126 | + let detail = yield req.ctx(DetailModel).packageData(id, isApp, isWeixin, channel, isShare); | ||
127 | + let data = { | ||
128 | + guangDetail: true, | ||
129 | + guang: {} | ||
130 | + }; | ||
131 | + | ||
132 | + data.guang.isWeixin = isWeixin; | ||
133 | + data.guang.channel = channel; | ||
134 | + data.guang.isShare = isShare; | ||
135 | + | ||
136 | + if (detail.code === 400) { | ||
137 | + return next(); | ||
138 | + } | ||
139 | + if (!detail.getArticle) { | ||
140 | + // TODO 跳转到逛首页 | ||
141 | + return; | ||
142 | + } | ||
143 | + | ||
144 | + if (isShare && detail && detail.sideNav) { | ||
145 | + data.sideNav = detail.sideNav; | ||
146 | + } | ||
147 | + | ||
148 | + // 作者信息数据 | ||
149 | + if (detail && detail.getAuthor && (typeof detail.getAuthor.name !== 'undefined')) { | ||
150 | + data.guang.author = { | ||
151 | + avatar: detail.getAuthor.avatar.replace('http://', '//'), | ||
152 | + name: detail.getAuthor.name, | ||
153 | + intro: detail.getAuthor.author_desc | ||
154 | + }; | ||
155 | + | ||
156 | + // guang双头部的问题 20160601 | ||
157 | + // 正确的URL | ||
158 | + 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 | ||
159 | + | ||
160 | + data.guang.author.url = helpers.https(url); | ||
161 | + } | ||
162 | + let guang = data.guang; | ||
163 | + | ||
164 | + guang.detail = { | ||
165 | + id: _.get(detail, 'getArticle.id'), | ||
166 | + title: detail.getArticle.article_title, | ||
167 | + publishTime: detail.getArticle.publishTime, | ||
168 | + pageView: detail.getArticle.pageViews, | ||
169 | + content: [] | ||
170 | + }; | ||
171 | + if (!detail.getArticleContent) { | ||
172 | + return next(); | ||
173 | + } | ||
174 | + | ||
175 | + let processContents = guangProcess.processArticleDetail(detail.getArticleContent, | ||
176 | + isApp, | ||
177 | + gender, | ||
178 | + isWeixin, | ||
179 | + isqq, | ||
180 | + isWeibo, isMip); | ||
181 | + | ||
182 | + let goodsList = yield req.ctx(DetailModel).productInfoBySkns(processContents.allgoods); | ||
183 | + | ||
184 | + guang.detail.content = guangProcess.pushGoodsInfo(processContents.finalDetail, goodsList, isApp); | ||
185 | + | ||
186 | + // 相关品牌 | ||
187 | + if (detail.getBrand && detail.getBrand.length) { | ||
188 | + guang.relatedBrand = _relatedBrand(detail.getBrand, isApp); | ||
189 | + } | ||
190 | + | ||
191 | + // 相关标签 | ||
192 | + if (detail.getArticle.tags && detail.getArticle.tags.length) { | ||
193 | + guang.relatedTag = _relatedTag(detail.getArticle.tags, isApp); | ||
194 | + } | ||
195 | + | ||
196 | + // 相关文章 | ||
197 | + if (detail.getOtherArticle && detail.getOtherArticle.length) { | ||
198 | + guang.relatedInfo = _relatedInfo(detail.getOtherArticle, isApp); | ||
199 | + } | ||
200 | + | ||
201 | + return res.render('guang/detail', Object.assign({ | ||
202 | + css: yield css('guang/detail.css'), | ||
203 | + gender: gender, | ||
204 | + localStyle: processContents.css, | ||
205 | + title: detail.getArticle.article_title | ||
206 | + }, data)); | ||
207 | + })().catch(next); | ||
208 | +}; | ||
209 | + | ||
210 | +module.exports = { | ||
211 | + detailIndex | ||
212 | +}; |
apps/mip/css.js
0 → 100644
1 | +const fs = require('fs'); | ||
2 | +const path = require('path'); | ||
3 | +const cssnano = require('cssnano'); | ||
4 | + | ||
5 | +const logger = global.yoho.logger; | ||
6 | +const css = {}; | ||
7 | + | ||
8 | +module.exports = (file) => { | ||
9 | + const isNotDev = process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test'; | ||
10 | + | ||
11 | + if (css[file] && isNotDev) { | ||
12 | + return Promise.resolve(css[file]); | ||
13 | + } | ||
14 | + | ||
15 | + const cssPath = path.join(__dirname, 'css', file); | ||
16 | + const cssfile = fs.readFileSync(cssPath).toString(); | ||
17 | + | ||
18 | + logger.info(`cssnano process ${cssPath}`); | ||
19 | + return cssnano.process(cssfile, { | ||
20 | + safe: true, | ||
21 | + autoprefixer: { | ||
22 | + add: true, | ||
23 | + browsers: ['> 1%', 'android >=4', 'ios >=8'] | ||
24 | + } | ||
25 | + }).then(function(result) { | ||
26 | + if (result && result.css) { | ||
27 | + css[file] = result.css; | ||
28 | + return css[file]; | ||
29 | + } | ||
30 | + return ''; | ||
31 | + }).catch(err => { | ||
32 | + logger.error(err); | ||
33 | + return ''; | ||
34 | + }); | ||
35 | +}; |
apps/mip/css/guang/detail.css
0 → 100644
1 | +.guang-detail-c { | ||
2 | + max-width: 750px; | ||
3 | + width: 100%; | ||
4 | + overflow: hidden; | ||
5 | + background-color: #f0f0f0; | ||
6 | + margin:0 auto; | ||
7 | +} | ||
8 | +.clearfix:after { | ||
9 | + content: ''; | ||
10 | + display: block; | ||
11 | + clear: both; | ||
12 | +} | ||
13 | +.guang-detail-c .editor-info { | ||
14 | + width: 100%; | ||
15 | + height: 65px; | ||
16 | + border-bottom: 1px solid #e0e0e0; | ||
17 | + padding: 0 20px; | ||
18 | + background-color: #fff; | ||
19 | +} | ||
20 | +.editor-info .pic { | ||
21 | + border-radius: 50%; | ||
22 | + overflow: hidden; | ||
23 | + margin-top: 10px; | ||
24 | + width: 45px; | ||
25 | + height: 45px; | ||
26 | + float: left; | ||
27 | +} | ||
28 | +.editor-info .name { | ||
29 | + line-height: 65px; | ||
30 | + float: left; | ||
31 | + font-size: 14px; | ||
32 | + color: #000; | ||
33 | + padding-left: 20px; | ||
34 | +} | ||
35 | +.editor-info .intro { | ||
36 | + line-height: 65px; | ||
37 | + float: left; | ||
38 | + font-size: 14px; | ||
39 | + color: #b0b0b0; | ||
40 | + padding-left: 20px; | ||
41 | +} | ||
42 | +.article-info { | ||
43 | + padding: 10px 20px; | ||
44 | + background-color: #fff; | ||
45 | +} | ||
46 | +.article-info .name { | ||
47 | + line-height: 30px; | ||
48 | + font-size: 20px; | ||
49 | + color: #000; | ||
50 | + font-weight: bold; | ||
51 | +} | ||
52 | +.article-info .view-c { | ||
53 | + color: #b0b0b0; | ||
54 | + font-size: 12px; | ||
55 | + line-height: 30px; | ||
56 | +} | ||
57 | +.guang-content { | ||
58 | + padding: 0 20px 20px; | ||
59 | + background-color: #fff; | ||
60 | + float: left; | ||
61 | + margin-bottom: 20px; | ||
62 | + box-sizing: border-box; | ||
63 | + width: 100%; | ||
64 | +} | ||
65 | +.guang-content p { | ||
66 | + padding: 5px 0; | ||
67 | +} | ||
68 | +.guang-content .pic { | ||
69 | + clear: both; | ||
70 | + margin: 0 auto; | ||
71 | + display: block; | ||
72 | + max-width: 100%; | ||
73 | +} | ||
74 | +.related-goods { | ||
75 | + float: left; | ||
76 | + width: 100%; | ||
77 | + background-color: #fff; | ||
78 | +} | ||
79 | +.related-goods .good-item { | ||
80 | + width: 100%; | ||
81 | + border-top: 1px solid #e0e0e0; | ||
82 | + float: left; | ||
83 | + padding: 20px 0; | ||
84 | +} | ||
85 | +.related-goods .good-item .pic { | ||
86 | + width: 25%; | ||
87 | + float: left; | ||
88 | +} | ||
89 | +.pic-mip { | ||
90 | + max-width: 100%; | ||
91 | +} | ||
92 | +.related-goods .good-item .info { | ||
93 | + width: 70%; | ||
94 | + float: left; | ||
95 | + margin-left: 5%; | ||
96 | +} | ||
97 | +.related-goods .good-item .name { | ||
98 | + color: #000; | ||
99 | + padding: 10px 0; | ||
100 | + font-size: 14px; | ||
101 | + display: -webkit-box; | ||
102 | + -webkit-line-clamp: 3; | ||
103 | + overflow: hidden; | ||
104 | + text-overflow: ellipsis; | ||
105 | + -webkit-box-orient: vertical; | ||
106 | + line-height: 25px; | ||
107 | +} | ||
108 | +.related-goods .good-item .price{ | ||
109 | + color: #d62927; | ||
110 | + font-size: 14px; | ||
111 | +} | ||
112 | +.more-goods { | ||
113 | + height: 40px; | ||
114 | + line-height: 40px; | ||
115 | + clear: both; | ||
116 | + border-top: 1px solid #e0e0e0; | ||
117 | + border-bottom: 1px solid #e0e0e0; | ||
118 | + font-size: 16px; | ||
119 | + background-color: #fff; | ||
120 | + padding: 0 20px; | ||
121 | + display: block; | ||
122 | +} | ||
123 | +.recommend-goods { | ||
124 | + width: 100%; | ||
125 | + overflow-x: scroll; | ||
126 | + overflow-y: hidden; | ||
127 | + margin: 20px 0; | ||
128 | + background-color: #fff; | ||
129 | + -webkit-overflow-scrolling: touch; | ||
130 | +} | ||
131 | +.good-scroll { | ||
132 | + height: 133px; | ||
133 | + margin: 20px 0; | ||
134 | + overflow: hidden; | ||
135 | + display: inline-flex; | ||
136 | + padding-right: 20px; | ||
137 | +} | ||
138 | +.recommend-goods .good-item { | ||
139 | + float: left; | ||
140 | + position: relative; | ||
141 | + width: 100px; | ||
142 | + margin-left: 20px; | ||
143 | +} | ||
144 | +.recommend-goods .good-item .price{ | ||
145 | + width: 100px; | ||
146 | + height: 20px; | ||
147 | + color: #fff; | ||
148 | + text-align: center; | ||
149 | + line-height: 20px; | ||
150 | + position: absolute; | ||
151 | + bottom: 0; | ||
152 | + left: 0; | ||
153 | + background-color: #000; | ||
154 | + opacity: 0.7; | ||
155 | +} | ||
156 | +.related-brand { | ||
157 | + background-color: #fff; | ||
158 | +} | ||
159 | +.brand-c { | ||
160 | + width: 100%; | ||
161 | + float: left; | ||
162 | + background-color: #fff; | ||
163 | +} | ||
164 | +.related-brand .title { | ||
165 | + line-height: 60px; | ||
166 | + text-align: center; | ||
167 | + color: #000; | ||
168 | + font-size: 18px; | ||
169 | + background-color: #fff; | ||
170 | +} | ||
171 | +.brand-item { | ||
172 | + width: 20%; | ||
173 | + margin: 10px 2.5%; | ||
174 | + float: left; | ||
175 | +} | ||
176 | +.brand-item p { | ||
177 | + font-size: 13px; | ||
178 | + color: #babac2; | ||
179 | + line-height: 20px; | ||
180 | + text-align: center; | ||
181 | + width: 100%; | ||
182 | + overflow: hidden; | ||
183 | + text-overflow: ellipsis; | ||
184 | + white-space: nowrap; | ||
185 | +} | ||
186 | +.brand-tag { | ||
187 | + border-top: 1px solid #e0e0e0; | ||
188 | + float: left; | ||
189 | + background-color: #fff; | ||
190 | + width: 100%; | ||
191 | + padding-bottom: 20px; | ||
192 | + padding-right: 20px; | ||
193 | + box-sizing: border-box; | ||
194 | +} | ||
195 | +.brand-tag .tag{ | ||
196 | + background-color: #444; | ||
197 | + float: left; | ||
198 | + color: #fff; | ||
199 | + line-height: 30px; | ||
200 | + padding: 0 10px; | ||
201 | + margin: 20px 0 0 20px; | ||
202 | +} | ||
203 | +.related-info { | ||
204 | + margin: 20px 0; | ||
205 | + padding: 20px; | ||
206 | + background-color: #fff; | ||
207 | + float: left; | ||
208 | + padding-bottom: 0; | ||
209 | +} | ||
210 | +.related-info .info-item { | ||
211 | + width: 100%; | ||
212 | + float: left; | ||
213 | + margin-bottom: 20px; | ||
214 | +} | ||
215 | +.related-info .info-item .pic { | ||
216 | + width: 35%; | ||
217 | + float: left; | ||
218 | +} | ||
219 | +.related-info .info-item .info { | ||
220 | + width: 60%; | ||
221 | + margin-left: 5%; | ||
222 | + float: left; | ||
223 | +} | ||
224 | +.related-info .info-item .title{ | ||
225 | + display: -webkit-box; | ||
226 | + -webkit-box-orient: vertical; | ||
227 | + -webkit-line-clamp: 3; | ||
228 | + word-break: break-all; | ||
229 | + overflow: hidden; | ||
230 | + line-height: 20px; | ||
231 | +} | ||
232 | +.related-info .info-item .time { | ||
233 | + color: #b0b0b0; | ||
234 | + line-height: 22px; | ||
235 | +} | ||
236 | +.big-pic { | ||
237 | + position: relative; | ||
238 | + margin-bottom: 3px; | ||
239 | + clear: both; | ||
240 | +} | ||
241 | +.small-pic { | ||
242 | + position: relative; | ||
243 | + margin-bottom: 3px; | ||
244 | + width: 100%; | ||
245 | +} | ||
246 | +.small-pic .pic { | ||
247 | + float: left; | ||
248 | + width: 50%; | ||
249 | + clear: none; | ||
250 | + max-width: 50%; | ||
251 | +} | ||
252 | +.tag-list-box { | ||
253 | + width: 100%; | ||
254 | + left: 0; | ||
255 | + bottom: 0; | ||
256 | + position: absolute; | ||
257 | + padding: 10px; | ||
258 | +} | ||
259 | +.label-box { | ||
260 | + clear: both; | ||
261 | +} | ||
262 | +.lable-info-box { | ||
263 | + font-size: 12px; | ||
264 | + background-color: rgba(0, 0, 0, 0.6); | ||
265 | + color: #fff; | ||
266 | + padding: 0 5px; | ||
267 | + border-radius: 15px; | ||
268 | + float: left; | ||
269 | + line-height: 25px; | ||
270 | + width: 60%; | ||
271 | + height: 25px; | ||
272 | + overflow: hidden; | ||
273 | + text-overflow: ellipsis; | ||
274 | + white-space: nowrap; | ||
275 | + margin-top: 5px; | ||
276 | +} | ||
277 | +.lable-info-box a { | ||
278 | + color: #fff; | ||
279 | + overflow: hidden; | ||
280 | + text-overflow: ellipsis; | ||
281 | +} | ||
282 | +.lable-focus { | ||
283 | + float: left; | ||
284 | + display: flex; | ||
285 | + align-items: center; | ||
286 | + line-height: 25px; | ||
287 | + height: 25px; | ||
288 | + margin-right: 15px; | ||
289 | + margin-top: 5px; | ||
290 | +} | ||
291 | +.lable-focus .focus-big { | ||
292 | + display: flex; | ||
293 | + align-items: center; | ||
294 | + width: 17px; | ||
295 | + height: 17px; | ||
296 | + border-radius: 17px; | ||
297 | + border: 4px solid rgba(253, 157, 43, 0.5); | ||
298 | + -webkit-box-pack: center; | ||
299 | + -webkit-justify-content: center; | ||
300 | + justify-content: center; | ||
301 | +} | ||
302 | +.lable-focus .focus-small { | ||
303 | + width: 17px; | ||
304 | + height: 17px; | ||
305 | + border-radius: 17px; | ||
306 | + background: rgba(253, 157, 43, 1); | ||
307 | + -webkit-transform: scale(0.5, 0.5); | ||
308 | + transform: scale(0.5, 0.5); | ||
309 | + margin: 0; | ||
310 | +} | ||
311 | + | ||
312 | + |
apps/mip/index.js
0 → 100644
1 | +/** | ||
2 | + * sub app service | ||
3 | + * @author: xuan.chen@yoho.cn<xuan.chen@yoho.cn> | ||
4 | + * @date: 2016/11/21 | ||
5 | + */ | ||
6 | + | ||
7 | +var express = require('express'), | ||
8 | + path = require('path'); | ||
9 | + | ||
10 | +var app = express(); | ||
11 | + | ||
12 | +// set view engin | ||
13 | +var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root | ||
14 | + | ||
15 | +app.on('mount', function(parent) { | ||
16 | + delete parent.locals.settings; // 不继承父 App 的设置 | ||
17 | + Object.assign(app.locals, parent.locals); | ||
18 | +}); | ||
19 | + | ||
20 | +app.use(global.yoho.hbs({ | ||
21 | + extname: '.hbs', | ||
22 | + defaultLayout: 'mip', | ||
23 | + layoutsDir: doraemon, | ||
24 | + partialsDir: [path.join(__dirname, 'views/partial')], | ||
25 | + views: path.join(__dirname, 'views/action'), | ||
26 | + helpers: global.yoho.helpers | ||
27 | +})); | ||
28 | + | ||
29 | +app.locals.layout = 'mip'; | ||
30 | + | ||
31 | +// router | ||
32 | +app.use(require('./router')); | ||
33 | + | ||
34 | +module.exports = app; |
apps/mip/mip-utils.js
0 → 100644
1 | +const cheerio = require('cheerio'); | ||
2 | + | ||
3 | +module.exports = { | ||
4 | + /** | ||
5 | + * 分离 CSS | ||
6 | + * @param {*} $ | ||
7 | + * @param {*} prefix | ||
8 | + */ | ||
9 | + processStyle($, prefix) { | ||
10 | + let css = []; | ||
11 | + | ||
12 | + $('*').each(function(index) { | ||
13 | + let $this = $(this); | ||
14 | + let localStyle = $this.attr('style'); | ||
15 | + let className = `yoho-inline-style-${prefix}-${index}`; | ||
16 | + | ||
17 | + if (localStyle) { | ||
18 | + css.push(`.${className}{${localStyle}}`); | ||
19 | + $this.removeAttr('style'); | ||
20 | + $this.addClass(className); | ||
21 | + } | ||
22 | + }); | ||
23 | + return css.join(''); | ||
24 | + }, | ||
25 | + | ||
26 | + /** | ||
27 | + * 替换标签 | ||
28 | + * @param {*} $ | ||
29 | + */ | ||
30 | + processTag($) { | ||
31 | + let css = []; | ||
32 | + | ||
33 | + // mip-anim | ||
34 | + $('img[src*=".gif"]').each(function() { | ||
35 | + let $this = $(this); | ||
36 | + let mipAnim = `<mip-anim layout="responsive" width="350" height="263" src="${$this.attr('src')}" alt="${$this.attr('alt') || ''}" class="${$this.attr('class') || ''}"></mip-anim>`; // eslint-disable-line | ||
37 | + | ||
38 | + $this.replaceWith(mipAnim); | ||
39 | + }); | ||
40 | + | ||
41 | + // mip-img | ||
42 | + $('img').each(function() { | ||
43 | + let $this = $(this); | ||
44 | + let mipImg = `<mip-img layout="responsive" width="350" height="263" src="${$this.attr('src')}" alt="${$this.attr('alt') || ''}" class="${$this.attr('class') || ''}"></mip-img>`; // eslint-disable-line | ||
45 | + | ||
46 | + $this.replaceWith(mipImg); | ||
47 | + }); | ||
48 | + | ||
49 | + // mip-video | ||
50 | + $('video').each(function() { | ||
51 | + let $this = $(this); | ||
52 | + let mipVideo = `<mip-video layout="responsive" width="350" height="263" poster="${$this.attr('poster') || ''}" src="${$this.attr('src')}" alt="${$this.attr('alt') || ''}" class="${$this.attr('class') || ''}"></mip-video>`; // eslint-disable-line | ||
53 | + | ||
54 | + $this.replaceWith(mipVideo); | ||
55 | + }); | ||
56 | + | ||
57 | + // mip-audio | ||
58 | + $('audio').each(function() { | ||
59 | + let $this = $(this); | ||
60 | + let mipAudio = `<mip-audio src="${$this.attr('src')}"></mip-audio>`; // eslint-disable-line | ||
61 | + | ||
62 | + $this.replaceWith(mipAudio); | ||
63 | + }); | ||
64 | + | ||
65 | + // mip-iframe | ||
66 | + $('iframe').each(function() { | ||
67 | + let $this = $(this); | ||
68 | + let mipIframe = `<mip-iframe layout="responsive" width="350" height="263" src="${$this.attr('src')}" class="${$this.attr('class') || ''}"></mip-iframe>`; // eslint-disable-line | ||
69 | + | ||
70 | + $this.replaceWith(mipIframe); | ||
71 | + }); | ||
72 | + | ||
73 | + // mip-link | ||
74 | + $('a').each(function() { | ||
75 | + let $this = $(this); | ||
76 | + let mipLink = `<mip-link href="${$this.attr('href')}" class="${$this.attr('class') || ''}" title="${$this.attr('title') || ''}">${$this.html()}</mip-link>`; // eslint-disable-line | ||
77 | + | ||
78 | + $this.replaceWith(mipLink); | ||
79 | + }); | ||
80 | + | ||
81 | + // style | ||
82 | + $('style').each(function() { | ||
83 | + let $this = $(this); | ||
84 | + | ||
85 | + css.push($this.html()); | ||
86 | + $this.remove(); | ||
87 | + }); | ||
88 | + | ||
89 | + return { | ||
90 | + mipHtml: $.html(), | ||
91 | + css: css.join('') | ||
92 | + }; | ||
93 | + }, | ||
94 | + | ||
95 | + /** | ||
96 | + * 处理 HTML 为 MIP 所需要的格式 | ||
97 | + * @param {*} html HTML | ||
98 | + * @param {*} prefix CSS 前缀 | ||
99 | + */ | ||
100 | + | ||
101 | + process(html = '', prefix = 0) { | ||
102 | + let $ = cheerio.load(html, { | ||
103 | + decodeEntities: false | ||
104 | + }); | ||
105 | + let inlineStyle = this.processStyle($, prefix); // 必须先处理内联样式 | ||
106 | + let tagHtml = this.processTag($); | ||
107 | + | ||
108 | + return { | ||
109 | + mipHtml: tagHtml.mipHtml, | ||
110 | + css: tagHtml.css + inlineStyle | ||
111 | + }; | ||
112 | + } | ||
113 | +}; | ||
114 | + |
apps/mip/models/guang.js
0 → 100644
1 | +/** | ||
2 | + * 逛详情models | ||
3 | + * @author: chenfeng<feng.chen@yoho.cn> | ||
4 | + * @date: 2016/09/07 | ||
5 | + */ | ||
6 | +'use strict'; | ||
7 | +const serviceAPI = global.yoho.ServiceAPI; | ||
8 | +const api = global.yoho.API; | ||
9 | +const _ = require('lodash'); | ||
10 | +const helpers = global.yoho.helpers; | ||
11 | + | ||
12 | +const URI_PACKAGE_ARTICLE = 'guang/service/v2/article/'; | ||
13 | +const URI_PACKAGE_AUTHOR = 'guang/service/v1/author/'; | ||
14 | + | ||
15 | + | ||
16 | +class DetailModel extends global.yoho.BaseModel { | ||
17 | + constructor(ctx) { | ||
18 | + super(ctx); | ||
19 | + } | ||
20 | + | ||
21 | + /** | ||
22 | + * 获取二级菜单顶部颜色 | ||
23 | + * @param {[string]} choosed | ||
24 | + * @return {[string]} | ||
25 | + */ | ||
26 | + _getSidebarColor(choosed) { | ||
27 | + let color = false; | ||
28 | + | ||
29 | + if (choosed === 'girls') { | ||
30 | + color = '#FF88AE'; | ||
31 | + } else if (choosed === 'kids') { | ||
32 | + color = '#7ad9f9'; | ||
33 | + } else if (choosed === 'lifestyle') { | ||
34 | + color = '#4f4138'; | ||
35 | + } | ||
36 | + | ||
37 | + return color; | ||
38 | + } | ||
39 | + | ||
40 | + /** | ||
41 | + * 微信侧边栏导航数据 | ||
42 | + * @param {*} list | ||
43 | + * @param {*} choosed | ||
44 | + */ | ||
45 | + _processSideBar(list, choosed) { | ||
46 | + const formatData = []; | ||
47 | + let offset = 0; // 分割数组用到的游标 | ||
48 | + | ||
49 | + list = list || []; | ||
50 | + | ||
51 | + _.forEach(list, (item, i) => { | ||
52 | + if (item.sub) { | ||
53 | + item.sub.unshift({ | ||
54 | + sort_name: item.sort_name, | ||
55 | + sort_name_en: item.sort_name_en, | ||
56 | + back: true, | ||
57 | + isSelect: false, | ||
58 | + bgColor: this._getSidebarColor(choosed) | ||
59 | + }); | ||
60 | + } | ||
61 | + | ||
62 | + // 如果有分隔符,分割数组 | ||
63 | + if (item.separative_sign === 'Y') { | ||
64 | + formatData.push(list.slice(offset, i)); | ||
65 | + offset = i; | ||
66 | + } | ||
67 | + }); | ||
68 | + | ||
69 | + // 数组被分割剩余的部分 | ||
70 | + formatData.push(list.slice(offset)); | ||
71 | + return formatData; | ||
72 | + } | ||
73 | + | ||
74 | + _getLeftNav(choosed) { | ||
75 | + choosed = choosed || 'all'; | ||
76 | + | ||
77 | + return serviceAPI.get('operations/api/v6/category/getCategory', {}, { | ||
78 | + cache: true | ||
79 | + }).then(result => { | ||
80 | + if (result && result.code === 200) { | ||
81 | + | ||
82 | + return this._processSideBar(result.data, choosed); | ||
83 | + } | ||
84 | + }); | ||
85 | + } | ||
86 | + | ||
87 | + _getShareData(id) { | ||
88 | + return serviceAPI.get('guang/api/v6/share/guang', { | ||
89 | + id: id | ||
90 | + }).then(result => { | ||
91 | + if (result && result.code === 200) { | ||
92 | + | ||
93 | + return result.data; | ||
94 | + } | ||
95 | + }); | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * 获取文章接口调用 | ||
100 | + * @param {*} articleId | ||
101 | + */ | ||
102 | + _getArticle(articleId) { | ||
103 | + return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticle`, { | ||
104 | + article_id: articleId | ||
105 | + }, { | ||
106 | + cache: true | ||
107 | + }); | ||
108 | + } | ||
109 | + | ||
110 | + /** | ||
111 | + * 获取作者接口调用 | ||
112 | + * @param {*} authorId | ||
113 | + */ | ||
114 | + _getAuthor(authorId) { | ||
115 | + return serviceAPI.get(`${URI_PACKAGE_AUTHOR}getAuthor`, { | ||
116 | + author_id: authorId | ||
117 | + }, { | ||
118 | + cache: true | ||
119 | + }); | ||
120 | + } | ||
121 | + | ||
122 | + /** | ||
123 | + * 获取文章详情接口调用 | ||
124 | + * @param {*} articleId | ||
125 | + */ | ||
126 | + _getArticleContent(articleId) { | ||
127 | + return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, { | ||
128 | + article_id: articleId | ||
129 | + }, { | ||
130 | + cache: true | ||
131 | + }); | ||
132 | + } | ||
133 | + | ||
134 | + /** | ||
135 | + * 获取文章相关品牌接口调用 | ||
136 | + * @param {*} articleId | ||
137 | + */ | ||
138 | + _getBrand(articleId) { | ||
139 | + return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getBrand`, { | ||
140 | + article_id: articleId | ||
141 | + }, { | ||
142 | + cache: true | ||
143 | + }); | ||
144 | + } | ||
145 | + | ||
146 | + /** | ||
147 | + * 获取资讯相关的其它资讯接口调用 | ||
148 | + * @param {*} articleId | ||
149 | + * @param {*} tag | ||
150 | + */ | ||
151 | + _getOtherArticle(articleId, tag) { | ||
152 | + return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getOtherArticle`, { | ||
153 | + article_id: articleId, | ||
154 | + tags: tag, | ||
155 | + offset: 0, | ||
156 | + limit: 3 | ||
157 | + }, { | ||
158 | + cache: true | ||
159 | + }); | ||
160 | + } | ||
161 | + | ||
162 | + /** | ||
163 | + * APP 获取微信模块 | ||
164 | + */ | ||
165 | + _getSingleTemplateWechat() { | ||
166 | + return api.get('', { | ||
167 | + method: 'app.resources.getSingleTemplate', | ||
168 | + module: 'wechat', | ||
169 | + key: 'guang_detail_wechat' | ||
170 | + }); | ||
171 | + } | ||
172 | + | ||
173 | + /** | ||
174 | + * [逛资讯详情页数据封装] | ||
175 | + * @param {[int]} id [内容ID] | ||
176 | + * @param {Boolean} isApp [标识是否是APP访问] | ||
177 | + * @return {[array]} | ||
178 | + */ | ||
179 | + packageData(id, isApp, isWeixin, channel, isShare) { | ||
180 | + let result = { | ||
181 | + getAuthor: {}, | ||
182 | + getArticle: {}, | ||
183 | + getArticleContent: {}, | ||
184 | + getBrand: {}, | ||
185 | + getOtherArticle: {} | ||
186 | + }; | ||
187 | + | ||
188 | + // 获取资讯 | ||
189 | + return this._getArticle(id).then(data => { | ||
190 | + // 调用接口失败 | ||
191 | + if (!data || data.code !== 200) { | ||
192 | + result.code = 400; | ||
193 | + return result; | ||
194 | + } | ||
195 | + let article = result.getArticle = data && data.data || {}; | ||
196 | + let promises = [ | ||
197 | + this._getAuthor(article.author_id), | ||
198 | + this._getArticleContent(id), | ||
199 | + this._getBrand(id) | ||
200 | + ]; | ||
201 | + | ||
202 | + // 获取资讯相关的其它资讯 | ||
203 | + if (typeof article.tag !== 'undefined') { | ||
204 | + promises.push(this._getOtherArticle(id, article.tag)); | ||
205 | + } | ||
206 | + | ||
207 | + // APP 获取微信模块 | ||
208 | + if (isApp) { | ||
209 | + promises.push(this._getSingleTemplateWechat()); | ||
210 | + } | ||
211 | + | ||
212 | + if (isShare) { | ||
213 | + let navGender = _.cloneDeep(channel); | ||
214 | + | ||
215 | + promises.push( | ||
216 | + this._getLeftNav(navGender), | ||
217 | + this._getShareData(id) | ||
218 | + ); | ||
219 | + } | ||
220 | + | ||
221 | + return Promise.all(promises).then(datas => { | ||
222 | + let getArticleContent = []; | ||
223 | + | ||
224 | + if (!datas) { | ||
225 | + return result; | ||
226 | + } | ||
227 | + | ||
228 | + if (datas[1]) { | ||
229 | + result.getArticleContent = getArticleContent = datas[1].data; | ||
230 | + } | ||
231 | + | ||
232 | + if (isApp && datas[4] && datas[4].data) { | ||
233 | + let preCount = 0; | ||
234 | + let i; | ||
235 | + | ||
236 | + for (i = 0; i < getArticleContent.length; i++) { | ||
237 | + if (getArticleContent[i].singleImage || | ||
238 | + getArticleContent[i].text || getArticleContent[i].smallPic) { | ||
239 | + preCount++; | ||
240 | + } | ||
241 | + } | ||
242 | + | ||
243 | + _.forEach(datas[4].data, item => { | ||
244 | + item.src = helpers.image(item.src, 280, 210, 1); | ||
245 | + }); | ||
246 | + | ||
247 | + getArticleContent.splice(preCount, 0, { | ||
248 | + weixinPublic: datas[4].data | ||
249 | + }); | ||
250 | + } | ||
251 | + | ||
252 | + if (isShare && datas[5]) { | ||
253 | + if (datas[5].wechatShareImgUrl) { | ||
254 | + datas[5].wechatShareImgUrl = | ||
255 | + datas[5].wechatShareImgUrl.substring(datas[5].wechatShareImgUrl.indexOf('//')); | ||
256 | + | ||
257 | + if (datas[5].wechatShareImgUrl.indexOf('?') === -1) { | ||
258 | + datas[5].wechatShareImgUrl = datas[5].wechatShareImgUrl + | ||
259 | + '?imageView2/2/interlace/1/q/75'; | ||
260 | + } | ||
261 | + } else if (datas[5].qqShareImgUrl) { | ||
262 | + datas[5].qqShareImgUrl = | ||
263 | + datas[5].qqShareImgUrl.substring(datas[5].qqShareImgUrl.indexOf('//')); | ||
264 | + | ||
265 | + if (datas[5].qqShareImgUrl.indexOf('?') === -1) { | ||
266 | + datas[5].qqShareImgUrl = datas[5].wechatShareImgUrl + '?imageView2/2/interlace/1/q/75'; | ||
267 | + } | ||
268 | + } else if (datas[5].showShareImgUrl) { | ||
269 | + datas[5].showShareImgUrl = | ||
270 | + datas[5].showShareImgUrl.substring(datas[5].showShareImgUrl.indexOf('//')); | ||
271 | + | ||
272 | + if (datas[5].showShareImgUrl.indexOf('?') === -1) { | ||
273 | + datas[5].showShareImgUrl = datas[5].showShareImgUrl + '?imageView2/2/interlace/1/q/75'; | ||
274 | + } | ||
275 | + } | ||
276 | + | ||
277 | + let preCount = 0; | ||
278 | + let i; | ||
279 | + | ||
280 | + for (i = 0; i < getArticleContent.length; i++) { | ||
281 | + if (getArticleContent[i].singleImage || | ||
282 | + getArticleContent[i].text || getArticleContent[i].smallPic) { | ||
283 | + preCount = i + 1; | ||
284 | + } | ||
285 | + } | ||
286 | + | ||
287 | + getArticleContent.splice(preCount, 0, { | ||
288 | + shareCode: datas[5] | ||
289 | + }); | ||
290 | + } | ||
291 | + | ||
292 | + if (datas[0]) { | ||
293 | + result.getAuthor = datas[0].data; | ||
294 | + } | ||
295 | + | ||
296 | + | ||
297 | + if (datas[2]) { | ||
298 | + result.getBrand = datas[2].data; | ||
299 | + } | ||
300 | + | ||
301 | + if (isShare && datas[4]) { | ||
302 | + result.sideNav = datas[4]; | ||
303 | + } | ||
304 | + | ||
305 | + if (datas.length === 5 && isApp || datas.length === 4 && !isApp || datas.length === 6 && isShare) { | ||
306 | + if (datas[3]) { | ||
307 | + result.getOtherArticle = datas[3].data; | ||
308 | + } | ||
309 | + } | ||
310 | + | ||
311 | + return result; | ||
312 | + }); | ||
313 | + }); | ||
314 | + } | ||
315 | + | ||
316 | + /** | ||
317 | + * [获取详情信息] | ||
318 | + * @param {[int]} id [资讯id] | ||
319 | + * @return {[object]} | ||
320 | + */ | ||
321 | + intro(id) { | ||
322 | + let param = { | ||
323 | + article_id: id, | ||
324 | + client_type: 'h5' | ||
325 | + }; | ||
326 | + | ||
327 | + return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, param, { | ||
328 | + cache: true | ||
329 | + }); | ||
330 | + } | ||
331 | + | ||
332 | + /** | ||
333 | + * [根据商品SKN获取商品的简要信息] | ||
334 | + * @param {[array]} sknString [skns] | ||
335 | + * @return {[type]} | ||
336 | + */ | ||
337 | + productInfoBySkns(sknString) { | ||
338 | + // 调用搜索接口 | ||
339 | + let param = { | ||
340 | + method: 'h5.product.batch', | ||
341 | + productSkn: sknString, | ||
342 | + order: 's_t_desc' | ||
343 | + }; | ||
344 | + | ||
345 | + return api.get('', param, { | ||
346 | + cache: true | ||
347 | + }).then(result => { | ||
348 | + return _.get(result, 'data.product_list', []); | ||
349 | + }); | ||
350 | + } | ||
351 | +} | ||
352 | + | ||
353 | +module.exports = DetailModel; |
apps/mip/router.js
0 → 100644
1 | +/** | ||
2 | + * router of sub app service | ||
3 | + * @author: xuan.chen@yoho.cn<xuan.chen@yoho.cn> | ||
4 | + * @date: 2016/11/21 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | +const router = require('express').Router(); //eslint-disable-line | ||
10 | +const cRoot = './controllers'; | ||
11 | + | ||
12 | +const rewrite = require('../../doraemon/middleware/rewrite'); | ||
13 | +const mip = require('../../doraemon/middleware/mip'); | ||
14 | +const guang = require(`${cRoot}/guang`); | ||
15 | + | ||
16 | +router.use(mip); | ||
17 | + | ||
18 | +router.get(/^\/guang\/info\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); | ||
19 | + | ||
20 | +module.exports = router; |
apps/mip/views/action/guang/detail.hbs
0 → 100644
1 | +<div class="guang-detail-c"> | ||
2 | + {{# guang}} | ||
3 | + {{# author}} | ||
4 | + <div class="editor-info" data-id={{id}}> | ||
5 | + <mip-link href="{{url}}"> | ||
6 | + <mip-img class="pic" width="45" height="45" src={{image2 avatar mode=2 q=60}}> | ||
7 | + </mip-img> | ||
8 | + <div class="name">{{name}}</div> | ||
9 | + <div class="intro">{{intro}}</div> | ||
10 | + </mip-link> | ||
11 | + </div> | ||
12 | + {{/ author}} | ||
13 | + {{# detail}} | ||
14 | + <div class="article-info"> | ||
15 | + <p class="name">{{title}}</p> | ||
16 | + <div class="view-c"> | ||
17 | + <span>日期:{{publishTime}}</span> | ||
18 | + </div> | ||
19 | + </div> | ||
20 | + <div class="guang-content clearfix"> | ||
21 | + {{# content}} | ||
22 | + {{#if text}} | ||
23 | + {{{text}}} | ||
24 | + {{/if}} | ||
25 | + {{#if bigImage}} | ||
26 | + <div class="big-pic"> | ||
27 | + {{#if isGif}} | ||
28 | + <mip-anim class="pic" width="{{width}}" height="{{height}}" src="{{image2 bigImage q=60}}"></mip-anim> | ||
29 | + {{else}} | ||
30 | + <mip-img class="pic" width="{{width}}" height="{{height}}" src="{{image2 bigImage q=60}}"></mip-img> | ||
31 | + {{/if}} | ||
32 | + {{#if tagList}} | ||
33 | + <div class="tag-list-box"> | ||
34 | + {{#each tagList}} | ||
35 | + {{#unless isApp}} | ||
36 | + <div class="label-box" data-skn="{{product_skn}}"> | ||
37 | + <div class="lable-focus"> | ||
38 | + <div class="focus-big"> | ||
39 | + <div class="focus-small"></div> | ||
40 | + </div> | ||
41 | + </div> | ||
42 | + <div class="lable-info-box{{#if isApp}} lable-infobox-borderadius{{/if}}"><mip-link href="{{href}}">{{tagName}}</mip-link></div> | ||
43 | + <div class="lable-btn add-to-cart" data-skn="{{product_skn}}"> | ||
44 | + </div> | ||
45 | + </div> | ||
46 | + {{/unless}} | ||
47 | + {{/each}} | ||
48 | + </div> | ||
49 | + {{/if}} | ||
50 | + </div> | ||
51 | + {{/if}} | ||
52 | + {{#if smallImage}} | ||
53 | + <div class="small-pic"> | ||
54 | + {{# smallImage}} | ||
55 | + {{#if isGif}} | ||
56 | + <mip-anim class="pic" width="160" height="160" src="{{image2 src q=60}}"></mip-anim> | ||
57 | + {{else}} | ||
58 | + <mip-img class="pic" width="160" height="160" src="{{image2 src q=60}}"></mip-img> | ||
59 | + {{/if}} | ||
60 | + {{/ smallImage}} | ||
61 | + </div> | ||
62 | + {{/if}} | ||
63 | + {{#if relatedReco}} | ||
64 | + <div class="related-goods clearfix"> | ||
65 | + {{#each relatedReco.goods}} | ||
66 | + {{#if url}} | ||
67 | + <div class="good-item"> | ||
68 | + <mip-link href="{{url}}"> | ||
69 | + {{#if default_images}} | ||
70 | + <div class="pic"> | ||
71 | + <mip-img class="pic-mip" width="76" height="102" src="{{image2 default_images w=152 h=204}}"> | ||
72 | + </mip-img> | ||
73 | + </div> | ||
74 | + {{/if}} | ||
75 | + <div class="info"> | ||
76 | + <p class="name">{{product_name}}</p> | ||
77 | + {{#if sales_price}} | ||
78 | + <p class="price">¥{{sales_price}}</p> | ||
79 | + {{/if}} | ||
80 | + </div> | ||
81 | + </mip-link> | ||
82 | + </div> | ||
83 | + {{/if}} | ||
84 | + {{/each}} | ||
85 | + </div> | ||
86 | + {{/if}} | ||
87 | + {{/ content}} | ||
88 | + </div> | ||
89 | + {{/ detail}} | ||
90 | + {{#detail.content}} | ||
91 | + {{#if moreLink}} | ||
92 | + <mip-link class="more-goods" href="{{moreLink}}">更多商品</mip-link> | ||
93 | + {{/if}} | ||
94 | + {{#if recommendProducts}} | ||
95 | + <div class="recommend-goods"> | ||
96 | + <div class="good-scroll"> | ||
97 | + {{#each recommendProducts}} | ||
98 | + <div class="good-item"> | ||
99 | + <mip-link href="{{href}}"> | ||
100 | + <mip-img class="pic" width="100" height="134" src="{{image2 pic_url w=152 h=204}}"> | ||
101 | + </mip-img> | ||
102 | + </mip-link> | ||
103 | + <p class="price">¥{{price}}</p> | ||
104 | + </div> | ||
105 | + {{/each}} | ||
106 | + </div> | ||
107 | + </div> | ||
108 | + {{/if}} | ||
109 | + {{/detail.content}} | ||
110 | + {{#if relatedBrand}} | ||
111 | + <div class="related-brand clearfix"> | ||
112 | + <div class="title">相关品牌</div> | ||
113 | + <div class="brand-c"> | ||
114 | + {{# relatedBrand}} | ||
115 | + <div class="brand-item"> | ||
116 | + <mip-link href="{{url}}"> | ||
117 | + <div class="pic"> | ||
118 | + <mip-img class="pic-mip" width="75" height="75" src="{{thumb}}"> | ||
119 | + </mip-img> | ||
120 | + </div> | ||
121 | + <p>{{name}}</p> | ||
122 | + </mip-link> | ||
123 | + </div> | ||
124 | + {{/ relatedBrand}} | ||
125 | + </div> | ||
126 | + </div> | ||
127 | + {{/if}} | ||
128 | + {{#if relatedInfo}} | ||
129 | + <div class="related-info"> | ||
130 | + {{# relatedInfo}} | ||
131 | + <div class="info-item"> | ||
132 | + <mip-link href="{{url}}"> | ||
133 | + <div class="pic"> | ||
134 | + <mip-img class="pic-mip" width="117" height="73" src="{{thumb}}"> | ||
135 | + </mip-img> | ||
136 | + </div> | ||
137 | + <div class="info"> | ||
138 | + <p class="title">{{title}}</p> | ||
139 | + <p class="time">{{publishTime}}</p> | ||
140 | + </div> | ||
141 | + </mip-link> | ||
142 | + </div> | ||
143 | + {{/ relatedInfo}} | ||
144 | + </div> | ||
145 | + {{/if}} | ||
146 | + {{#if relatedTag}} | ||
147 | + <div class="brand-tag"> | ||
148 | + {{# relatedTag}} | ||
149 | + <mip-link href="//guang.m.yohobuy.com/tags/index?query={{name}}" class="tag">{{name}}</mip-link> | ||
150 | + {{/ relatedTag}} | ||
151 | + </div> | ||
152 | + {{/if}} | ||
153 | + {{/ guang}} | ||
154 | +</div> |
@@ -14,6 +14,7 @@ const crypto = global.yoho.crypto; | @@ -14,6 +14,7 @@ const crypto = global.yoho.crypto; | ||
14 | const helpers = global.yoho.helpers; | 14 | const helpers = global.yoho.helpers; |
15 | const productProcess = require(`${utils}/product-process`); | 15 | const productProcess = require(`${utils}/product-process`); |
16 | const searchModel = require(`${mRoot}/search`); | 16 | const searchModel = require(`${mRoot}/search`); |
17 | +const searchProcess = require(`${utils}/search-process`); | ||
17 | 18 | ||
18 | /** | 19 | /** |
19 | * 从 useragent 获取 uid | 20 | * 从 useragent 获取 uid |
@@ -236,7 +237,7 @@ const category = (req, res, next) => { | @@ -236,7 +237,7 @@ const category = (req, res, next) => { | ||
236 | } | 237 | } |
237 | 238 | ||
238 | searchModel.getSearchData(initialData).then((firstPageGoods) => { | 239 | searchModel.getSearchData(initialData).then((firstPageGoods) => { |
239 | - res.render('search/goods-list', { | 240 | + res.render('search/goods-list', Object.assign({ |
240 | _noLazy: true, // 首屏不使用lazyload | 241 | _noLazy: true, // 首屏不使用lazyload |
241 | module: 'product', | 242 | module: 'product', |
242 | page: 'search-list', | 243 | page: 'search-list', |
@@ -252,7 +253,7 @@ const category = (req, res, next) => { | @@ -252,7 +253,7 @@ const category = (req, res, next) => { | ||
252 | localCss: true, | 253 | localCss: true, |
253 | appPath: appPath, | 254 | appPath: appPath, |
254 | introText: req.query.intro_text | 255 | introText: req.query.intro_text |
255 | - }); | 256 | + }, searchProcess.getListSeoData(req.query.gender, req.query.title || req.query.sort_name))); |
256 | }).catch(next); | 257 | }).catch(next); |
257 | }; | 258 | }; |
258 | 259 |
@@ -51,7 +51,13 @@ const newDetail = { | @@ -51,7 +51,13 @@ const newDetail = { | ||
51 | pageHeader: headerData, | 51 | pageHeader: headerData, |
52 | result: result, | 52 | result: result, |
53 | page: 'new-detail', | 53 | page: 'new-detail', |
54 | - title: result.goodsName, | 54 | + title: result.goodsName + result.sortName + '正品 | YOHO!BUY 有货', |
55 | + keywords: result.brandName + result.sortName + ',' + result.brandName + '官网专卖店,' + | ||
56 | + result.brandName + '官方授权店,' + result.brandName + '正品,' + result.brandName + '打折,' + | ||
57 | + result.brandName + '折扣店,' + | ||
58 | + result.brandName + '真品,' + result.brandName + '代购', | ||
59 | + description: `YOHO!BUY 有货-${result.brandName}官方授权店,${result.goodsName}图片、报价、介绍。` + | ||
60 | + `YOHO!BUY 有货${result.brandName}官网专卖店提供${result.brandName}正品、${result.brandName}真品、 ${result.brandName}打折、${result.brandName}代购等。`, // eslint-disable-line | ||
55 | pageFooter: true, | 61 | pageFooter: true, |
56 | localCss: true, | 62 | localCss: true, |
57 | appPath: appPath | 63 | appPath: appPath |
@@ -431,6 +431,10 @@ const shop = { | @@ -431,6 +431,10 @@ const shop = { | ||
431 | let decorators = redShopPrcs.pushGoodsInfo(decoratorsAll.decorators, goodsList); | 431 | let decorators = redShopPrcs.pushGoodsInfo(decoratorsAll.decorators, goodsList); |
432 | 432 | ||
433 | res.render('newshop/shop-reds', { | 433 | res.render('newshop/shop-reds', { |
434 | + title: shopInfo.shop_name + '|' + shopInfo.shop_name + '潮流服装服饰-Yoho!Buy有货', | ||
435 | + keywords: shopInfo.shop_name + ',' + shopInfo.shop_name + '服装服饰,' + shopInfo.shop_name + '潮流服装服饰', | ||
436 | + description: shopInfo.shop_name + '|Yoho!Buy有货' + shopInfo.shop_name + | ||
437 | + '潮流服饰官方授权店!100%品牌正品保证,支持货到付款。', | ||
434 | pageHeader: _.assign({ | 438 | pageHeader: _.assign({ |
435 | shopPage: { | 439 | shopPage: { |
436 | text: '分类', | 440 | text: '分类', |
@@ -182,7 +182,7 @@ let discountDetail = (req, res, next) => { | @@ -182,7 +182,7 @@ let discountDetail = (req, res, next) => { | ||
182 | params.renderData.pageHeader.navTitle = result.title; | 182 | params.renderData.pageHeader.navTitle = result.title; |
183 | 183 | ||
184 | // 唤起 APP 的路径 | 184 | // 唤起 APP 的路径 |
185 | - res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.discountmarketpro","params":{"id":"${id}","cover_url":"${result.activity.cover_url.split('?')[0]}","title":"${result.title}"}}`; | 185 | + res.locals.appPath = result.activity && result.activity.cover_url ? `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.discountmarketpro","params":{"id":"${id}","cover_url":"${result.activity.cover_url.split('?')[0]}","title":"${result.title}"}}` : ''; |
186 | 186 | ||
187 | res.render('sale/discount-detail', Object.assign(params.renderData, result, { | 187 | res.render('sale/discount-detail', Object.assign(params.renderData, result, { |
188 | localCss: true | 188 | localCss: true |
@@ -174,7 +174,7 @@ const index = (req, res, next) => { | @@ -174,7 +174,7 @@ const index = (req, res, next) => { | ||
174 | } | 174 | } |
175 | 175 | ||
176 | })((result) => { | 176 | })((result) => { |
177 | - res.render('search/index', { | 177 | + res.render('search/index', Object.assign({ |
178 | module: 'product', | 178 | module: 'product', |
179 | page: 'search-index', | 179 | page: 'search-index', |
180 | pageHeader: headerModel.setNav({ | 180 | pageHeader: headerModel.setNav({ |
@@ -190,7 +190,7 @@ const index = (req, res, next) => { | @@ -190,7 +190,7 @@ const index = (req, res, next) => { | ||
190 | wantTerms: result.guessTerms | 190 | wantTerms: result.guessTerms |
191 | } | 191 | } |
192 | 192 | ||
193 | - }); | 193 | + }, searchProcess.getListSeoData())); |
194 | }); | 194 | }); |
195 | }; | 195 | }; |
196 | 196 |
@@ -132,6 +132,8 @@ const tool = { | @@ -132,6 +132,8 @@ const tool = { | ||
132 | 132 | ||
133 | // 底部简介URL链接 | 133 | // 底部简介URL链接 |
134 | dest.introUrl = '/product/detail/intro/' + origin.product_skn; | 134 | dest.introUrl = '/product/detail/intro/' + origin.product_skn; |
135 | + dest.brandName = _.get(origin, 'brand_info.brand_name', ''); | ||
136 | + dest.sortName = _.get(origin, 'middle_sort_name', ''); | ||
135 | 137 | ||
136 | return dest; | 138 | return dest; |
137 | }, | 139 | }, |
@@ -30,4 +30,7 @@ module.exports = app => { | @@ -30,4 +30,7 @@ module.exports = app => { | ||
30 | 30 | ||
31 | // 用户服务: 在线客服 | 31 | // 用户服务: 在线客服 |
32 | app.use('/service', require('./apps/service')); | 32 | app.use('/service', require('./apps/service')); |
33 | + | ||
34 | + // MIP | ||
35 | + app.use('/mip', require('./apps/mip')); | ||
33 | }; | 36 | }; |
doraemon/middleware/mip.js
0 → 100644
@@ -25,56 +25,66 @@ const seoMap = { | @@ -25,56 +25,66 @@ const seoMap = { | ||
25 | keywords: '创意生活,创意生活馆,潮流家居,潮流创意家居,家居生活用品,Yoho!Buy有货', | 25 | keywords: '创意生活,创意生活馆,潮流家居,潮流创意家居,家居生活用品,Yoho!Buy有货', |
26 | description: 'Yoho!BUY有货官网创意生活频道提供了潮流创意家居,家居生活用品等正品网购,给您的生活带来更多创意。' | 26 | description: 'Yoho!BUY有货官网创意生活频道提供了潮流创意家居,家居生活用品等正品网购,给您的生活带来更多创意。' |
27 | }, | 27 | }, |
28 | - '/product/sale?channel=boys': { | 28 | + '/product/boys-sale/': { |
29 | title: '折扣男装专区|男装SALE折扣,男款鞋包配饰特卖|Yoho!Buy有货 100%正品保证', | 29 | title: '折扣男装专区|男装SALE折扣,男款鞋包配饰特卖|Yoho!Buy有货 100%正品保证', |
30 | keywords: 'SALE,男装SALE,男装折扣,男款鞋包配饰特卖', | 30 | keywords: 'SALE,男装SALE,男装折扣,男款鞋包配饰特卖', |
31 | description: 'Yoho!Buy有货SALE频道提供男装折扣,精致品牌男装sale,限时特惠。Yoho!Buy有货男装折扣,100%正品保证!' | 31 | description: 'Yoho!Buy有货SALE频道提供男装折扣,精致品牌男装sale,限时特惠。Yoho!Buy有货男装折扣,100%正品保证!' |
32 | }, | 32 | }, |
33 | - '/product/sale?gender=2,3': { | 33 | + '/product/girls-sale/': { |
34 | title: '折扣女装专区|女装SALE折扣,女款鞋包配饰特卖|Yoho!Buy有货', | 34 | title: '折扣女装专区|女装SALE折扣,女款鞋包配饰特卖|Yoho!Buy有货', |
35 | keywords: 'SALE,女装SALE,女装折扣,女款鞋包配饰特卖', | 35 | keywords: 'SALE,女装SALE,女装折扣,女款鞋包配饰特卖', |
36 | description: 'Yoho!Buy有货SALE频道提供女装折扣,精致品牌女装sale,限时特惠。Yoho!Buy有货女装折扣,100%正品保证!' | 36 | description: 'Yoho!Buy有货SALE频道提供女装折扣,精致品牌女装sale,限时特惠。Yoho!Buy有货女装折扣,100%正品保证!' |
37 | }, | 37 | }, |
38 | - '/product/new?gender=1,3': { | 38 | + '/product/kids-sale/': { |
39 | + title: 'SALE|童装SALE,童装折扣,潮童鞋包配饰特卖|YOHO!BUY有货', | ||
40 | + keywords: 'SALE,童装SALE,童装折扣,潮童鞋包配饰特卖', | ||
41 | + description: 'YOHO!BUY有货SALE频道提供童装折扣,精致品牌童装sale,童装,针织衫,外套 卫衣,夹克,棉衣,裤子,品牌童鞋,潮童鞋包配饰等限时特惠。YOHO!BUY有货潮童折扣,100%正品保证!' | ||
42 | + }, | ||
43 | + '/product/lifestyle-sale/': { | ||
44 | + title: 'SALE|家居生活用品SALE,生活用品折扣,数码家居特卖YOHO!BUY有货', | ||
45 | + keywords: 'SALE,家居生活用品SALE,生活用品折扣,数码家居特卖', | ||
46 | + description: 'YOHO!BUY有货SALE频道提供生活用品折扣,数码家居特卖,数码3c,居家,玩具娱乐,文具,美妆等限时特惠。YOHO!BUY有货家居生活用品SALE,,100%正品保证! ' | ||
47 | + }, | ||
48 | + '/product/boys-new/': { | ||
39 | title: '男生潮装新品|男装新品发布,饰品推荐|Yoho!Buy有货 ', | 49 | title: '男生潮装新品|男装新品发布,饰品推荐|Yoho!Buy有货 ', |
40 | keywords: '男生潮装新品,新品发布,新品男装,新款男装推荐,新款男鞋推荐,新款男包推荐,新款男饰品推荐,Yoho!Buy有货', | 50 | keywords: '男生潮装新品,新品发布,新品男装,新款男装推荐,新款男鞋推荐,新款男包推荐,新款男饰品推荐,Yoho!Buy有货', |
41 | description: 'Yoho!Buy有货男装新品到着为您提供新品男装,男装新品直达就选Yoho!Buy有货,100%正品保证!' | 51 | description: 'Yoho!Buy有货男装新品到着为您提供新品男装,男装新品直达就选Yoho!Buy有货,100%正品保证!' |
42 | }, | 52 | }, |
43 | - '/product/new?gender=2,3': { | 53 | + '/product/girls-new/': { |
44 | title: '女生潮装新品|女装新品发布,饰品推荐|Yoho!Buy有货 ', | 54 | title: '女生潮装新品|女装新品发布,饰品推荐|Yoho!Buy有货 ', |
45 | keywords: '女生潮流新品,女款新品发布,新品女装,新款女装推荐,新款女鞋推荐,新款女包推荐,新款饰品推荐,Yoho!Buy有货', | 55 | keywords: '女生潮流新品,女款新品发布,新品女装,新款女装推荐,新款女鞋推荐,新款女包推荐,新款饰品推荐,Yoho!Buy有货', |
46 | description: 'Yoho!Buy有货女装新品到着为您提供新品女装,女装样品,女装新款推荐;汇集国内外最新款女装,鞋,女包,饰品,100%正品保证!' | 56 | description: 'Yoho!Buy有货女装新品到着为您提供新品女装,女装样品,女装新款推荐;汇集国内外最新款女装,鞋,女包,饰品,100%正品保证!' |
47 | }, | 57 | }, |
48 | - '/product/new?msort=365&channel=4': { | 58 | + '/product/kids-new/': { |
49 | title: '新品到着|潮童新品发布,新款童装童鞋,包包配饰推荐|Yoho!Buy有货', | 59 | title: '新品到着|潮童新品发布,新款童装童鞋,包包配饰推荐|Yoho!Buy有货', |
50 | keywords: '潮童新品发布,新品童装,新款童装推荐,新款童鞋,新款儿童鞋包,儿童配饰新品,Yoho!Buy有货', | 60 | keywords: '潮童新品发布,新品童装,新款童装推荐,新款童鞋,新款儿童鞋包,儿童配饰新品,Yoho!Buy有货', |
51 | description: 'Yoho!Buy有货潮童新品到着为您提供新品童装,童装样品,童装新款推荐;汇集国内外最新款童装,童鞋,儿童鞋包配饰。' | 61 | description: 'Yoho!Buy有货潮童新品到着为您提供新品童装,童装样品,童装新款推荐;汇集国内外最新款童装,童鞋,儿童鞋包配饰。' |
52 | }, | 62 | }, |
53 | - '/product/new?msort=10&channel=4': { | 63 | + '/product/lifestyle-new/': { |
54 | title: '新品到着|数码3c,居家,玩具娱乐,文具,美妆|Yoho!Buy有货', | 64 | title: '新品到着|数码3c,居家,玩具娱乐,文具,美妆|Yoho!Buy有货', |
55 | keywords: '数码3c,居家,玩具娱乐,文具,美妆,Yoho!Buy有货', | 65 | keywords: '数码3c,居家,玩具娱乐,文具,美妆,Yoho!Buy有货', |
56 | description: 'Yoho!Buy有货创意生活新品到着为您提供潮流创意生活,汇集国内外最新款数码3c,居家,玩具娱乐,文具,美妆。' | 66 | description: 'Yoho!Buy有货创意生活新品到着为您提供潮流创意生活,汇集国内外最新款数码3c,居家,玩具娱乐,文具,美妆。' |
57 | }, | 67 | }, |
58 | - '/brands?channel=1': { | 68 | + '/boys-brands/': { |
59 | title: '潮流男装品牌|男装品牌排行榜,男装品牌大全|Yoho!Buy有货', | 69 | title: '潮流男装品牌|男装品牌排行榜,男装品牌大全|Yoho!Buy有货', |
60 | keywords: '潮流男装品牌,男装品牌,男装品牌排行榜,男装品牌大全,Yoho!Buy有货', | 70 | keywords: '潮流男装品牌,男装品牌,男装品牌排行榜,男装品牌大全,Yoho!Buy有货', |
61 | description: 'Yoho!Buy有货男装品牌一览汇集国内国际各大男装品牌大全,为广大爱好时尚的男士青年提供品牌男装、休闲男装、商务男装.Yoho!Buy有货,100%正品保证' | 71 | description: 'Yoho!Buy有货男装品牌一览汇集国内国际各大男装品牌大全,为广大爱好时尚的男士青年提供品牌男装、休闲男装、商务男装.Yoho!Buy有货,100%正品保证' |
62 | }, | 72 | }, |
63 | - '/brands?channel=2': { | 73 | + '/girls-brands/': { |
64 | title: '潮流女装品牌|女装品牌排行榜,女装品牌大全|Yoho!Buy有货', | 74 | title: '潮流女装品牌|女装品牌排行榜,女装品牌大全|Yoho!Buy有货', |
65 | keywords: '潮流女装品牌,女装品牌,女装品牌排行榜,女装品牌大全,Yoho!Buy有货', | 75 | keywords: '潮流女装品牌,女装品牌,女装品牌排行榜,女装品牌大全,Yoho!Buy有货', |
66 | description: 'Yoho!Buy有货女装品牌一览汇集各大女装品牌,提供品牌女装、休闲女装、商务女装.Yoho!Buy有货品牌女装100%正品保证。' | 76 | description: 'Yoho!Buy有货女装品牌一览汇集各大女装品牌,提供品牌女装、休闲女装、商务女装.Yoho!Buy有货品牌女装100%正品保证。' |
67 | }, | 77 | }, |
68 | - '/brands?channel=3': { | 78 | + '/kids-brands/': { |
69 | title: '品牌一览|童装童鞋品牌,儿童鞋包配饰排行榜大全|Yoho!Buy有货', | 79 | title: '品牌一览|童装童鞋品牌,儿童鞋包配饰排行榜大全|Yoho!Buy有货', |
70 | keywords: '童装品牌,童装童鞋排行榜,儿童鞋包配饰排行榜,潮童品牌大全,品牌一览,Yoho!Buy有货', | 80 | keywords: '童装品牌,童装童鞋排行榜,儿童鞋包配饰排行榜,潮童品牌大全,品牌一览,Yoho!Buy有货', |
71 | description: 'Yoho!Buy有货童装品牌一览汇集国内国际各大童装品牌大全,提供品牌童装、童鞋,儿童鞋包配饰,100%正品保证' | 81 | description: 'Yoho!Buy有货童装品牌一览汇集国内国际各大童装品牌大全,提供品牌童装、童鞋,儿童鞋包配饰,100%正品保证' |
72 | }, | 82 | }, |
73 | - '/brands?channel=4': { | 83 | + '/lifestyle-brands/': { |
74 | title: '品牌一览|数码3c,居家,玩具娱乐,文具,美妆品牌|Yoho!Buy有货', | 84 | title: '品牌一览|数码3c,居家,玩具娱乐,文具,美妆品牌|Yoho!Buy有货', |
75 | keywords: '数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌', | 85 | keywords: '数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌', |
76 | description: 'Yoho!Buy有货女装品牌一览汇集国内国际各大数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌.' | 86 | description: 'Yoho!Buy有货女装品牌一览汇集国内国际各大数码3c品牌,居家品牌,玩具娱乐品牌,文具品牌,美妆品牌.' |
77 | - }, | 87 | + } |
78 | /* eslint-enable */ | 88 | /* eslint-enable */ |
79 | }; | 89 | }; |
80 | 90 |
@@ -12,8 +12,11 @@ | @@ -12,8 +12,11 @@ | ||
12 | <meta content="email=no" name="format-detection" /> | 12 | <meta content="email=no" name="format-detection" /> |
13 | <meta name="referrer" content="always"> | 13 | <meta name="referrer" content="always"> |
14 | {{# cononical}} | 14 | {{# cononical}} |
15 | - <link rel="cononical" href="{{currentHref}}"/> | 15 | + <link rel="cononical" href="{{currentHref}}"> |
16 | {{/ cononical}} | 16 | {{/ cononical}} |
17 | + {{#if miphtml}} | ||
18 | + <link rel="miphtml" href="{{miphtml}}"> | ||
19 | + {{/if}} | ||
17 | {{#dnsPrefetch.hosts}} | 20 | {{#dnsPrefetch.hosts}} |
18 | <link rel="dns-prefetch" href="{{this}}"> | 21 | <link rel="dns-prefetch" href="{{this}}"> |
19 | {{/dnsPrefetch.hosts}} | 22 | {{/dnsPrefetch.hosts}} |
@@ -23,7 +26,7 @@ | @@ -23,7 +26,7 @@ | ||
23 | var isWechat = /micromessenger/i.test(navigator.userAgent || ''); | 26 | var isWechat = /micromessenger/i.test(navigator.userAgent || ''); |
24 | if (isWechat) { | 27 | if (isWechat) { |
25 | document.title =document.title.replace(' | Yoho!Buy有货 | 潮流购物逛不停', ''); | 28 | document.title =document.title.replace(' | Yoho!Buy有货 | 潮流购物逛不停', ''); |
26 | - (function () { if (typeof (WeixinJSBridge) == "undefined") { document.addEventListener("WeixinJSBridgeReady", function (a) { setTimeout(function () { WeixinJSBridge.invoke("setFontSizeCallback", { fontSize: 0 }, function (b) { }) }, 0) }) } else { setTimeout(function () { WeixinJSBridge.invoke("setFontSizeCallback", { fontSize: 0 }, function (a) { }) }, 0) } })(); | 29 | + (function(){function setWechatSize(){if(typeof WeixinJSBridge!=="undefined"&&WeixinJSBridge.invoke){WeixinJSBridge.invoke("setFontSizeCallback",{fontSize:0},function(){})}}if(typeof WeixinJSBridge!=="undefined"){setTimeout(setWechatSize,0)}else{document.addEventListener("WeixinJSBridgeReady",function(){setTimeout(setWechatSize,0)})};}()); |
27 | } | 30 | } |
28 | </script> | 31 | </script> |
29 | 32 |
doraemon/views/mip.hbs
0 → 100644
1 | +<!DOCTYPE html> | ||
2 | +<html mip> | ||
3 | +<head> | ||
4 | + <meta charset="utf-8"> | ||
5 | + <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> | ||
6 | + <title>{{title}} | Yoho!Buy有货 | 潮流购物逛不停</title> | ||
7 | + <link rel="stylesheet" type="text/css" href="https://mipcache.bdstatic.com/static/v1/mip.css"> | ||
8 | + <link rel="canonical" href="{{canonical}}"> | ||
9 | + <style mip-custom> | ||
10 | + .main-wrap{width: 100%;max-width: 750px;margin: 0 auto;} | ||
11 | + {{css}} | ||
12 | + {{localStyle}} | ||
13 | + </style> | ||
14 | +</head> | ||
15 | +<body> | ||
16 | +<div class="main-wrap">{{{body}}}</div> | ||
17 | +<mip-stats-baidu token="d22478778b220ee60bce74bd15d390ae" setconfig="%5B'_trackEvent'%2C%20'mip'%2C%20'{{canonical}}'%5D"></mip-stats-baidu> | ||
18 | +<script src="https://mipcache.bdstatic.com/static/v1/mip.js"></script> | ||
19 | +<script src="https://mipcache.bdstatic.com/static/v1/mip-stats-baidu/mip-stats-baidu.js"></script> | ||
20 | +<script src="https://mipcache.bdstatic.com/static/v1/mip-anim/mip-anim.js"></script> | ||
21 | +<script src="https://mipcache.bdstatic.com/static/v1/mip-link/mip-link.js"></script> | ||
22 | +<script src="https://mipcache.bdstatic.com/static/v1/mip-audio/mip-audio.js"></script> | ||
23 | +</body> | ||
24 | +</html> |
@@ -12,7 +12,7 @@ | @@ -12,7 +12,7 @@ | ||
12 | a.async = 1; | 12 | a.async = 1; |
13 | a.src = j; | 13 | a.src = j; |
14 | m.parentNode.insertBefore(a, m); | 14 | m.parentNode.insertBefore(a, m); |
15 | - }(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//cdn.yoho.cn/yas-jssdk/2.4.0/yas.js', '_yas')); | 15 | + }(window, document, 'script', (document.location.protocol === 'https:' ? 'https:' : 'http:') + '//cdn.yoho.cn/yas-jssdk/2.4.1/yas.js', '_yas')); |
16 | 16 | ||
17 | var _hmt = _hmt || []; | 17 | var _hmt = _hmt || []; |
18 | 18 | ||
@@ -56,7 +56,7 @@ | @@ -56,7 +56,7 @@ | ||
56 | uid = uid === 0 ? '' : uid; | 56 | uid = uid === 0 ? '' : uid; |
57 | window._ozuid = uid; // 暴露ozuid | 57 | window._ozuid = uid; // 暴露ozuid |
58 | if (window._yas) { | 58 | if (window._yas) { |
59 | - window._yas(1 * new Date(), '2.4.0', 'yohobuy_m', uid, '', ''); | 59 | + window._yas(1 * new Date(), '2.4.1', 'yohobuy_m', uid, '', ''); |
60 | } | 60 | } |
61 | 61 | ||
62 | setTimeout(function() { | 62 | setTimeout(function() { |
@@ -75,7 +75,7 @@ | @@ -75,7 +75,7 @@ | ||
75 | }, 1000); | 75 | }, 1000); |
76 | }()); | 76 | }()); |
77 | 77 | ||
78 | - /* tar add 170426 品众代码去除 */ | 78 | + {{!--/* tar add 170426 品众代码去除 */--}} |
79 | {{!--window._fxcmd = window._fxcmd || []; | 79 | {{!--window._fxcmd = window._fxcmd || []; |
80 | _fxcmd.sid = 'bb3b16fa1106a6ab8619da0095755f32'; | 80 | _fxcmd.sid = 'bb3b16fa1106a6ab8619da0095755f32'; |
81 | _fxcmd.trackAll = false; | 81 | _fxcmd.trackAll = false; |
@@ -90,7 +90,7 @@ | @@ -90,7 +90,7 @@ | ||
90 | var sc = document.getElementsByTagName('script')[0]; | 90 | var sc = document.getElementsByTagName('script')[0]; |
91 | sc.parentNode.insertBefore(_pzfx,sc); | 91 | sc.parentNode.insertBefore(_pzfx,sc); |
92 | }, 1000);--}} | 92 | }, 1000);--}} |
93 | - | 93 | + |
94 | 94 | ||
95 | </script> | 95 | </script> |
96 | 96 |
1 | { | 1 | { |
2 | "name": "m-yohobuy-node", | 2 | "name": "m-yohobuy-node", |
3 | - "version": "5.7.1", | 3 | + "version": "5.7.3", |
4 | "private": true, | 4 | "private": true, |
5 | "description": "A New Yohobuy Project With Express", | 5 | "description": "A New Yohobuy Project With Express", |
6 | "repository": { | 6 | "repository": { |
@@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
26 | "body-parser": "^1.16.1", | 26 | "body-parser": "^1.16.1", |
27 | "captchapng": "0.0.1", | 27 | "captchapng": "0.0.1", |
28 | "cheerio": "^0.22.0", | 28 | "cheerio": "^0.22.0", |
29 | + "cssnano": "^3.10.0", | ||
29 | "client-sessions": "^0.8.0", | 30 | "client-sessions": "^0.8.0", |
30 | "compression": "^1.6.2", | 31 | "compression": "^1.6.2", |
31 | "connect-memcached": "^0.2.0", | 32 | "connect-memcached": "^0.2.0", |
@@ -52,7 +53,7 @@ | @@ -52,7 +53,7 @@ | ||
52 | "xml2js": "^0.4.17", | 53 | "xml2js": "^0.4.17", |
53 | "yoho-express-session": "^2.0.0", | 54 | "yoho-express-session": "^2.0.0", |
54 | "yoho-md5": "^2.0.0", | 55 | "yoho-md5": "^2.0.0", |
55 | - "yoho-node-lib": "=0.2.25", | 56 | + "yoho-node-lib": "=0.2.27", |
56 | "yoho-zookeeper": "^1.0.8" | 57 | "yoho-zookeeper": "^1.0.8" |
57 | }, | 58 | }, |
58 | "devDependencies": { | 59 | "devDependencies": { |
@@ -62,7 +63,6 @@ | @@ -62,7 +63,6 @@ | ||
62 | "babel-polyfill": "^6.23.0", | 63 | "babel-polyfill": "^6.23.0", |
63 | "babel-preset-env": "^1.4.0", | 64 | "babel-preset-env": "^1.4.0", |
64 | "css-loader": "^0.28.1", | 65 | "css-loader": "^0.28.1", |
65 | - "cssnano": "^3.10.0", | ||
66 | "eslint": "^3.19.0", | 66 | "eslint": "^3.19.0", |
67 | "eslint-config-yoho": "^1.0.1", | 67 | "eslint-config-yoho": "^1.0.1", |
68 | "eslint-loader": "^1.7.1", | 68 | "eslint-loader": "^1.7.1", |
@@ -103,7 +103,7 @@ | @@ -103,7 +103,7 @@ | ||
103 | "yoho-fastclick": "^1.0.6", | 103 | "yoho-fastclick": "^1.0.6", |
104 | "yoho-hammer": "^2.0.7", | 104 | "yoho-hammer": "^2.0.7", |
105 | "yoho-iscroll": "^5.2.0", | 105 | "yoho-iscroll": "^5.2.0", |
106 | - "yoho-jquery": "^2.2.4", | 106 | + "yoho-jquery": "^1.12.4", |
107 | "yoho-jquery-lazyload": "^1.9.12", | 107 | "yoho-jquery-lazyload": "^1.9.12", |
108 | "yoho-jquery-qrcode": "^0.14.0", | 108 | "yoho-jquery-qrcode": "^0.14.0", |
109 | "yoho-mlellipsis": "0.0.3", | 109 | "yoho-mlellipsis": "0.0.3", |
@@ -306,7 +306,7 @@ plusstar = { | @@ -306,7 +306,7 @@ plusstar = { | ||
306 | }); | 306 | }); |
307 | }, 300); | 307 | }, 300); |
308 | }, | 308 | }, |
309 | - goodsList: function() { | 309 | + goodsList: function(reload) { |
310 | let that = this, | 310 | let that = this, |
311 | skn = []; | 311 | skn = []; |
312 | 312 | ||
@@ -319,6 +319,10 @@ plusstar = { | @@ -319,6 +319,10 @@ plusstar = { | ||
319 | return false; | 319 | return false; |
320 | } | 320 | } |
321 | 321 | ||
322 | + if (!reload) { | ||
323 | + $('.goods').append('<div class="divide">正在加载...</div>'); | ||
324 | + } | ||
325 | + | ||
322 | loading.showLoadingMask(); | 326 | loading.showLoadingMask(); |
323 | skn = that.common.productSkns.slice((that.common.page - 1) * | 327 | skn = that.common.productSkns.slice((that.common.page - 1) * |
324 | that.common.pagesize, that.common.page * that.common.pagesize); | 328 | that.common.pagesize, that.common.page * that.common.pagesize); |
@@ -356,6 +360,7 @@ plusstar = { | @@ -356,6 +360,7 @@ plusstar = { | ||
356 | PAGE_NUM: that.common.page - 1 | 360 | PAGE_NUM: that.common.page - 1 |
357 | }); | 361 | }); |
358 | 362 | ||
363 | + $('.divide').remove(); | ||
359 | $('.plusstar-resources .goods').append(data); | 364 | $('.plusstar-resources .goods').append(data); |
360 | 365 | ||
361 | $('.plusstar-resources .goods').find('img.lazy:not([src])').lazyload(); | 366 | $('.plusstar-resources .goods').find('img.lazy:not([src])').lazyload(); |
@@ -399,6 +404,8 @@ $(function() { | @@ -399,6 +404,8 @@ $(function() { | ||
399 | 404 | ||
400 | plusstar.init(); | 405 | plusstar.init(); |
401 | 406 | ||
407 | + plusstar.goodsList(true); | ||
408 | + | ||
402 | // 滚动翻页 | 409 | // 滚动翻页 |
403 | $(window).scroll(function() { | 410 | $(window).scroll(function() { |
404 | scrollFn(); | 411 | scrollFn(); |
@@ -15,13 +15,13 @@ let fCbFn, hCbFn; // 筛选和关闭的回调 | @@ -15,13 +15,13 @@ let fCbFn, hCbFn; // 筛选和关闭的回调 | ||
15 | // 隐藏筛选界面 | 15 | // 隐藏筛选界面 |
16 | function hideFilter() { | 16 | function hideFilter() { |
17 | setTimeout(function() { | 17 | setTimeout(function() { |
18 | - $filter.addClass('hide'); | 18 | + $filter && $filter.addClass('hide'); |
19 | }, 301); | 19 | }, 301); |
20 | } | 20 | } |
21 | 21 | ||
22 | // 显示筛选界面 | 22 | // 显示筛选界面 |
23 | function showFilter() { | 23 | function showFilter() { |
24 | - $filter.removeClass('hide'); | 24 | + $filter && $filter.removeClass('hide'); |
25 | } | 25 | } |
26 | 26 | ||
27 | // 一级菜单点击时背景高亮 | 27 | // 一级菜单点击时背景高亮 |
@@ -356,6 +356,10 @@ function filterInit() { | @@ -356,6 +356,10 @@ function filterInit() { | ||
356 | url: '/product/sale/filter', | 356 | url: '/product/sale/filter', |
357 | data: defaultOpt, | 357 | data: defaultOpt, |
358 | success: function(data) { | 358 | success: function(data) { |
359 | + if (data === '') { | ||
360 | + return false; | ||
361 | + } | ||
362 | + | ||
359 | $goodsContainer.append(data); | 363 | $goodsContainer.append(data); |
360 | 364 | ||
361 | // 初始化filter&注册filter回调 | 365 | // 初始化filter&注册filter回调 |
@@ -198,6 +198,15 @@ | @@ -198,6 +198,15 @@ | ||
198 | .goods { | 198 | .goods { |
199 | background-color: #fff; | 199 | background-color: #fff; |
200 | padding: 0 14px; | 200 | padding: 0 14px; |
201 | + | ||
202 | + .divide { | ||
203 | + float: left; | ||
204 | + height: 50px; | ||
205 | + width: 100%; | ||
206 | + padding: 10px 0; | ||
207 | + color: #ccc; | ||
208 | + text-align: center; | ||
209 | + } | ||
201 | } | 210 | } |
202 | } | 211 | } |
203 | 212 |
@@ -6,6 +6,7 @@ | @@ -6,6 +6,7 @@ | ||
6 | const _ = require('lodash'); | 6 | const _ = require('lodash'); |
7 | const helpers = global.yoho.helpers; | 7 | const helpers = global.yoho.helpers; |
8 | const productPrcs = require('./product-process'); | 8 | const productPrcs = require('./product-process'); |
9 | +const mipUtils = require('../apps/mip/mip-utils'); | ||
9 | 10 | ||
10 | /** | 11 | /** |
11 | * 将商品转化成以 product_skn 为键名的对象 | 12 | * 将商品转化成以 product_skn 为键名的对象 |
@@ -103,7 +104,7 @@ const formatArticle = (articleData, showTag, isApp, showAuthor, uid) => { | @@ -103,7 +104,7 @@ const formatArticle = (articleData, showTag, isApp, showAuthor, uid) => { | ||
103 | }; | 104 | }; |
104 | let originUrl = helpers.urlFormat(colparam.urlpath || '/author/index', null, 'guang'); // 跳转回的链接 | 105 | let originUrl = helpers.urlFormat(colparam.urlpath || '/author/index', null, 'guang'); // 跳转回的链接 |
105 | // 根据用户是否登录做处理的链接 | 106 | // 根据用户是否登录做处理的链接 |
106 | - let collectUrl = 'javascript:;'; // eslint-disable-line | 107 | + let collectUrl = 'javascript:;'; // eslint-disable-line |
107 | 108 | ||
108 | if (!uid) { | 109 | if (!uid) { |
109 | let playUrlEncode = `${originUrl}${colparam.param}`.replace(/\//g, '\\\/'); | 110 | let playUrlEncode = `${originUrl}${colparam.param}`.replace(/\//g, '\\\/'); |
@@ -206,16 +207,27 @@ const getProductIcon = (type) => { | @@ -206,16 +207,27 @@ const getProductIcon = (type) => { | ||
206 | /** | 207 | /** |
207 | * 逛详情页数据处理 | 208 | * 逛详情页数据处理 |
208 | */ | 209 | */ |
209 | -const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isWeibo) => { | 210 | +const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isWeibo, isMip) => { |
210 | let finalDetail = []; | 211 | let finalDetail = []; |
211 | let allgoods = ''; | 212 | let allgoods = ''; |
213 | + let localStyle = []; | ||
212 | 214 | ||
213 | _.forEach(articleContent, (value, index) => { | 215 | _.forEach(articleContent, (value, index) => { |
214 | 216 | ||
215 | // 文字 | 217 | // 文字 |
216 | if (_.get(value, 'text.data.text', false)) { | 218 | if (_.get(value, 'text.data.text', false)) { |
219 | + let newText = ''; | ||
220 | + | ||
221 | + if (isMip) { | ||
222 | + let mipHtml = mipUtils.process(value.text.data.text, index); | ||
223 | + | ||
224 | + newText = mipHtml.mipHtml; | ||
225 | + localStyle.push(mipHtml.css); | ||
226 | + } else { | ||
227 | + newText = value.text.data.text; | ||
228 | + } | ||
217 | finalDetail.push({ | 229 | finalDetail.push({ |
218 | - text: value.text.data.text | 230 | + text: newText |
219 | }); | 231 | }); |
220 | } | 232 | } |
221 | 233 | ||
@@ -235,7 +247,10 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | @@ -235,7 +247,10 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | ||
235 | finalDetail.push({ | 247 | finalDetail.push({ |
236 | bigImage: helpers.image(_.get(value, 'singleImage.data[0].src', ''), 640, 640), | 248 | bigImage: helpers.image(_.get(value, 'singleImage.data[0].src', ''), 640, 640), |
237 | noLazy: index <= 3, | 249 | noLazy: index <= 3, |
238 | - tagList: tagList | 250 | + tagList: tagList, |
251 | + isGif: /\.gif/i.test(_.get(value, 'singleImage.data[0].src', '')), | ||
252 | + width: 320, | ||
253 | + height: _.get(value, 'singleImage.data[0].height', 0) / _.get(value, 'singleImage.data[0].width', 1) * 320 // eslint-disable-line | ||
239 | }); | 254 | }); |
240 | } | 255 | } |
241 | 256 | ||
@@ -244,12 +259,14 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | @@ -244,12 +259,14 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | ||
244 | finalDetail.push({ | 259 | finalDetail.push({ |
245 | smallImage: [ | 260 | smallImage: [ |
246 | { | 261 | { |
247 | - src: helpers.image(_.get(value, 'smallPic.data[0].src', ''), 315, 420) | 262 | + src: helpers.image(_.get(value, 'smallPic.data[0].src', ''), 315, 420), |
263 | + isGif: /\.gif/i.test(_.get(value, 'smallPic.data[0].src', '')), | ||
248 | }, | 264 | }, |
249 | { | 265 | { |
250 | - src: helpers.image(_.get(value, 'smallPic.data[1].src', ''), 315, 420) | 266 | + src: helpers.image(_.get(value, 'smallPic.data[1].src', ''), 315, 420), |
267 | + isGif: /\.gif/i.test(_.get(value, 'smallPic.data[0].src', '')), | ||
251 | } | 268 | } |
252 | - ], | 269 | + ] |
253 | }); | 270 | }); |
254 | } | 271 | } |
255 | 272 | ||
@@ -296,8 +313,7 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | @@ -296,8 +313,7 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | ||
296 | finalDetail.push({ | 313 | finalDetail.push({ |
297 | relatedReco: { | 314 | relatedReco: { |
298 | isApp: isApp, | 315 | isApp: isApp, |
299 | - goods: goodsData, | ||
300 | - moreNum: goodsData.length - 2 > 0 ? goodsData.length - 2 : 0 | 316 | + goods: goodsData |
301 | } | 317 | } |
302 | }); | 318 | }); |
303 | } | 319 | } |
@@ -350,7 +366,8 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | @@ -350,7 +366,8 @@ const processArticleDetail = (articleContent, isApp, gender, isWeixin, isqq, isW | ||
350 | 366 | ||
351 | return { | 367 | return { |
352 | finalDetail: finalDetail, | 368 | finalDetail: finalDetail, |
353 | - allgoods: allgoods | 369 | + allgoods: allgoods, |
370 | + css: localStyle.join('') | ||
354 | }; | 371 | }; |
355 | }; | 372 | }; |
356 | 373 | ||
@@ -362,9 +379,26 @@ const pushGoodsInfo = (finalDetail, goodsList, isApp) => { | @@ -362,9 +379,26 @@ const pushGoodsInfo = (finalDetail, goodsList, isApp) => { | ||
362 | 379 | ||
363 | _.forEach(finalDetail, (value, key) => { | 380 | _.forEach(finalDetail, (value, key) => { |
364 | if (value.relatedReco) { | 381 | if (value.relatedReco) { |
365 | - _.forEach(value.relatedReco.goods, (item, subKey) => { | ||
366 | - finalDetail[key].relatedReco.goods[subKey] = goodsObj[item.id]; | 382 | + let goodsIds = []; |
383 | + | ||
384 | + _.forEach(value.relatedReco.goods, relatedGoods => { | ||
385 | + goodsIds.push(relatedGoods.id); | ||
386 | + }); | ||
387 | + | ||
388 | + goodsIds = _.uniq(goodsIds); | ||
389 | + finalDetail[key].relatedReco.goods = []; | ||
390 | + | ||
391 | + _.forEach(goodsIds, (item, subKey) => { | ||
392 | + if (goodsObj[item]) { | ||
393 | + finalDetail[key].relatedReco.goods[subKey] = goodsObj[item]; | ||
394 | + } else { | ||
395 | + delete finalDetail[key].relatedReco.goods[subKey]; | ||
396 | + } | ||
367 | }); | 397 | }); |
398 | + | ||
399 | + let moreNum = _.get(finalDetail[key], 'relatedReco.goods.length', 0); | ||
400 | + | ||
401 | + finalDetail[key].relatedReco.moreNum = moreNum - 2 > 0 ? moreNum - 2 : 0; | ||
368 | } | 402 | } |
369 | 403 | ||
370 | if (value.collocation) { | 404 | if (value.collocation) { |
@@ -143,6 +143,24 @@ module.exports = { | @@ -143,6 +143,24 @@ module.exports = { | ||
143 | return ''; | 143 | return ''; |
144 | } | 144 | } |
145 | }, | 145 | }, |
146 | + | ||
147 | + /** | ||
148 | + * 图片质量调整 | ||
149 | + */ | ||
150 | + imageslim: function(imageUrl) { | ||
151 | + if (imageUrl && _.isString(imageUrl)) { | ||
152 | + let urls = imageUrl.split('?'); | ||
153 | + let uri = urls[0]; | ||
154 | + | ||
155 | + if (uri.indexOf('http:') === 0) { | ||
156 | + uri = uri.replace('http:', ''); | ||
157 | + } | ||
158 | + | ||
159 | + return uri + '?imageslim'; | ||
160 | + } else { | ||
161 | + return ''; | ||
162 | + } | ||
163 | + }, | ||
146 | isEqualOr: function() { | 164 | isEqualOr: function() { |
147 | let args = Array.prototype.slice.call(arguments); | 165 | let args = Array.prototype.slice.call(arguments); |
148 | let v1 = args[0]; | 166 | let v1 = args[0]; |
@@ -4,6 +4,12 @@ | @@ -4,6 +4,12 @@ | ||
4 | * @date: 2016/7/29 | 4 | * @date: 2016/7/29 |
5 | */ | 5 | */ |
6 | 6 | ||
7 | +const _getGender = { | ||
8 | + '1,3': '男生', | ||
9 | + '2,3': '女生', | ||
10 | + '1,2,3': '', | ||
11 | +}; | ||
12 | + | ||
7 | /** | 13 | /** |
8 | * 根据频道判断出性别 | 14 | * 根据频道判断出性别 |
9 | */ | 15 | */ |
@@ -66,8 +72,31 @@ const getTypeCont = (type, order) => { | @@ -66,8 +72,31 @@ const getTypeCont = (type, order) => { | ||
66 | } | 72 | } |
67 | }; | 73 | }; |
68 | 74 | ||
75 | +/** | ||
76 | + * 品类列表页 SEO 数据 | ||
77 | + * @param {*} gender | ||
78 | + * @param {*} sort_name | ||
79 | + */ | ||
80 | +const getListSeoData = (gender, sort_name) => { | ||
81 | + let seoData = { | ||
82 | + title: '潮流服装配饰,创意生活用品_男生|女生|潮童服装,鞋履,配饰品牌正品-YOHO!BUY有货', | ||
83 | + keywords: '潮流服装配饰,创意生活用品,男生服装配饰,女生服装配饰,潮童服装配饰', | ||
84 | + description: '潮流服装配饰及创意生活正品网购!YOHO!BUY有货提供男生、女生、潮童服装配饰。100%品牌正品保证,支持货到付款。' | ||
85 | + }; | ||
86 | + | ||
87 | + if (gender && sort_name) { | ||
88 | + seoData = { | ||
89 | + title: `${sort_name}|新款${sort_name}${_getGender[gender]}|品牌正品|YOHO!BUY有货`, | ||
90 | + keywords: `新款${sort_name},${_getGender[gender]}${sort_name},品牌正品`, | ||
91 | + description: `正品网购!YOHO!BUY有货提供新款${sort_name}${_getGender[gender]}${sort_name}100%品牌正品保证,支持货到付款。` | ||
92 | + }; | ||
93 | + } | ||
94 | + return seoData; | ||
95 | +}; | ||
96 | + | ||
69 | module.exports = { | 97 | module.exports = { |
70 | getGenderByChannel, | 98 | getGenderByChannel, |
71 | getChannelType, | 99 | getChannelType, |
72 | - getTypeCont | 100 | + getTypeCont, |
101 | + getListSeoData | ||
73 | }; | 102 | }; |
-
Please register or login to post a comment