Authored by 李靖

开发完成

'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);
};
... ...
.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;
}
... ...
'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;
... ...
... ... @@ -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;
... ...
<div class="good-list-page search-page yoho-page">
{{> list}}
{{> mip-footer}}
</div>
... ...
{{#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}}
... ...
<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
... ...
... ... @@ -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>
... ...