From 9b707d80a5a7ecf3952efeeb36ed2dc2aca68abc Mon Sep 17 00:00:00 2001 From: 李靖 <lijing@lijingdeMacBook-Pro.local> Date: Wed, 13 Dec 2017 13:38:50 +0800 Subject: [PATCH] 开发完成 --- apps/mip/controllers/list.js | 34 ++++++++++++++++++++++++++++++++++ apps/mip/css/list.css | 304 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/mip/models/list.js | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/mip/router.js | 3 +++ apps/mip/views/action/list.hbs | 4 ++++ apps/mip/views/partial/list.hbs | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ apps/mip/views/partial/mip-footer.hbs | 14 ++++++++++++++ doraemon/views/mip.hbs | 1 + 8 files changed, 520 insertions(+), 0 deletions(-) create mode 100644 apps/mip/controllers/list.js create mode 100644 apps/mip/css/list.css create mode 100644 apps/mip/models/list.js create mode 100644 apps/mip/views/action/list.hbs create mode 100644 apps/mip/views/partial/list.hbs create mode 100644 apps/mip/views/partial/mip-footer.hbs diff --git a/apps/mip/controllers/list.js b/apps/mip/controllers/list.js new file mode 100644 index 0000000..7e27269 --- /dev/null +++ b/apps/mip/controllers/list.js @@ -0,0 +1,34 @@ +'use strict'; + +const css = require('../css'); +const mRoot = '../models'; +const listModel = require(`${mRoot}/list`); +const co = require('bluebird').coroutine; + +exports.index = (req, res, next) => { + co(function* () { + let params = { + page: 1, + limit: 40, + sales: 'Y', + outlets: 2, + stocknumber: 1, + need_filter: 'no', + type: 'default', + order: 's_t_desc', + id: req.params.id + }; + + let list = yield req.ctx(listModel).index(params); + let goodsList = { + name: list.name || '', + list: list.list, + fuzzyWord: list.fuzzyWord + }; + + return res.render('list', Object.assign({ + css: yield css('list.css'), + title: `${goodsList.name}价格_图片_品牌_怎么样-YOHO!BUY有货`, + }, goodsList)); + })().catch(next); +}; diff --git a/apps/mip/css/list.css b/apps/mip/css/list.css new file mode 100644 index 0000000..361d616 --- /dev/null +++ b/apps/mip/css/list.css @@ -0,0 +1,304 @@ +.good-info { + float: left; + box-sizing: border-box; + -webkit-box-sizing: border-box; + width: 44%; + margin-left: 4%; +} + +.good-detail-img { + position: relative; + width: 100%; +} + +.good-detail-img img { + width: 100%; +} + +.good-info .tag-container { + overflow: hidden; + width: 100%; + height: 20px; +} + +.good-info .tag-container .good-tag { + display: block; + float: left; + box-sizing: border-box; + margin-right: 4px; + height: 20px; + text-align: center; + font-size: 12px; + line-height: 20px; +} + +.good-info .tag-container .good-tag:last-child { + margin-right: 0; +} + +.good-info .tag-container .new-tag { + width: 40px; + background-color: #78dc7e; + color: #fff; +} + +.good-info .tag-container .hot-tag { + width: 60px; + background-color: #ff575c; + color: #fff; +} + +.good-info .tag-container .renew-tag { + width: 50px; + background-color: #78dc7e; + color: #fff; +} + +.good-info .tag-container .sale-tag { + width: 40px; + background-color: #ff575c; + color: #fff; +} + +.good-info .tag-container .new-festival-tag { + color: #000; + width: 50px; + background-image: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/new-festival.png"); + background-repeat: no-repeat; + background-color: #fff; + background-size: 100px 28px; +} + +.good-info .tag-container .limit-tag { + width: 60px; + border: 1px solid #000; + color: #000; +} + +.good-info .tag-container .is-presell { + width: 40px; + background-color: #000; + color: #fff; +} + +.good-info .tag-container .is-global { + padding: 3px 10px 0 8px; + color: #fff; + background-color: #462e3e; + line-height: 26px; +} + +.good-info .tag-container .is-global span { + display: inline-block; + background-image: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/airplane.png"); + background-repeat: no-repeat; + padding-left: 32px; + background-size: auto 95%; +} + +.good-detail-img .good-islike { + position: absolute; + top: 0; + right: 0; + width: 60px; + height: 60px; + color: #b0b0b0; + text-align: center; + text-decoration: none; + font-size: 30px; + line-height: 60px; +} + +.good-detail-img .good-like { + color: #d72928; +} + +.good-detail-img img { + display: block; + width: 100%; +} + +.good-detail-img .few-tag { + position: absolute; + bottom: 0; + width: 100%; + height: 24px; + background: #ffac5b; + color: #fff; + text-align: center; + font-size: 12px; + line-height: 24px; +} + +.good-detail-img .out-tag { + position: absolute; + bottom: 0; + width: 100%; + height: 32px; + background: #b0b0b0; + color: #fff; + text-align: center; + font-size: 18px; + line-height: 32px; +} + +.good-detail-img .no-storage { + width: 100%; + height: 100%; + overflow: hidden; + background-color: #000; + opacity: 0.4; + position: absolute; + top: 0; +} + +.good-detail-img .no-storage .no-storage-img { + display: block; + width: 100%; + height: 100%; + background-image: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/outlet_sellout_bg.png"); + background-repeat: no-repeat; + background-size: contain; +} + +.good-detail-text { + position: relative; +} + +.good-detail-text .name a { + transform: scale(0.9); + margin: 7px 0 5px; + min-height: 30px; + color: #444; + font-size: 12px; + line-height: 18px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + overflow: hidden; + height: 36px; +} + +.good-detail-text .price { + font-size: 12px; + line-height: 22px; + white-space: nowrap; + transform: scale(0.9); +} + +.good-detail-text .price .sale-price { + color: #d62927; +} + +.good-detail-text .price .sale-price.no-price { + color: #000; +} + +.good-detail-text .price .market-price { + font-size: 12px; + margin: 0 0 0 5px; + color: #b0b0b0; + text-decoration: line-through; +} + +.good-detail-text .vip-grade { + display: inline-block; + margin-right: 8px; + width: 26px; + height: 16px; + vertical-align: text-bottom; +} + +.good-detail-text .vip-grade-1 { + background: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/silver.png") no-repeat; + background-size: contain; +} + +.good-detail-text .vip-grade-2 { + background: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/golden.png") no-repeat; + background-size: contain; +} + +.good-detail-text .vip-grade-3 { + background: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/platinum.png") no-repeat; + background-size: contain; +} + +.good-detail-text .vip-info { + margin-top: 3px; + color: #444; + font-size: 12px; + line-height: 16px; +} + +.good-detail-text .vip-info .vip-icon { + display: inline-block; + margin-right: 8px; + width: 44px; + height: 16px; + background: url("//cdn.yoho.cn/yohobuywap-node/6.2.37/img/product/vip-icon.png") no-repeat; + background-size: contain; + vertical-align: bottom; +} + +.mip-footer { + clear: both; + position: relative; +} + +.mip-footer .option { + font-size: 0; +} + +.mip-footer .option a { + line-height: 50px; + font-size: 13px; + padding: 0 5%; +} + +.mip-footer .option .login { + border-right: solid 1px #e0e0e0; +} + +.mip-footer .option .back-to-top { + float: right; +} + +.mip-footer .option .back-to-top span { + font-weight: bold; + margin-left: 5px; + transform: scaleY(0.5); + display: inline-block; +} + +.mip-footer .copy-right { + background-color: #eee; + color: #666; + text-align: center; + line-height: 45px; + font-size: 13px; +} + +.mip-footer .mip-fixed { + position: relative !important; +} + +.mip-footer .mip-gototop { + display: inline; +} + +.list-too-little { + padding: 2% 4%; + border-bottom: 1px solid #e6e6e6; + color: #444; + font-size: 12px; +} + +.list-too-little .word { + display: inline-block; + padding: 5px 15px; + border-radius: 10px; + border: 1px solid #bbb; + margin-right: 6px; + margin-top: 5px; +} diff --git a/apps/mip/models/list.js b/apps/mip/models/list.js new file mode 100644 index 0000000..1786eeb --- /dev/null +++ b/apps/mip/models/list.js @@ -0,0 +1,83 @@ +'use strict'; + +const utils = '../../../utils'; +const redis = require(`${utils}/redis`); +const _ = require('lodash'); +const helpers = global.yoho.helpers; +const camelCase = global.yoho.camelCase; + +class List extends global.yoho.BaseModel { + constructor(ctx) { + super(ctx); + } + + list(params) { + let options = { + data: { + method: 'web.search.forseo', + sales: params.sales, + outlets: params.outlets, + stocknumber: params.stocknumber, + need_filter: params.need_filter, + query: params.query, + type: params.type, + page: params.page || 1, + limit: params.limit || 24, + order: params.order || 0 + }, + param: { + code: 200 + } + }; + + return this.get(options).then(result => { + return result; + }); + } + + getSearchKeywordDataById(params) { + return redis.all([ + ['get', `global:yoho:seo:keywords:id:${params.id}`] + ]).then(redisData => { + return redisData; + }); + } + + index(params) { + return Promise.all([ + this.getSearchKeywordDataById(params), + ]).then(result => { + let resu = { + list: [], + fuzzyWord: [] + }; + + if (_.get(result, '[0][0]')) { + let build = []; + let redisData = JSON.parse(result[0][0]); + + return this.list(Object.assign(params, {query: redisData.name})).then(listData => { + _.forEach(_.slice(redisData.data, 0, 12), value => { + build.push({ + name: value.keyword, + link: helpers.urlFormat(`/mip/list/${value.id}.html`, null) + }); + }); + resu.name = redisData.name; + resu.fuzzyWord = build; + if (_.get(listData, 'data.product_list')) { + resu.list = camelCase(listData.data.product_list); + _.forEach(resu.list, value => { + value.isSoonSoldOut = value.isSoonSoldOut === 'Y'; + }); + } + return resu; + }); + } else { + return resu; + } + }); + } +} + +module.exports = List; diff --git a/apps/mip/router.js b/apps/mip/router.js index c7fd9fe..c1be5a9 100644 --- a/apps/mip/router.js +++ b/apps/mip/router.js @@ -12,10 +12,13 @@ const cRoot = './controllers'; const rewrite = require('../../doraemon/middleware/rewrite'); const mip = require('../../doraemon/middleware/mip'); const guang = require(`${cRoot}/guang`); +const list = require(`${cRoot}/list`); router.use(mip); router.get(/^\/guang\/info\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); router.get(/^\/guang\/(.*?)\.html/, rewrite.resolve, guang.detailIndex); +router.get('/list/:id.html', list.index); + module.exports = router; diff --git a/apps/mip/views/action/list.hbs b/apps/mip/views/action/list.hbs new file mode 100644 index 0000000..aa4935f --- /dev/null +++ b/apps/mip/views/action/list.hbs @@ -0,0 +1,4 @@ +<div class="good-list-page search-page yoho-page"> + {{> list}} + {{> mip-footer}} +</div> diff --git a/apps/mip/views/partial/list.hbs b/apps/mip/views/partial/list.hbs new file mode 100644 index 0000000..ad9fc06 --- /dev/null +++ b/apps/mip/views/partial/list.hbs @@ -0,0 +1,77 @@ +{{#if fuzzyWord}} + <div class="word-content"> + <div class="list-too-little"> + {{# fuzzyWord}} + <span class="word"><a data-type="mip" href="{{link}}">{{name}}</a></span> + {{/ fuzzyWord}} + </div> + </div> +{{/if}} +{{#if list}} + {{#list}} + <div class="good-info {{#if @root.saleViplogin}}sale-vip{{/if}}" data-id="{{productSkn}}" data-bp-id="guang_goodList_{{productName}}_false"> + <div class="tag-container clearfix"> + {{#each tags}} + {{#if isNew}} + <p class="good-tag new-tag">NEW</p> + {{/if}} + {{#if isAdvance}} + <p class="good-tag renew-tag">再到着</p> + {{/if}} + {{#if isDiscount}} + <p class="good-tag sale-tag">SALE</p> + {{/if}} + {{#if isYohoood}} + <p class="good-tag running-man-tag">跑男同款</p> + {{/if}} + {{#if isLimited}} + <p class="good-tag limit-tag">限量商品</p> + {{/if}} + {{# isPresell}} + <p class="good-tag is-presell">预售</p> + {{/ isPresell}} + {{/each}} + </div> + <div class="good-detail-img"> + <a data-type="mip" class="good-thumb" href="//m.yohobuy.com/product/{{productSkn}}.html"> + <mip-img src="{{image defaultImages 235 314}}"></mip-img> + </a> + {{!-- {{log isSoonSoldOut}} --}} + {{#if isSoonSoldOut}} + <p class="few-tag">即将售罄</p> + {{/if}} + + {{#if noStorage}} + <div class="no-storage"> + <div class="no-storage-img"></div> + </div> + {{/if}} + </div> + <div class="good-detail-text"> + <div class="name"> + <a data-type="mip" href="//m.yohobuy.com/product/{{productSkn}}.html">{{productName}}</a> + </div> + <div class="price"> + {{#if @root.saleViplogin}} + <i class="vip-grade vip-grade-{{@root.vipLevel}}"></i> + <span class="sale-price {{^marketPrice}}no-price{{/marketPrice}}">¥ + {{#if @root.vipPrice1}}{{round vip1Price}}{{/if}} + {{#if @root.vipPrice2}}{{round vip2Price}}{{/if}} + {{#if @root.vipPrice3}}{{round vip3Price}}{{/if}} + </span> + {{else}} + <span class="sale-price {{^marketPrice}}no-price{{/marketPrice}}">¥{{round salesPrice}}</span> + {{/if}} + {{#marketPrice}} + <span class="market-price">¥{{round .}}</span> + {{/marketPrice}} + </div> + {{#if @root.saleVip}} + <div class="vip-info"> + <i class="vip-icon"></i>更优惠 + </div> + {{/if}} + </div> + </div> + {{/list}} +{{/if}} diff --git a/apps/mip/views/partial/mip-footer.hbs b/apps/mip/views/partial/mip-footer.hbs new file mode 100644 index 0000000..d6bebe0 --- /dev/null +++ b/apps/mip/views/partial/mip-footer.hbs @@ -0,0 +1,14 @@ +<div class="mip-footer"> + <div class="option"> + <a data-type="mip" href="//m.yohobuy.com/signin.html" class="login">登录</a> + <a data-type="mip" href="//m.yohobuy.com/reg.html" class="reg">注册</a> + <mip-fixed class="mip-fixed" type="gototop"> + <mip-gototop class="mip-gototop"> + <a data-type="mip" class="back-to-top">回到顶部<span>∧</span></a> + </mip-gototop> + </mip-fixed> + </div> + <p class="copy-right"> + CopyRight©2007-2017 南京新与力文化传播有限公司 + </p> +</div> \ No newline at end of file diff --git a/doraemon/views/mip.hbs b/doraemon/views/mip.hbs index 3e0dbd4..b3224d6 100644 --- a/doraemon/views/mip.hbs +++ b/doraemon/views/mip.hbs @@ -34,5 +34,6 @@ <script src="https://mipcache.bdstatic.com/static/v1/mip-anim/mip-anim.js"></script> <script src="https://mipcache.bdstatic.com/static/v1/mip-audio/mip-audio.js"></script> <script src="https://mipcache.bdstatic.com/extensions/platform/v1/mip-cambrian/mip-cambrian.js"></script> +<script src="https://mipcache.bdstatic.com/static/v1/mip-gototop/mip-gototop.js"></script> </body> </html> -- libgit2 0.24.0