Authored by 毕凯

Merge remote-tracking branch 'origin/feature/baseAct' into release/5.7

... ... @@ -80,6 +80,9 @@ if (!app.locals.devEnv) {
// 指定libray目录
global.utils = path.resolve('./utils');
// 添加请求上下文
app.use(global.yoho.httpCtx());
// 访问域名层级
app.set('subdomain offset', 3);
... ...
'use strict';
const indexModel = require('../models/user-recommend');
exports.index = (req, res, next) => {
let responseData = {
module: 'activity',
page: 'user-recommend',
width750: true,
localCss: true,
loadJs: [
{
src: global.yoho.config.jsSdk
}
]
};
let params = {
page: 1,
limit: 10
};
if (req.user.uid || req.query.uid) {
params.uid = req.user.uid || req.query.uid;
}
if (req.query.udid || req.cookies._yasvd) {
params.udid = req.query.udid || req.cookies._yasvd;
}
if (req.query.skn) {
params.firstProductSkn = req.query.skn;
}
req.ctx(indexModel).index(params).then(result => {
res.render('user-recommend', Object.assign(responseData, result));
}).catch(next);
};
exports.moreGoods = (req, res, next) => {
let params = {
page: req.query.page || 1,
limit: 10
};
if (req.user.uid || req.query.uid) {
params.uid = req.user.uid || req.query.uid;
}
if (req.query.udid || req.cookies._yasvd) {
params.udid = req.query.udid || req.cookies._yasvd;
}
if (req.query.skn) {
params.firstProductSkn = req.query.skn;
}
req.ctx(indexModel).moreGoods(params).then(result => {
res.json(result);
}).catch(next);
};
... ...
'use strict';
const _ = require('lodash');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
getBigpic() {
let options = {
url: 'operations/api/v5/resource/home',
data: {
content_code: '8512bf0755cc549ac323f852c9fd945d'
},
param: {
cache: true,
code: 200
},
api: global.yoho.ServiceAPI
};
return this.get(options).then(result => {
return result;
});
}
getGoods(params) {
let options = {
data: {
method: 'app.search.productMarket',
uid: params.uid,
udid: params.udid,
firstProductSkn: params.firstProductSkn,
page: params.page,
limit: params.limit
},
param: {
code: 200
}
};
return this.get(options).then(result => {
return result;
});
}
index(params) {
return Promise.all([
this.getBigpic(),
this.getGoods(params)
]).then(result => {
let resu = {
bigPic: {},
goodList: []
};
if (result) {
if (_.get(result, '[0].data.list', false)) {
if (_.get(result[0].data.list[0], 'data[0]', false)) {
let val = result[0].data.list[0].data[0];
resu.bigPic = {
src: val.src,
url: val.url
};
}
}
if (_.get(result, '[1].data.product_list', false)) {
let build = [];
let data = result[1].data.product_list;
_.forEach(data, (val) => {
let discount = this.getDiscound(val.sales_price, val.market_price);
build.push({
productName: val.product_name,
salesPrice: val.sales_price,
marketPrice: val.market_price === val.sales_price ? '' : val.market_price,
defaultImages: val.default_images ? val.default_images.split(',')[0] : '',
productSkn: val.product_skn,
discount: discount
});
});
resu.goodList = build;
}
if (_.get(result, '[1].data.coupon_list', false)) {
let couponNum = result[1].data.coupon_list.length;
if (couponNum % 2 !== 0) {
resu.odd = true;
} else {
resu.odd = false;
}
resu.couponList = result[1].data.coupon_list;
}
}
return resu;
});
}
moreGoods(params) {
return Promise.all([
this.getGoods(params)
]).then(result => {
let resu = {
goodList: []
};
if (_.get(result, '[0].data.product_list', false)) {
let build = [];
let data = result[0].data.product_list;
_.forEach(data, (val) => {
let discount = this.getDiscound(val.sales_price, val.market_price);
build.push({
productName: val.product_name,
salesPrice: val.sales_price,
marketPrice: val.market_price === val.sales_price ? '' : val.market_price,
defaultImages: val.default_images ? val.default_images.split(',')[0] : '',
productSkn: val.product_skn,
discount: discount
});
});
resu.goodList = build;
}
return resu;
});
}
getDiscound(salesPrice, marketPrice) {
let dis = Math.ceil(parseInt(salesPrice, 10) / parseInt(marketPrice, 10) * 10);
let disMes = '';
switch (dis) {
case 0:
disMes = '<span>1</span>折';
break;
case 1:
disMes = '<span>1</span>折';
break;
case 2:
disMes = '<span>2</span>折';
break;
case 3:
disMes = '<span>3</span>折';
break;
case 4:
disMes = '<span>4</span>折';
break;
case 5:
disMes = '<span>5</span>折';
break;
case 6:
disMes = '<span>6</span>折';
break;
case 7:
disMes = '<span>7</span>折';
break;
case 8:
disMes = '<span>8</span>折';
break;
case 9:
disMes = '<span>9</span>折';
break;
default:
disMes = '热卖';
break;
}
return disMes;
}
};
... ...
... ... @@ -43,13 +43,14 @@ const appDownloads = require(`${cRoot}/app-downloads`);
const redbag = require(`${cRoot}/redbag`);
const annualAccount = require(`${cRoot}/annual-account`);
const birthday = require(`${cRoot}/birthday`);
const shareBuy = require(`${cRoot}/share-buy`);
const update = require('../../doraemon/middleware/update');
const userRecommend = require(`${cRoot}/user-recommend`);
// routers
... ... @@ -255,5 +256,7 @@ router.get('/share-buy/detail', update('5.7.0'), shareBuy.detail); // 分享购
router.get('/share-buy/my-rebeat', update('5.7.0'), auth, shareBuy.myRebeat); // 我的返利
router.get('/user-recommend', userRecommend.index); // 广点通投放落地页
router.get('/user-recommend/moreGoods', userRecommend.moreGoods); // 获取商品分页
module.exports = router;
... ...
<div class="gdt-c">
{{# bigPic}}
<a class="big-pic" href="{{url}}">
<img src="{{image2 src w=750 h=280 q=60}}" />
</a>
{{/ bigPic}}
<div class="big-title">领取优惠卷
<a class="more" href='//m.yohobuy.com/coupon/floor?title=领券中心&share_id=1037&code=b78b32ed81b18dde8ac84fd33602b88b&type=5&openby:yohobuy={"action":"go.couponCenter", "params":{"share":"/operations/api/v5/webshare/getShare","share_id":"1037","title":"领券中心"}}'>
更多优惠卷
<span class="iconfont">&#xe604;</span>
</a>
</div>
<div class="ticket-c clearfix{{#if odd}} odd{{/if}}">
{{# couponList}}
<a class="ticket-item yoho-conpon" data-token="{{id}}:0" href="javascript:;">
<div class="tip">
<div class="price">
<span class="ico">¥</span>{{couponAmount}}
</div>
<div class="name line-clamp-2">{{couponName}}</div>
</div>
</a>
{{/ couponList}}
</div>
<div class="big-title">潮流优选</div>
<div class="goods clearfix">
{{# goodList}}
<a class="good-item" href="//m.yohobuy.com/product/{{productSkn}}.html">
<div class="pic">
<img src="{{image2 defaultImages w=330 h=379 q=90}}" />
</div>
<div class="price">¥{{salesPrice}}
{{#if marketPrice}}
<span>¥{{marketPrice}}</span>
{{/if}}
</div>
<div class="tip">
<div class="tip-c">
<div>{{productName}}</div>
</div>
<div class="ico"></div>
</div>
<div class="discount">{{{discount}}}</div>
</a>
{{/ goodList}}
</div>
</div>
... ...
... ... @@ -98,7 +98,8 @@ module.exports = {
notifyUrl: domains.service + 'payment/weixin_notify',
},
maxQps: 1200,
geetestJs: '//static.geetest.com/static/tools/gt.js'
geetestJs: '//static.geetest.com/static/tools/gt.js',
jsSdk: '//cdn.yoho.cn/js-sdk/1.2.2/jssdk.js'
};
if (isProduction) {
... ...
{{# goodList}}
<a class="good-item" href="//m.yohobuy.com/product/{{productSkn}}.html">
<div class="pic">
<img src="{{image2 defaultImages w=330 h=379 q=90}}" />
</div>
<div class="price">¥{{salesPrice}}
{{#if marketPrice}}
<span>¥{{marketPrice}}</span>
{{/if}}
</div>
<div class="tip">
<div class="tip-c">
<div>{{productName}}</div>
</div>
<div class="ico"></div>
</div>
<div class="discount">{{{discount}}}</div>
</a>
{{/ goodList}}
... ...
'use strict';
import {
Controller
} from 'yoho-mvc';
import {
GetMore
} from './view';
import {
moreGoods as getMore
} from './model';
let $ = require('yoho-jquery');
let goodContent = require('activity/user-recommend/recommend-goods.hbs');
class ActController extends Controller {
constructor() {
super();
this.more = new GetMore();
this.more.on('more', this.doMore.bind(this));
this.page = 1;
this.loading = false;
global.jQuery = $;
}
doMore() {
if (!this.end && !this.loading) {
this.page ++;
this.moreGood(this.page);
}
}
moreGood(page) {
this.loading = true;
$('.gdt-c').append('<p class="show-more">加载更多...</p>');
getMore('//m.yohobuy.com/activity/user-recommend/moreGoods', {page: page}).then(data => {
if (data.goodList.length > 0) {
$('.goods').append(goodContent(data));
} else {
$('.gdt-c').append('<p class="show-more">没有更多了...</p>');
this.end = true;
}
}).catch(() => {}).finally(() => {
this.loading = false;
$('.show-more').remove();
});
}
}
module.exports = ActController;
... ...
require('activity/user-recommend.page.css');
const ActController = require('./controller');
new ActController();
... ...
'use strict';
import {
http
} from 'yoho-mvc';
function moreGoods(url, data) {
return http({
url: location.protocol + url,
data: data,
});
}
export {
moreGoods
};
... ...
import {
View
} from 'yoho-mvc';
class GetMore extends View {
constructor() {
super('.gdt-c');
// srcoll to load more
$(window).scroll(() => {
window.requestAnimationFrame(this.scrollHandler.bind(this));
});
}
scrollHandler() {
if (($(window).scrollTop() + $(window).height() >= $(document).height() * 0.8)) {
this.emit('more');
}
}
}
export {
GetMore
};
... ...
.gdt-c {
padding-bottom: 30px;
.show-more {
text-align: center;
color: #b0b0b0;
font-size: 28px;
}
.big-pic {
width: 750px;
display: block;
img {
width: 100%;
}
}
.big-title {
height: 95px;
line-height: 95px;
text-align: center;
color: #444;
font-size: 28px;
font-weight: bold;
margin: 0 30px;
position: relative;
.more {
font-size: 24px;
color: #b0b0b0;
font-weight: normal;
position: absolute;
top: 0;
right: 0;
}
}
.ticket-c {
padding: 0 30px;
.ticket-item {
width: 329px;
height: 154px;
float: left;
background-image: resolve("activity/user-recommend/ticket-1.jpg");
background-size: 100% 100%;
margin-bottom: 30px;
&:nth-child(odd) {
margin-right: 30px;
}
&:nth-last-child(1) {
margin-bottom: 0;
}
&:nth-last-child(2) {
margin-bottom: 0;
}
.tip {
height: 154px;
padding: 0 30px;
color: #fff;
.price {
font-size: 60px;
}
.name {
font-size: 22px;
}
.num {
font-size: 18px;
}
.ico {
font-size: 50px;
padding-right: 5px;
}
}
}
.ticket-item.disable {
background-image: resolve("activity/user-recommend/ticket-2.jpg");
}
}
.odd {
.ticket-item:last-child {
width: 100%;
}
}
.goods {
padding: 0 30px;
.good-item {
width: 330px;
float: left;
margin-bottom: 50px;
position: relative;
background-color: #292929;
display: block;
&:nth-child(odd) {
margin-right: 30px;
}
}
.pic {
width: 330px;
height: 379px;
img {
width: 100%;
height: 100%;
}
}
.price {
height: 60px;
line-height: 60px;
text-align: center;
color: #fff;
background-color: #cf2020;
font-size: 26px;
span {
font-size: 20px;
color: #fff;
opacity: 0.8;
padding: 0 5px;
text-decoration: line-through;
}
}
.tip {
height: 65px;
color: #fff;
margin: 15px 0;
padding: 0 60px 0 10px;
font-size: 24px;
position: relative;
overflow: hidden;
.tip-c {
height: 65px;
text-overflow: ellipsis;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
display: table-cell;
vertical-align: middle;
div {
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
.ico {
width: 32px;
height: 32px;
background-image: resolve("activity/user-recommend/arr.png");
background-size: 100%;
position: absolute;
right: 10px;
top: 16px;
}
}
.discount {
width: 68px;
height: 63px;
background-image: resolve("activity/user-recommend/discount.png");
background-size: 100%;
position: absolute;
top: -9px;
left: 20px;
color: #fff;
text-align: center;
line-height: 63px;
padding-left: 8px;
font-size: 20px;
span {
font-size: 30px;
font-weight: bold;
}
}
}
}
... ...