Showing
8 changed files
with
264 additions
and
146 deletions
apps/mip/controllers/list.js
0 → 100644
1 | +'use strict'; | ||
2 | +const css = require('../css'); | ||
3 | +const _ = require('lodash'); | ||
4 | +const co = require('bluebird').coroutine; | ||
5 | +const mRoot = '../models'; | ||
6 | +const utils = '../../../utils'; | ||
7 | +const productProcess = require(`${utils}/product-process`); | ||
8 | +const searchProcess = require(`${utils}/search-process`); | ||
9 | +const stringProcess = require(`${utils}/string-process`); | ||
10 | +const redis = require(`${utils}/redis`); | ||
11 | +const logger = global.yoho.logger; | ||
12 | +const listModel = require(`${mRoot}/list`); | ||
13 | +const camelCase = global.yoho.camelCase; | ||
14 | + | ||
15 | +/** | ||
16 | + * 封面图 | ||
17 | + * @type {{boys: string, gilrs: string}} | ||
18 | + */ | ||
19 | +const _coverChannel = { | ||
20 | + boys: '1,3', | ||
21 | + gilrs: '2,3' | ||
22 | +}; | ||
23 | + | ||
24 | +const index = (req, res, next) => { | ||
25 | + let params = _.assign({}, req.query); | ||
26 | + let uid = req.user.uid; | ||
27 | + | ||
28 | + // 获取第一页数据做服务端渲染 | ||
29 | + let initialData = _.assign({ | ||
30 | + gender: params.gender, | ||
31 | + type: 'default', | ||
32 | + order: '0', | ||
33 | + page: 1, | ||
34 | + limit: 24, | ||
35 | + isApp: params.app_version | ||
36 | + }, params); | ||
37 | + | ||
38 | + if (uid) { | ||
39 | + initialData.uid = uid; | ||
40 | + } | ||
41 | + | ||
42 | + co(function* () { | ||
43 | + let result = yield req.ctx(listModel).getCategoryGoods(initialData); | ||
44 | + let categoryIntroRedis = []; | ||
45 | + let responseResult = { | ||
46 | + list: productProcess.processProductList(_.get(result, 'data.product_list', []), { | ||
47 | + isApp: params.isApp || (params.appVersion && params.appVersion !== 'false'), | ||
48 | + gender: _coverChannel[params.coverChannel], | ||
49 | + showSimilar: params.shop_id || params.material === 'true' ? false : true | ||
50 | + }) | ||
51 | + }; | ||
52 | + let seoParams = searchProcess.getFilterValueForSeo(initialData, _.get(result, 'data', {})); | ||
53 | + let seoRenderData = searchProcess.getListSeoData(seoParams); | ||
54 | + let seoTitle = _.get(seoParams, 'sort'); | ||
55 | + let paramsTitle = params.title || params.sort_name; // 可能会配置的标题,优先级最高 | ||
56 | + | ||
57 | + if (paramsTitle) { | ||
58 | + seoTitle = stringProcess.decodeURIComponent(paramsTitle); | ||
59 | + } | ||
60 | + | ||
61 | + if (seoTitle) { | ||
62 | + try { | ||
63 | + categoryIntroRedis = | ||
64 | + yield redis.hmgetAsync(`category:description:${md5(seoTitle)}`, 'category', 'description').timeout(200); // eslint-disable-line | ||
65 | + } catch (e) { | ||
66 | + logger.warn(`redis.hmgetAsync error, key is category:description:md5(${seoTitle})`); | ||
67 | + } | ||
68 | + } | ||
69 | + | ||
70 | + let categoryIntro = categoryIntroRedis[1] ? { | ||
71 | + title: categoryIntroRedis[0], | ||
72 | + desc: categoryIntroRedis[1] | ||
73 | + } : null; | ||
74 | + | ||
75 | + // 唤起 APP 的路径 | ||
76 | + res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.list","params":${JSON.stringify(params)}}`; | ||
77 | + | ||
78 | + res.render('list', Object.assign({ | ||
79 | + css: yield css('chanpin.css'), | ||
80 | + commonCss: yield css('common.css'), | ||
81 | + title: seoRenderData.title || '商品列表', | ||
82 | + mipFooter: true, | ||
83 | + canonical: { | ||
84 | + currentHref: `https://www.yohobuy.com${req.url}` | ||
85 | + }, | ||
86 | + pageTitle: seoTitle || '商品列表', | ||
87 | + }, camelCase(responseResult))); | ||
88 | + })().catch(next); | ||
89 | +} | ||
90 | + | ||
91 | +module.exports = { | ||
92 | + index | ||
93 | +} |
@@ -270,71 +270,4 @@ | @@ -270,71 +270,4 @@ | ||
270 | border: 1px solid #bbb; | 270 | border: 1px solid #bbb; |
271 | margin-right: 6px; | 271 | margin-right: 6px; |
272 | margin-top: 5px; | 272 | margin-top: 5px; |
273 | -} | ||
274 | - | ||
275 | -/* 底部开始 */ | ||
276 | -.mip-footer-fixed { | ||
277 | - width: 100%; | ||
278 | - height: 95px; | ||
279 | - position: relative; | ||
280 | - clear: both; | ||
281 | -} | ||
282 | - | ||
283 | -.mip-footer { | ||
284 | - max-width: 750px; | ||
285 | - margin: 0 auto; | ||
286 | - background-color: #fff; | ||
287 | - height: 95px; | ||
288 | - width: 100%; | ||
289 | - clear: both; | ||
290 | - position: fixed; | ||
291 | - bottom: 0; | ||
292 | - left: 0; | ||
293 | - right: 0; | ||
294 | -} | ||
295 | - | ||
296 | -.mip-footer .option { | ||
297 | - background-color: #fff; | ||
298 | - font-size: 0; | ||
299 | -} | ||
300 | - | ||
301 | -.mip-footer .option a { | ||
302 | - line-height: 50px; | ||
303 | - font-size: 13px; | ||
304 | - padding: 0 5%; | ||
305 | -} | ||
306 | - | ||
307 | -.mip-footer .option .login { | ||
308 | - border-right: solid 1px #e0e0e0; | ||
309 | -} | ||
310 | - | ||
311 | -.mip-footer .option .back-to-top { | ||
312 | - line-height: 50px; | ||
313 | - font-size: 13px; | ||
314 | - padding: 0 5%; | ||
315 | - float: right; | ||
316 | -} | ||
317 | - | ||
318 | -.mip-footer .option .back-to-top span { | ||
319 | - font-weight: bold; | ||
320 | - margin-left: 5px; | ||
321 | - transform: scaleY(0.5); | ||
322 | -} | ||
323 | - | ||
324 | -.mip-footer .copy-right { | ||
325 | - background-color: #eee; | ||
326 | - color: #666; | ||
327 | - text-align: center; | ||
328 | - line-height: 45px; | ||
329 | - font-size: 13px; | ||
330 | -} | ||
331 | - | ||
332 | -.mip-footer .mip-fixed { | ||
333 | - position: relative !important; | ||
334 | - z-index: 0 !important; | ||
335 | -} | ||
336 | - | ||
337 | -.mip-footer .mip-gototop { | ||
338 | - display: inline !important; | ||
339 | -} | ||
340 | -/* 底部结束 */ | 273 | +} |
@@ -313,4 +313,71 @@ | @@ -313,4 +313,71 @@ | ||
313 | 313 | ||
314 | .mip-appdl-downbtn { | 314 | .mip-appdl-downbtn { |
315 | top: 15px !important; | 315 | top: 15px !important; |
316 | -} | ||
316 | +} | ||
317 | + | ||
318 | +/* 底部开始 */ | ||
319 | +.mip-footer-fixed { | ||
320 | + width: 100%; | ||
321 | + height: 95px; | ||
322 | + position: relative; | ||
323 | + clear: both; | ||
324 | +} | ||
325 | + | ||
326 | +.mip-footer { | ||
327 | + max-width: 750px; | ||
328 | + margin: 0 auto; | ||
329 | + background-color: #fff; | ||
330 | + height: 95px; | ||
331 | + width: 100%; | ||
332 | + clear: both; | ||
333 | + position: fixed; | ||
334 | + bottom: 0; | ||
335 | + left: 0; | ||
336 | + right: 0; | ||
337 | +} | ||
338 | + | ||
339 | +.mip-footer .option { | ||
340 | + background-color: #fff; | ||
341 | + font-size: 0; | ||
342 | +} | ||
343 | + | ||
344 | +.mip-footer .option a { | ||
345 | + line-height: 50px; | ||
346 | + font-size: 13px; | ||
347 | + padding: 0 5%; | ||
348 | +} | ||
349 | + | ||
350 | +.mip-footer .option .login { | ||
351 | + border-right: solid 1px #e0e0e0; | ||
352 | +} | ||
353 | + | ||
354 | +.mip-footer .option .back-to-top { | ||
355 | + line-height: 50px; | ||
356 | + font-size: 13px; | ||
357 | + padding: 0 5%; | ||
358 | + float: right; | ||
359 | +} | ||
360 | + | ||
361 | +.mip-footer .option .back-to-top span { | ||
362 | + font-weight: bold; | ||
363 | + margin-left: 5px; | ||
364 | + transform: scaleY(0.5); | ||
365 | +} | ||
366 | + | ||
367 | +.mip-footer .copy-right { | ||
368 | + background-color: #eee; | ||
369 | + color: #666; | ||
370 | + text-align: center; | ||
371 | + line-height: 45px; | ||
372 | + font-size: 13px; | ||
373 | +} | ||
374 | + | ||
375 | +.mip-footer .mip-fixed { | ||
376 | + position: relative !important; | ||
377 | + z-index: 0 !important; | ||
378 | +} | ||
379 | + | ||
380 | +.mip-footer .mip-gototop { | ||
381 | + display: inline !important; | ||
382 | +} | ||
383 | +/* 底部结束 */ |
@@ -947,71 +947,4 @@ | @@ -947,71 +947,4 @@ | ||
947 | .mip-footer { | 947 | .mip-footer { |
948 | bottom: 60px !important; | 948 | bottom: 60px !important; |
949 | position: relative !important; | 949 | position: relative !important; |
950 | -} | ||
951 | - | ||
952 | -/* 底部开始 */ | ||
953 | -.mip-footer-fixed { | ||
954 | - width: 100%; | ||
955 | - height: 95px; | ||
956 | - position: relative; | ||
957 | - clear: both; | ||
958 | -} | ||
959 | - | ||
960 | -.mip-footer { | ||
961 | - max-width: 750px; | ||
962 | - margin: 0 auto; | ||
963 | - background-color: #fff; | ||
964 | - height: 95px; | ||
965 | - width: 100%; | ||
966 | - clear: both; | ||
967 | - position: fixed; | ||
968 | - bottom: 0; | ||
969 | - left: 0; | ||
970 | - right: 0; | ||
971 | -} | ||
972 | - | ||
973 | -.mip-footer .option { | ||
974 | - background-color: #fff; | ||
975 | - font-size: 0; | ||
976 | -} | ||
977 | - | ||
978 | -.mip-footer .option a { | ||
979 | - line-height: 50px; | ||
980 | - font-size: 13px; | ||
981 | - padding: 0 5%; | ||
982 | -} | ||
983 | - | ||
984 | -.mip-footer .option .login { | ||
985 | - border-right: solid 1px #e0e0e0; | ||
986 | -} | ||
987 | - | ||
988 | -.mip-footer .option .back-to-top { | ||
989 | - line-height: 50px; | ||
990 | - font-size: 13px; | ||
991 | - padding: 0 5%; | ||
992 | - float: right; | ||
993 | -} | ||
994 | - | ||
995 | -.mip-footer .option .back-to-top span { | ||
996 | - font-weight: bold; | ||
997 | - margin-left: 5px; | ||
998 | - transform: scaleY(0.5); | ||
999 | -} | ||
1000 | - | ||
1001 | -.mip-footer .copy-right { | ||
1002 | - background-color: #eee; | ||
1003 | - color: #666; | ||
1004 | - text-align: center; | ||
1005 | - line-height: 45px; | ||
1006 | - font-size: 13px; | ||
1007 | -} | ||
1008 | - | ||
1009 | -.mip-footer .mip-fixed { | ||
1010 | - position: relative !important; | ||
1011 | - z-index: 0 !important; | ||
1012 | -} | ||
1013 | - | ||
1014 | -.mip-footer .mip-gototop { | ||
1015 | - display: inline !important; | ||
1016 | -} | ||
1017 | -/* 底部结束 */ | ||
950 | +} |
apps/mip/models/list.js
0 → 100644
1 | +/** | ||
2 | + * list model | ||
3 | + * @author: wsl<shuiling.wang@yoho.cn> | ||
4 | + * @date: 2018/08/20 | ||
5 | + */ | ||
6 | +'use strict'; | ||
7 | +const utils = '../../../utils'; | ||
8 | +// const productProcess = require(`${utils}/product-process`); | ||
9 | +const searchProcess = require(`${utils}/search-process`); | ||
10 | +const _ = require('lodash'); | ||
11 | +// const logger = global.yoho.logger; | ||
12 | +// const cache = require('memory-cache'); | ||
13 | +// const helpers = global.yoho.helpers; | ||
14 | +// const co = require('bluebird').coroutine; | ||
15 | + | ||
16 | +module.exports = class extends global.yoho.BaseModel { | ||
17 | + constructor(ctx) { | ||
18 | + super(ctx); | ||
19 | + } | ||
20 | + | ||
21 | + /** | ||
22 | + * 获取品类下的商品列表 | ||
23 | + * @param isSearch 是否是搜索列表页 | ||
24 | + * 搜索列表页默认调用 app.search.li 接口 | ||
25 | + * 类目列表页默认调用 web.search.search 接口 | ||
26 | + */ | ||
27 | + getCategoryGoods(params, isSearch) { | ||
28 | + let method = isSearch ? 'app.search.li' : 'web.search.search'; | ||
29 | + | ||
30 | + if (params.filter_poolId) { | ||
31 | + method = 'app.search.pool'; | ||
32 | + } | ||
33 | + | ||
34 | + if (params.shop_id && !params.filter_poolId && !params.productPool) { | ||
35 | + method = 'app.search.li'; | ||
36 | + } | ||
37 | + | ||
38 | + // 个人中心优惠券立即使用 - 商品列表 | ||
39 | + if (params.coupon_id || params.coupon_code) { | ||
40 | + method = 'app.search.coupon'; | ||
41 | + } | ||
42 | + | ||
43 | + // 物料商品列表增加 | ||
44 | + if (params.material === 'true') { | ||
45 | + method = 'app.search.recommendProduct'; | ||
46 | + } | ||
47 | + | ||
48 | + if (params.isblknew) { | ||
49 | + method = 'app.search.newProduct'; | ||
50 | + } | ||
51 | + | ||
52 | + if (params.promotion_id) { | ||
53 | + method = 'app.search.promotion'; | ||
54 | + } | ||
55 | + | ||
56 | + // 学生优惠 | ||
57 | + if (params.students) { | ||
58 | + method = 'app.student.discount'; | ||
59 | + } | ||
60 | + | ||
61 | + // 学生返币查询 | ||
62 | + if (params.coin) { | ||
63 | + method = 'app.student.rebate'; | ||
64 | + } | ||
65 | + | ||
66 | + // 促销活动 | ||
67 | + if (params.specialsale_id) { | ||
68 | + method = 'app.search.li'; | ||
69 | + } | ||
70 | + | ||
71 | + if (method === 'web.search.search') { | ||
72 | + params.from = 'categoryList'; | ||
73 | + } | ||
74 | + | ||
75 | + let paramsForApi = searchProcess.getSearchParamsWithoutMethod(params); | ||
76 | + | ||
77 | + return this.get({ | ||
78 | + data: _.assign({}, paramsForApi, { | ||
79 | + method: method | ||
80 | + }) | ||
81 | + }); | ||
82 | + } | ||
83 | + | ||
84 | +} |
@@ -15,6 +15,7 @@ const guang = require(`${cRoot}/guang`); | @@ -15,6 +15,7 @@ const guang = require(`${cRoot}/guang`); | ||
15 | const chanpin = require(`${cRoot}/chanpin`); | 15 | const chanpin = require(`${cRoot}/chanpin`); |
16 | const hot = require(`${cRoot}/hot`); | 16 | const hot = require(`${cRoot}/hot`); |
17 | const productDetail = require(`${cRoot}/product-detail`); | 17 | const productDetail = require(`${cRoot}/product-detail`); |
18 | +const list = require(`${cRoot}/list`); | ||
18 | 19 | ||
19 | router.use(mip); | 20 | router.use(mip); |
20 | 21 | ||
@@ -22,10 +23,12 @@ router.get(/^\/guang\/info\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); | @@ -22,10 +23,12 @@ router.get(/^\/guang\/info\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); | ||
22 | router.get(/^\/guang\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); | 23 | router.get(/^\/guang\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); |
23 | 24 | ||
24 | router.get('/chanpin/:id.html', chanpin.index); | 25 | router.get('/chanpin/:id.html', chanpin.index); |
25 | -router.get('/list/:id.html', chanpin.redirect); | 26 | + |
27 | +// router.get('/list/:id.html', chanpin.redirect); | ||
26 | 28 | ||
27 | router.get('/product/:skn.html', productDetail.index); | 29 | router.get('/product/:skn.html', productDetail.index); |
28 | 30 | ||
29 | router.get('/hot/:id.html', hot.index); | 31 | router.get('/hot/:id.html', hot.index); |
32 | +router.get('/list(/:pathParams)?', rewrite.resolvePathParams, list.index) | ||
30 | 33 | ||
31 | module.exports = router; | 34 | module.exports = router; |
apps/mip/views/action/list.hbs
0 → 100644
@@ -13,10 +13,10 @@ const isTest = process.env.NODE_ENV === 'test'; | @@ -13,10 +13,10 @@ const isTest = process.env.NODE_ENV === 'test'; | ||
13 | 13 | ||
14 | const domains = { | 14 | const domains = { |
15 | 15 | ||
16 | - api: 'http://api.yoho.cn/', | ||
17 | - service: 'http://service.yoho.cn/', | ||
18 | - liveApi: 'http://testapi.live.yohops.com:9999/', | ||
19 | - singleApi: 'http://api-test3.yohops.com:9999/', | 16 | + // api: 'http://api.yoho.cn/', |
17 | + // service: 'http://service.yoho.cn/', | ||
18 | + // liveApi: 'http://testapi.live.yohops.com:9999/', | ||
19 | + // singleApi: 'http://api-test3.yohops.com:9999/', | ||
20 | 20 | ||
21 | // gray | 21 | // gray |
22 | // api: 'http://apigray.yoho.cn/', | 22 | // api: 'http://apigray.yoho.cn/', |
@@ -24,10 +24,10 @@ const domains = { | @@ -24,10 +24,10 @@ const domains = { | ||
24 | 24 | ||
25 | // platformApi: 'http://172.16.6.210:8088/', | 25 | // platformApi: 'http://172.16.6.210:8088/', |
26 | 26 | ||
27 | - // api: 'http://api-test3.dev.yohocorp.com/', | ||
28 | - // service: 'http://api-test3.dev.yohocorp.com/', | ||
29 | - // liveApi: 'http://testapi.live.yohops.com:9999/', | ||
30 | - // singleApi: 'http://api-test3.dev.yohocorp.com/', | 27 | + api: 'http://api-test3.dev.yohocorp.com/', |
28 | + service: 'http://api-test3.dev.yohocorp.com/', | ||
29 | + liveApi: 'http://testapi.live.yohops.com:9999/', | ||
30 | + singleApi: 'http://api-test3.dev.yohocorp.com/', | ||
31 | 31 | ||
32 | imSocket: 'ws://socket.yohobuy.com:10240', | 32 | imSocket: 'ws://socket.yohobuy.com:10240', |
33 | imCs: 'http://im.yohobuy.com/api', | 33 | imCs: 'http://im.yohobuy.com/api', |
-
Please register or login to post a comment