Authored by 李奇

Merge branch 'master' into feature/cs-quit-queue

Showing 61 changed files with 2628 additions and 1327 deletions

Too many changes to show.

To preserve performance only 61 of 61+ files are displayed.

**/bundle/**/*.js
**/dist/**/*.js
coverage
public/static/js-sdk
public/static/yas-jssdk
public/js/home/jquery.upload.js
public/js/activity/live/yas_live_data.js
\ No newline at end of file
public/js/activity/live/yas_live_data.js
... ...
phantomjs_cdnurl=http://npm.taobao.org/mirrors/phantomjs
registry=http://npm.yoho.cn
\ No newline at end of file
... ...
... ... @@ -80,8 +80,12 @@ if (!app.locals.devEnv) {
// 指定libray目录
global.utils = path.resolve('./utils');
// 添加请求上下文
app.use(global.yoho.httpCtx());
// 访问域名层级
app.set('subdomain offset', 3);
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
... ... @@ -169,6 +173,9 @@ app.use((req, res, next) => {
next();
});
// 添加请求上下文
app.use(global.yoho.httpCtx());
// dispatcher
try {
const user = require('./doraemon/middleware/user');
... ...
'use strict';
const questionModel = require('../models/question');
const headerModel = require('../../../doraemon/models/header'); // 头部model
exports.list = (req, res, next) => {
req.ctx(questionModel).getQuestionList().then(result => {
res.render('question/list', {
title: '调研中心',
module: '3party',
page: 'question-list',
pageHeader: headerModel.setNav({
navTitle: '调研中心'
}),
list: result,
isApp: req.yoho.isApp,
localCss: true
});
}).catch(next);
};
exports.check = (req, res, next) => {
let params = req.body;
params.uid = req.user.uid || params.uid;
if (!params.uid) {
return res.send({code: 400, message: '请先登录!'});
}
req.ctx(questionModel).getQuestionStatus(params).then(result => {
res.send(result);
}).catch(next);
};
exports.submit = (req, res, next) => {
let params = req.body;
params.uid = req.user.uid || params.uid;
if (!params.uid) {
return res.send({code: 400, message: '请先登录!'});
}
// 标识问卷来源
if (req.yoho.isApp) {
params.sourceType = 'APP';
} else if (req.yoho.mobile) {
params.sourceType = 'H5';
} else {
params.sourceType = 'PC';
}
req.ctx(questionModel).submitQuestion(params).then(result => {
res.send(result);
}).catch(next);
};
exports.detail = (req, res, next) => {
let id = parseInt(`0${req.params.id}`, 10);
req.ctx(questionModel).getQuestionDetail(id, req.user.uid).then(result => {
if (result && result.detail && req.yoho.isApp) {
result.detail.uid = req.user.uid;
}
res.render('question/detail', Object.assign(result, {
title: 'YOHOBUY!潮流大调查',
module: '3party',
page: 'question-detail',
pageHeader: headerModel.setNav({
navTitle: 'YOHOBUY!潮流大调查'
}),
isApp: req.yoho.isApp,
localCss: true
}));
}).catch(next);
};
... ...
/**
* question model
* @author: yyq<yanqing.yang@yoho.cn>
* @date: 2017/05/23
*/
const _ = require('lodash');
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
getQuestionList() {
return this.get({
url: 'activity/question/questionList',
api: global.yoho.ServiceAPI
}).then(result => {
let list = _.get(result, 'data.rows', []);
_.forEach(list, (value, key) => {
value.index = key + 1;
if (!_.get(value, 'share.imgUrl', '')) {
_.set(value, 'share.imgUrl', 'http://img11.static.yhbimg.com/sns/2017/05/25/14/0177e28a98f73417ae1a2a146aa2670dd2.png'); // eslint-disable-line
}
});
return list;
});
}
getQuestionStatus(params) {
return this.get({
url: '/activity/question/questionValidate',
data: params,
api: global.yoho.ServiceAPI
});
}
getQuestionDetail(id, uid) {
return Promise.all([
this.get({
url: '/activity/question/questionValidate',
data: {id: id, uid: uid},
api: global.yoho.ServiceAPI
}),
this.get({
url: 'activity/question/questionDetail',
data: {id: id},
api: global.yoho.ServiceAPI
})
]).then(result => {
let resData = {};
if (_.get(result, '[0].code', '') === 200) {
let data = _.get(result, '[1].data', {});
if (data.questions) {
_.forEach(data.questions, value => {
if (+value.questionType === 3) {
value.questionContents = _.fill(Array(value.fillBlankNum || 1), true);
}
});
}
if (!_.isEmpty(data)) {
resData.detail = data;
}
} else {
resData.errText = _.get(result, '[0].message', '哟,本次调研已经飞走了,请移步其他调研呗!');
}
return resData;
});
}
submitQuestion(info) {
return this.post({
url: '/activity/question/submitQuestions',
data: info,
api: global.yoho.ServiceAPI
});
}
};
... ...
... ... @@ -10,7 +10,9 @@ const router = require('express').Router(); // eslint-disable-line
const cRoot = './controllers';
const ads = require(`${cRoot}/ads`);
const check = require(`${cRoot}/check`);
const question = require(`${cRoot}/question`);
const validateCode = require('../passport/controllers/validateCode');
const auth = require('../../doraemon/middleware/auth');
// routers
... ... @@ -18,4 +20,10 @@ router.get('/ads', ads.index);
router.get('/check', validateCode.load, check.index);
router.post('/check/submit', validateCode.check, check.submit);
router.get('/questionnaire', auth, question.list);
router.post('/questionnaire/check', question.check);
router.post('/questionnaire/submit', question.submit);
router.get('/questionnaire/:id', auth, question.detail);
module.exports = router;
... ...
<div class="qs-detail-page">
{{# detail}}
<div class="error-tip"></div>
<div class="detail-wrap">
<p class="sub-title">{{title}}</p>
<p class="guide-tip">{{description}}</p>
<div id="qs-wrap" class="qs-wrap" data-id="{{id}}" data-cid="{{uid}}" data-title="{{share.title}}" data-desc="{{share.subtitle}}" data-img="{{share.imgUrl}}">
{{# questions}}
<dl class="qs-item" data-index="{{questionIndex}}" data-type="{{questionType}}">
<dt>{{questionTitle}}</dt>
{{#isEqualOr questionType 1}}
{{# questionContents}}
<dd class="radio-option" data-index="{{@index}}">
<span class="iconfont">&#xe6ea;</span>
<div class="option-box">{{{option}}}</div>
{{#if addon}}
<input type="text">
{{/if}}
</dd>
{{/ questionContents}}
{{/isEqualOr}}
{{#isEqualOr questionType 2}}
{{# questionContents}}
<dd class="check-option" data-index="{{@index}}">
<span class="iconfont">&#xe6ea;</span>
<div class="option-box">{{{option}}}</div>
{{#if addon}}
<input type="text">
{{/if}}
</dd>
{{/ questionContents}}
{{/isEqualOr}}
{{#isEqualOr questionType 3}}
{{# questionContents}}
<dd><textarea class="text-input"></textarea></dd>
{{/ questionContents}}
{{/isEqualOr}}
</dl>
{{/ questions}}
</div>
<div class="submit">
<button class="submit-btn">提交</button>
</div>
</div>
{{/ detail}}
<div class="qs-err">
<p class="err-text">{{{errText}}}</p>
<a href="/3party/questionnaire">去做问卷</a>
</div>
<div id="tip-dialog" class="tip-dialog hide">
<div class="dg-wrap">
<div class="dg-content"><p>您的问卷还没有成功提交哦!<br>是否立刻返回!</p></div>
<div class="dg-btns clearfix">
<span class="back-btn">返回</span>
<span class="close-btn continue-btn">继续填写</span>
</div>
</div>
</div>
</div>
... ...
<div class="qs-list-page">
{{#if list}}
<ul id="qs-list" class="qs-list">
{{#each list}}
<li data-id="{{id}}" data-title="{{title}}" data-desc="{{share.subtitle}}" data-img="{{share.imgUrl}}">{{index}}.{{title}}</li>
{{/each}}
</ul>
{{/if}}
<div id="tip-dialog" class="tip-dialog hide">
<div class="dg-wrap">
<div class="dg-content"></div>
<div class="dg-btns sure-btns clearfix hide">
<span class="close-btn sure-btn">确定</span>
</div>
<div class="dg-btns share-btns clearfix">
<span class="close-btn cancel-btn">取消</span>
<span class="share-btn">分享问卷</span>
</div>
</div>
</div>
</div>
... ...
/**
* @author: jing.li@yoho.cn
* @date: 2017/04/24
*/
'use strict';
const birtdDayModel = require('../models/birthday');
exports.index = (req, res) => {
let responseData = {
module: 'activity',
page: 'birthday',
title: '生日卷',
width750: true,
localCss: true
};
res.render('birthday', responseData);
};
exports.getCoupon = (req, res, next) => {
req.ctx(birtdDayModel).getCoupon({uid: req.user.uid}).then(data => {
res.json(data);
}).catch(next);
};
... ...
... ... @@ -23,7 +23,9 @@ exports.index = (req, res, next) => {
module: 'activity',
page: 'coupon-floor',
wechatShare: true,
title: '领券中心',
title: '有货优惠券_有货现金优惠券,全场券,品类券,品牌券_领券频道-Yoho!Buy有货',
keywords: '有货优惠券,有货现金优惠券,全场券,品类券,品牌券',
description: 'Yoho!Buy有货官网领券频道,提供有货优惠券,有货现金优惠券,有货全场券,有货品类券,品牌券免费领取,让你做网购达人,省钱又省心!',
pageHeader: headerModel.setNav({
navTitle: '领券中心'
}),
... ...
... ... @@ -2,6 +2,9 @@
const model = require('../models/feature');
exports.index = function(req, res, next) {
// 唤起 APP 的路径
res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.h5","params":{"param":{"share_id":"${req.query.share_id}"},"share":"/operations/api/v5/webshare/getShare","shareparam":{"share_id":"${req.query.share_id}"},"url":"https://activity.yoho.cn/feature/${req.params.code}.html"}}`;
model.index({
code: req.params.code,
type: req.query.type
... ... @@ -14,6 +17,7 @@ exports.index = function(req, res, next) {
page: 'feature',
title: result.name || 'Yoho!Buy有货',
content: result,
activity_id: req.params.code,
isFeature: true
});
}).catch(next);
... ...
... ... @@ -8,38 +8,71 @@ const channels = {
};
exports.productLst = function(req, res, next) {
let keys = ['sort', 'misort', 'msort', 'gender', 'brand'],
params = {
uid: req.user.uid || req.query.uid,
udid: req.query.udid,
promotion: req.query.pid,
let uid = req.user.uid || req.query.uid;
let udid = req.query.udid;
let getProductList;
if (req.query.maybeLike) {
getProductList = model.maybeLikeList(Object.assign({
uid: uid,
udid: udid,
yh_channel: req.query.yh_channel || (req.cookies._Channel && channels[req.cookies._Channel]) || 1,
specified_sort: req.query.enum,
stocknumber: req.query.sn,
p_d: req.query.pd,
noDup: req.query.noDup,
limit: req.query.limit || 10
};
keys.forEach(function(k) {
if (req.query[k]) {
params[k] = req.query[k];
}
});
if (params.specified_sort) {
if (params.brand) {
params.limit = params.brand.split(',').length;
} else if (params.sort) {
params.limit = params.sort.split(',').length;
} else if (params.misort) {
params.limit = params.misort.split(',').length;
} else if (params.msort) {
params.limit = params.msort.split(',').length;
limit: req.query.limit
}, req.query));
} else {
let keys = ['sort', 'misort', 'msort', 'gender', 'brand'],
params = {
uid: uid,
udid: udid,
promotion: req.query.pid,
yh_channel: req.query.yh_channel || (req.cookies._Channel && channels[req.cookies._Channel]) || 1,
specified_sort: req.query.enum,
stocknumber: req.query.sn,
p_d: req.query.pd,
noDup: req.query.noDup,
limit: req.query.limit || 10
};
keys.forEach(function(k) {
if (req.query[k]) {
params[k] = req.query[k];
}
});
if (params.specified_sort) {
if (params.brand) {
params.limit = params.brand.split(',').length;
} else if (params.sort) {
params.limit = params.sort.split(',').length;
} else if (params.misort) {
params.limit = params.misort.split(',').length;
} else if (params.msort) {
params.limit = params.msort.split(',').length;
}
}
getProductList = model.productLst(params);
}
getProductList.then((result) => {
res.jsonp(result);
}).catch(next);
};
exports.coupon = function(req, res, next) {
let activity_template_id = req.query.activity_id;
let uid = req.user.uid || req.query.uid;
if (!uid || !activity_template_id) {
return res.jsonp({
code: 400
});
}
model.productLst(params).then((result) => {
model.getCoupon({
activity_template_id,
uid
}).then((result) => {
res.jsonp(result);
}).catch(next);
};
... ...
'use strict';
const shareBuyModel = require('../models/share-buy'),
headerModel = require('../../../doraemon/models/header'),
co = require('bluebird').coroutine;
exports.index = (req, res, next) => {
let activityId = req.query.act_id || 2023,
isApp = req.yoho.isApp,
uid = req.user.uid,
protocol = req.app.locals.isProduction ? 'https:' : 'http:';
co(function* () {
let isStudent = yield req.ctx(shareBuyModel).checkStudent(uid);
let indexData = yield req.ctx(shareBuyModel).shareIndex(activityId, isApp, uid, isStudent, protocol);
res.render('share-buy/share-buy', {
pageHeader: headerModel.setNav({
navTitle: '分享购'
}),
isApp: isApp,
localCss: true,
width750: true,
title: '分享购',
userCouponBoList: indexData.userCouponBoList,
newsFlash: indexData.newsFlash,
rebeatUrl: indexData.rebeatUrl,
strategyUrl: indexData.strategyUrl,
banner: indexData.banner,
isStudent: indexData.isStudent
});
})().catch(next);
};
exports.detail = (req, res, next) => {
let param = {
couponId: req.query.couponId,
couponCode: req.query.couponCode
},
isApp = req.yoho.isApp;
req.ctx(shareBuyModel).shareDetail(param, isApp).then(data => {
res.render('share-buy/share-detail', {
pageHeader: headerModel.setNav({
navTitle: '分享购'
}),
isApp: isApp,
localCss: true,
width750: true,
title: '分享购',
page: 'share-detail',
detailData: data
});
}).catch(next);
};
exports.myRebeat = (req, res, next) => {
let uid = req.user.uid,
isApp = req.yoho.isApp;
req.ctx(shareBuyModel).myRebeat(uid, isApp).then(data => {
res.render('share-buy/my-rebeat', {
pageHeader: headerModel.setNav({
navTitle: '我的返利收益'
}),
isApp: isApp,
localCss: true,
width750: true,
title: '我的返利收益',
page: 'my-rebeat',
rebeatData: data
});
}).catch(next);
};
... ...
'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: 50,
isApp: req.yoho.isApp
};
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,
isApp: req.yoho.isApp
};
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);
};
... ...
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
getCoupon(params) {
let options = {
data: {
method: 'app.promotion.validateGetBirthCoupon',
uid: params.uid
},
param: {
code: 200
}
};
return this.get(options).then(result => {
return result;
});
}
};
... ...
... ... @@ -359,12 +359,24 @@ exports.receiveCoupon = (receiveData, uid) => {
};
exports.couponSend = (uid, token) => {
return api.get('', {
let data = {
method: 'app.coupons.couponSend',
uid: uid,
coupon_send_token: token
}).then(result => {
};
if (/:/.test(token)) {
let [couponId, personCouponId] = token.split(':');
data = {
method: 'app.promotion.getCoupon',
uid: uid,
couponId: couponId,
personCouponId: personCouponId
};
}
return api.get('', data).then(result => {
if (!result) {
result.code = 404;
... ...
'use strict';
const _ = require('lodash');
const api = global.yoho.API;
const helpers = global.yoho.helpers;
... ... @@ -10,10 +11,8 @@ const _getProductBySkns = function(productObj) {
productObj.defaultPros = [];
if (result && result.data && result.data.product_list && result.code === 200) {
result.data.product_list.forEach(function(val) {
var goods_id = Array.isArray(val.goods_list) &&
val.goods_list.length ? val.goods_list[0].goods_id : null;
var obj = {
producturl: `//m.yohobuy.com/product/pro_${val.product_id}_${goods_id}/${val.cn_alphabet}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${val.product_skn}}}`, // eslint-disable-line
producturl: `//m.yohobuy.com/product/${val.product_skn}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${val.product_skn}}}`, // eslint-disable-line
productimg: helpers.image(val.default_images, 213, 284, 2, 60).replace('quality/80', 'quality/60'),
productname: val.product_name,
vipprice: val.vip_price,
... ... @@ -67,6 +66,20 @@ module.exports = {
f.component[0].type === 'productGroup' && f.component[0].defaultSkns) {
sknsArr.push(_getProductBySkns(f.component[0]));
}
if (f.component && f.component[0] &&
f.component[0].type === 'productGroup' && f.component[0].favourite_prds_enable === '1') {
f.component[0].searchCondition = Object.assign({
maybeLike: '1',
limit: '12'
}, f.component[0].searchCondition || {});
}
_.forEach(f.component, function(component) {
if (component.persenal_enable === '1') {
f.hide = true; // 个性化券楼层先不展示,前端异步查询到的时候,再展示
}
});
});
}
... ...
... ... @@ -39,5 +39,32 @@ module.exports = {
});
return data;
});
},
maybeLikeList: function(params) {
return api.get('', {
method: 'app.search.newLast7day',
uid: params.uid || 0,
udid: params.udid || 0,
yh_channel: params.yh_channel,
limit: params.limit,
need_filter: 'null'
}, {
cache: true
}).then(res => {
var data = [],
lst = (res && res.data && res.data.product_list) || [];
lst.forEach(function(o) {
o && data.push(_getProduct(o));
});
return data;
});
},
getCoupon: function(params) {
return api.get('', Object.assign({
method: 'app.coupons.personalCoupons'
}, params), {
cache: true
});
}
};
... ...
const api = global.yoho.API;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const service = global.yoho.ServiceAPI;
module.exports = class extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 首页数据
*/
shareIndex(activityId, isApp, uid, isStudent, protocol) {
return api.all([this._CouponInfo(activityId, uid, isStudent), this._redeatList(),
this._banner()]).then(result => {
const indexData = {
newsFlash: []
};
const rebeatUrl = '//m.yohobuy.com/activity/share-buy/my-rebeat',
strategyUrl = 'http://activity.yoho.cn/feature/115.html?share_id=2023&title=分享购攻略';
indexData.isStudent = isStudent;
if (result[0] && result[0].data && result[0].data.userCouponBoList) {
_.forEach(result[0].data.userCouponBoList, function(val) {
if (val.sortNames) {
val.couponDescribe = '限' + val.sortNames + '使用';
} else if (val.brandNames) {
val.couponDescribe = '限' + val.brandNames + '使用';
} else if (val.shareCoupon === '全场通用') {
val.couponDescribe = '任意商品使用';
} else if (val.shopNames) {
val.couponDescribe = '限' + val.shopNames + '使用';
}
val.detailUrl = helpers.urlFormat('/activity/share-buy/detail', {
couponId: val.couponId,
couponCode: val.couponCode
});
if (isApp) {
val.detailUrl = protocol + val.detailUrl +
'&openby:yohobuy={"action":"go.h5","params":{"islogin":"N","url":"' + protocol +
val.detailUrl + '","params":{"couponId":"' + val.couponId + '","couponCode":"' +
val.couponCode + '"}}}';
}
if (!indexData.isStudent) {
val.detailUrl = '';
}
});
indexData.userCouponBoList = result[0].data.userCouponBoList;
}
if (result[1] && result[1].data && result[1].data.detail) {
_.forEach(result[1].data.detail, function(data) {
indexData.newsFlash.push({
flashDetail: '用户' + data.nickName + ' 今日返利' + data.coinNum + '个有货币'
});
});
}
if (result[2]) {
indexData.banner = result[2].data[0].src;
}
indexData.rebeatUrl = isApp ? rebeatUrl +
'?openby:yohobuy={"action":"go.h5","params":{"islogin":"N","url":"http:' + rebeatUrl + '"}}' :
rebeatUrl;
indexData.strategyUrl = isApp ? strategyUrl +
'&openby:yohobuy={"action":"go.h5","params":{"islogin":"N","url":"' + strategyUrl + '"}}' : strategyUrl;
return indexData;
});
}
/**
* 首页资源位
*/
_banner() {
return service.get('operations/api/v5/resource/get', {
content_code: 'a4ceb2d742c55008ac7be30bca43e03f',
platform: 'iphone'
}, {
cache: true,
code: 200
}).then((result) => {
if (result && result.data) {
return result.data[0];
}
});
}
/**
* 首页获取优惠券信息
*/
_CouponInfo(activityId, uid, isStudent) {
return api.get('', {
method: 'app.activity.getActivityCouponInfo',
activity_id: activityId,
uid: uid,
isStudent: isStudent
}, {
code: 200
}).then((result) => {
if (result && result.code === 200 && result.data) {
return result;
}
});
}
/**
* 首页获取返利记录
*/
_redeatList() {
return api.get('', {
method: 'app.yohocoinrebeat.lastedlist'
}, {
code: 200,
cache: true
}).then((result) => {
if (result && result.code === 200 && result.data) {
return result;
}
});
}
/**
* 优惠劵详情数据
*/
shareDetail(param, isApp) {
return api.get('', {
method: 'app.activity.getActivityCouponDesc',
coupon_code: param.couponCode,
coupon_id: param.couponId
}, {
code: 200
}).then((result) => {
let moreUrl,
detailData;
if (result && result.code === 200 && result.data) {
detailData = _.assign(detailData, param);
moreUrl = helpers.urlFormat('', {
coupon_code: param.couponCode,
coupon_id: param.couponId,
title: '优惠活动商品',
intro_text: '优惠券可适用于以下产品'
}, 'list');
detailData.moreUrl = isApp ? moreUrl +
'&openby:yohobuy={"action":"go.couponProductList","params":{"coupon_code":"' + param.couponCode +
'","coupon_id":"' + param.couponId +
'","title":"优惠活动商品","actiontype":"1","coupon_title":"优惠券可适用于以下产品"}}' : moreUrl;
detailData.isApp = isApp ? true : false;
detailData.finish = parseInt(result.data.expiredTime, 10) > 0 ? false : true;
if (result.data.userCouponBoList[0].sortNames) {
detailData.detailDes = '限品类: ' + result.data.userCouponBoList[0].sortNames;
} else if (result.data.userCouponBoList[0].brandNames) {
detailData.detailDes = '限品牌: ' + result.data.userCouponBoList[0].brandNames;
} else if (result.data.userCouponBoList[0].shareCoupon === '全场通用') {
detailData.detailDes = result.data.userCouponBoList[0].shareCoupon;
} else if (result.data.userCouponBoList[0].shopNames) {
detailData.detailDes = result.data.userCouponBoList[0].shopNames;
}
detailData = _.assign(detailData, {
counum: result.data.userCouponBoList[0].couponValue,
couponType: result.data.userCouponBoList[0].shareCouponType,
expiredTime: result.data.expiredTime,
couponValidity: result.data.couponValidity
});
return detailData;
} else {
return {};
}
});
}
/**
* 判断是不是学生
*/
checkStudent(uid) {
return api.get('', {
method: 'app.student.checkIsStudent',
uid: uid
}).then(result => {
let isStudent;
if (result && result.data && result.code === 200) {
isStudent = parseInt(result.data.isStudent, 10) === 1 ? true : false;
}
return isStudent;
});
}
/**
* 我的返利页数据
*/
myRebeat(uid, isApp) {
return api.get('', {
method: 'app.yohocoinrebeat.detail',
uid: uid
}, {
code: 200
}).then((result) => {
let currencyUrl = 'http://m.yohobuy.com/home/helpDetail?code=20151230-102233&caption=有货币介绍&name=有货币介绍';
let shareUrl = 'http://m.yohobuy.com/activity/share-buy';
if (result && result.code === 200 && result.data) {
let dateTime;
_.forEach(result.data.detail, function(val) {
val.cancel = parseInt(val.status, 10) === 0 ? true : false;
val.already = parseInt(val.status, 10) === 2 ? true : false;
dateTime = new Date(val.createTime);
val.createTime = dateTime.getFullYear() + '.' + (dateTime.getMonth() + 1) +
'.' + dateTime.getDate();
});
result.data.currencyUrl = isApp ? currencyUrl +
'&openby:yohobuy={"action":"go.h5","params":{"islogin":"N","url":"' +
currencyUrl + '"}}' : currencyUrl;
result.data.shareUrl = isApp ? shareUrl +
'?openby:yohobuy={"action":"go.h5","params":{"islogin":"N","url":"' +
shareUrl + '"}}' : shareUrl;
return result.data;
} else {
return {};
}
});
}
};
... ...
... ... @@ -6,7 +6,7 @@
'use strict';
const service = global.yoho.ServiceAPI;
const service = global.yoho.StoreAPI;
const moment = require('moment');
// 格式年月日
... ...
'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',
platform: 'iphone'
},
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);
let url = `//m.yohobuy.com/product/${val.product_skn}.html`;
if (params.isApp) {
url += `?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${val.product_skn}"}}`; // eslint-disable-line
}
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] : '',
url: url,
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);
let url = `//m.yohobuy.com/product/${val.product_skn}.html`;
if (params.isApp) {
url += `?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":"${val.product_skn}"}}`; // eslint-disable-line
}
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] : '',
url: url,
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,6 +43,15 @@ 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
router.get('/demo', demo.index);
... ... @@ -226,6 +235,7 @@ router.get('/redbag/2017', redbag.index);
// 获取活动页面个性化推荐商品数据
router.get('/individuation', individuation.productLst);
router.get('/individuation/coupon', individuation.coupon);
// 活动页模版
router.get('/feature/:code.html', feature.index);
... ... @@ -238,4 +248,15 @@ router.get('/app-downloads', appDownloads.index);
router.get('/couponSend', couponFloor.couponSend); // 获取优惠券
router.get('/birthday', auth, birthday.index); // 生日卷活动
router.get('/getCoupon', birthday.getCoupon); // 获取生日卷状态
router.get('/share-buy', update('5.7.0'), auth, shareBuy.index); // 分享购首页
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="birthday-c">
<a class="btn"></a>
<div class="rule clearfix">
<div class="rule-item">
<div>领取时间:</div>
<div>生日当月可领取,以您个人信息填写的生日为准。</div>
</div>
<div class="rule-item">
<div>领取详情:</div>
<div>生日卷领取之日起16日内有效,过期不补偿,领取后请尽快使用。</div>
</div>
<div class="rule-item">
<div>领取资格:</div>
<div>您在领取时,必须是有货VIP银卡、金卡、白金卡用户,<a href="//m.yohobuy.com/home/grade">(了解您当前的VIP级别)</a>,且在个人信息中已完善生日信息<a href="//m.yohobuy.com/home/mydetails">(查看/完善个人信息)</a></div>
</div>
</div>
<p class="foot-tip">温馨提示:同一用户一年内(365天)仅可以领取一次生日特惠哦!</p>
<div class="dia-c">
<div class="bg"></div>
<div class="dia">
<p class="title"></p>
<p class="message"></p>
</div>
</div>
</div>
... ...
<div class="feature-page yoho-page">
<div class="feature-page yoho-page" data-id="{{activity_id}}">
{{#unless content.visiable}}
<div class="over">
<p>此活动已结束</p>
... ... @@ -18,13 +18,13 @@
{{/isEqualOr}}
{{#isEqualOr type '' 'common_floor' 'fix'}}
{{! 普通楼层 顶悬浮}}
<div {{#if param.anchorname}}id="{{param.anchorname}}"{{/if}} {{#if param.tabname}}tabname="{{param.tabname}}"{{/if}} {{#if id}}data-id="{{id}}"{{/if}} class="floor {{type}}"
<div {{#if param.anchorname}}id="{{param.anchorname}}"{{/if}} {{#if param.tabname}}tabname="{{param.tabname}}"{{/if}} {{#if id}}data-id="{{id}}"{{/if}} class="floor {{type}} {{#if hide}}hide{{/if}}"
style="{{#if param.bgcolor}}background-color:{{param.bgcolor}}{{/if}}">
{{#if param.bgimg}}
{{#isLazyLoad type @index}}
<img class="lazy" data-original="{{image2 param.bgimg q=75}}">
<img class="lazy" data-original="{{imageslim param.bgimg}}">
{{else}}
<img src="{{image2 param.bgimg q=75}}">
<img src="{{imageslim param.bgimg}}">
{{/isLazyLoad}}
{{/if}}
{{#component}}
... ... @@ -34,14 +34,15 @@
{{#if modalImg}}
<div class="modal">
<span class="modal-close"></span>
<img class="modal-img lazy" data-original="{{image2 modalImg q=75}}">
<img class="modal-img lazy" data-original="{{imageslim modalImg}}">
</div>
{{/if}}
{{/isEqualOr}}
{{#isEqualOr type 'coupon'}}
{{! 优惠券}}
<a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-token="{{token}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
<a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-persenal-enable="{{persenal_enable}}" data-token="{{token}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}"
fp="{{getAnalysis ../this @index}}"></a>
{{/isEqualOr}}
{{#isEqualOr type 'yohoCoin'}}
... ... @@ -65,7 +66,7 @@
<div class="swiper-wrapper">
{{#list}}
<div class="swiper-slide" style="{{styleFormat this percent=1}}">
<img src="{{image2 src q=75}}">
<img src="{{imageslim src}}">
<a class="anchor" href="{{#if link}}{{link}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../../this @index}}"></a>
</div>
{{/list}}
... ... @@ -87,7 +88,7 @@
{{#isEqualOr type 'productGroup'}}
{{! 商品池}}
<div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{image2 proBgImg q=75}}) repeat;background-size:100%;"{{/if}}>
<div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{imageslim proBgImg}}) repeat;background-size:100%;"{{/if}}>
<div class="product-source" condition='{{stringify searchCondition}}' fp="{{getAnalysis ../this @index}}"
{{#unless defaultPros.length}}
{{#if searchCondition.item}}
... ... @@ -102,9 +103,9 @@
<div class="feature-product-info {{#if ../searchCondition}}novisible{{/if}}">
<a class="first-part product-detail" href='{{producturl}}'>
<div class="product-detail-imgbox">
{{#if ../lefTopImg}}<img class="leftopimg lazy" data-original="{{image2 ../lefTopImg q=75}}">{{/if}}
{{#if ../rigTopImg}}<img class="rigtopimg lazy" data-original="{{image2 ../rigTopImg q=75}}">{{/if}}
<img class="product-detail-img lazy" data-original="{{image2 productimg q=75}}">
{{#if ../lefTopImg}}<img class="leftopimg lazy" data-original="{{imageslim ../lefTopImg}}">{{/if}}
{{#if ../rigTopImg}}<img class="rigtopimg lazy" data-original="{{imageslim ../rigTopImg}}">{{/if}}
<img class="product-detail-img lazy" data-original="{{imageslim productimg}}">
</div>
{{#isEqualOr ../showPrdName '1'}}<p class="product-name">{{productname}}</p>{{/isEqualOr}}
<div class="product-detail-text">
... ... @@ -127,7 +128,7 @@
<div class="brand-div">
<span class="brand-name"{{#if ../fontColor}}style="color:{{../fontColor}};"{{/if}}>{{brandname}}</span>
</div>
<img class="brand-img lazy" data-original="{{image2 ../brandImg q=75}}">
<img class="brand-img lazy" data-original="{{imageslim ../brandImg}}">
</a>
{{/if}}
</div>
... ... @@ -136,8 +137,8 @@
<div class="feature-product-info novisible">
<a class="first-part product-detail" href=''>
<div class="product-detail-imgbox">
{{#if lefTopImg}}<img class="leftopimg" src="{{image2 lefTopImg q=75}}">{{/if}}
{{#if rigTopImg}}<img class="rigtopimg" src="{{image2 rigTopImg q=75}}">{{/if}}
{{#if lefTopImg}}<img class="leftopimg" src="{{imageslim lefTopImg}}">{{/if}}
{{#if rigTopImg}}<img class="rigtopimg" src="{{imageslim rigTopImg}}">{{/if}}
<img class="product-detail-img" src="">
</div>
{{#isEqualOr showPrdName '1'}}<p class="product-name"></p>{{/isEqualOr}}
... ... @@ -160,7 +161,7 @@
<div class="brand-div">
<span class="brand-name" {{#if fontColor}}style="color:{{fontColor}};"{{/if}}></span>
</div>
<img class="brand-img" src="{{image2 brandImg q=75}}">
<img class="brand-img" src="{{imageslim brandImg}}">
</a>
{{/if}}
</div>
... ...
<div class="my-rebeat-page">
{{# rebeatData}}
<ul class="gross-earnings">
<li>累计返利有货币
<p>
<span class="amount">{{haveRebeatNum}}</span>
</p>
</li>
<li>等待返利到账的有货币
<p>
<span class="amount">{{waitingRebeatNum}}</span>
</p>
</li>
<li>返利取消
<span class="reason">(返利订单因退货等原因取消)</span>
<p>
<span class="amount">{{cancleRebeatNum}}</span>
</p>
</li>
</ul>
<p class="title">返利明细</p>
{{#if detail}}
<ul class="earnings-detail">
{{# detail}}
<li>
<p class="earnings-info">
<span class="num">{{#if cancel}}-{{/if}}{{#if already}}+{{/if}}{{coinNum}}</span>
<span class="user">{{nickName}} <i {{#if cancel}}class="cancel"{{/if}}>{{statusStr}}</i></span>
</p>
<p class="order-info">
<span class="time">{{createTime}}</span>
<span class="order-code">订单号:{{orderCode}}</span>
</p>
</li>
{{/ detail}}
</ul>
<div class="hints">
<p>友情提示:返利订单确认收货后7天无退货,对应金额的有货币将
会发放至您的有货账户!
</p>
<p>有货币是什么?<a href="{{currencyUrl}}">了解详情</a></p>
</div>
{{else}}
<a class="no-rebeat" href="{{shareUrl}}">暂时没有相关返利信息,立即参与分享赢返利<i class="iconfont">&#xe614;</i></a>
{{/if}}
{{/ rebeatData}}
</div>
... ...
<div class="share-buy-page yoho-page">
{{#if banner}}
<div class="share-title">
<img src="{{image banner 750 366}}"><img>
</div>
{{/if}}
<div class="coupon-list" data-student="{{isStudent}}">
{{# userCouponBoList}}
<div class="coupon-group">
<div class="coupon-left">
<p class="coupon-money">
<i>&#xA5;</i>
<span class="money">{{couponValue}}</span>
</p>
<p class="coupon-type">{{shareCouponType}}</p>
</div>
<div class="coupon-right">
{{#if detailUrl}}
<a href="{{detailUrl}}" class="join">立即参与</a>
{{else}}
<span class="join">立即参与</span>
{{/if}}
<p class="coupon-mold">{{shareCoupon}}</p>
<p class="coupon-limit">{{couponDescribe}}</p>
</div>
</div>
{{/ userCouponBoList}}
</div>
<div class="news-flash">
<span class="news-title">返利快讯</span>
<ul class="news">
{{# newsFlash}}
<li>{{flashDetail}}</li>
{{/ newsFlash}}
</ul>
</div>
<div class="tab">
<a href="{{rebeatUrl}}">我的返利收益</a>
<a href="{{strategyUrl}}">分享购攻略</a>
</div>
</div>
... ...
<div class="share-detail-page" >
{{# detailData}}
<div class="coupon-detail">
<div class="countdown">
<div class="title">距离活动时间还剩:</div>
{{#if finish}}
<span class="finish">活动已结束!</span>
{{else}}
<div class="activity-time" data-id="{{expiredTime}}">
<span></span>
<span></span>
<span></span>
<span></span>小时
<span></span>
<span></span>分钟
<span></span>
<span></span>
</div>
{{/if}}
</div>
<div class="coupon-info" data-id="{{couponId}}">
<div class="info-top">
<div class="coupon-money">
<i>&#xA5;</i>
<span>{{counum}}</span>
</div>
<span class="coupon-code">{{couponCode}}</span>
{{#if isApp}}
<a href='//m.yohobuy.com/?openby:yohobuy={"action":"go.copy","params":{"text":"{{couponCode}}","message":"复制成功"}}' class="copy">复制</a>
{{/if}}
<p class="share-way">
{{#if finish}}
<span class="failure">(劵码已失效)</span>
{{else}}
(券码可直接分享给好友)
{{/if}}
<span class="coupon-type">{{couponType}}<span>
</p>
</div>
<div class="info-bottom">
<span class="share-coupon">{{detailDes}}</span>
<span class="coupon-tip">特列商品(秒杀、限定、境外、预售等)暂不支持使用优惠券。</span>
<span class="validity">有效期: {{couponValidity}}</span>
</div>
<p class="use-way">
使用方法:<br>
复制以上优惠券码,在有货APP优惠券列表页兑换券码或结
算时优惠券栏输入扣减; <br>
券码一个账户仅可使用1次。
</p>
</div>
</div>
<div class="commodity">
<p class="title">
<span>优惠券可适用于以下产品</span>
<a class="more" href="{{moreUrl}}">更多商品<i class="iconfont">&#xe614;</i></a>
</p>
<div class="goods-container"></div>
</div>
{{/ detailData}}
</div>
... ...
<div class="gdt-c">
{{# bigPic}}
<a class="big-pic" href="{{url}}">
<img src="{{image2 src w=750 h=280 q=60}}" />
</a>
{{/ bigPic}}
{{#if couponList}}
<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.h5","params":{"code":"b78b32ed81b18dde8ac84fd33602b88b","param":{"share_id":"1037","code":"b78b32ed81b18dde8ac84fd33602b88b","title":"领券中心","type":"5"},"share":"/operations/api/v5/webshare/getShare","shareparam":{"share_id":"1037"},"title":"领券中心","type":"5","url":"http://m.yohobuy.com/coupon/floor"}}'>
更多优惠券
<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>
{{/if}}
<div class="big-title">潮流优选</div>
<div class="goods clearfix">
{{# goodList}}
<a class="good-item" href="{{url}}">
<div class="pic">
<img class="lazy" data-original="{{image2 defaultImages w=330 h=379 q=90}}" />
</div>
<div class="price">¥{{salesPrice}}
{{#if marketPrice}}
<span>¥{{marketPrice}}</span>
{{/if}}
</div>
<div class="tip-bg">
<div class="tip">
<div class="tip-c">
<div>{{productName}}</div>
</div>
<div class="ico"></div>
</div>
</div>
<div class="discount">{{{discount}}}</div>
</a>
{{/ goodList}}
</div>
</div>
... ...
... ... @@ -15,6 +15,10 @@ let configFile = `
{
"appID": "EX33S4LRW7.com.yoho.buy",
"paths": [ "*" ]
},
{
"appID": "FP8T8KM2NE.com.yoho.buy.c3",
"paths": [ "*" ]
}
]
}
... ...
... ... @@ -21,6 +21,9 @@ const index = (req, res) => {
signurl: helpers.urlFormat('/signin.html')
};
// 唤起 APP 的路径
res.locals.appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.shopcart","params":{}}';
res.render('index', Object.assign(pageData, {
title: '购物车',
module: 'cart',
... ... @@ -132,9 +135,16 @@ const del = (req, res, next) => {
* [加入购物车]
*/
const add = (req, res, next) => {
if (!req.xhr) {
return next();
}
// for guang
let allowOrigin = _.get(req, 'headers.origin', null) ?
req.headers.origin : req.protocol + '://guang.' + req.headers.host;
res.setHeader('Access-Control-Allow-Origin', allowOrigin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
// if (!req.xhr) {
// return next();
// }
let shoppingKey = req.cookies._SPK || '',
uid = req.user && req.user.uid;
let productSku = req.body.productSku,
... ...
... ... @@ -184,6 +184,7 @@ exports.orderSub = (req, res, next) => {
let couponCode = req.body.couponCode || null;
let yohoCoin = req.body.yohoCoin || 0;
let skuList = req.body.skuList || '';
let isPrintPrice = req.body.isPrintPrice || 'Y';
let orderInfo;
try {
... ... @@ -259,6 +260,7 @@ exports.orderSub = (req, res, next) => {
// 接口需要的其他参数
let otherParams = {
isPrintPrice: isPrintPrice,
unionKey: unionKey, // 友盟数据
userAgent: userAgent,
isWechat: req.yoho.isWechat,
... ...
... ... @@ -64,7 +64,7 @@ exports.cartPay = (uid, cartType, orderInfo, limitProductCode, sku, skn, buyNumb
}
// cookie保存的数据
if (orderInfo) {
if (orderInfo && !_.isEmpty(orderInfo)) {
orderInfo.paymentType = orderInfo.paymentType ? orderInfo.paymentType : '';
orderComputeAPI = shoppingAPI.orderComputeAPI(
uid,
... ...
... ... @@ -21,7 +21,8 @@ const indexData = (uid, shoppingKey, saleChannel, cartType) => {
method: 'app.Shopping.queryCart',
uid: uid,
shopping_key: shoppingKey,
sale_channel: saleChannel
sale_channel: saleChannel,
is_support_mlp: 'Y'
}).then((data) => {
return data.code === 200 ? cartProcess.processData(data, cartType) : void 0;
});
... ... @@ -40,7 +41,8 @@ const selectGood = (uid, sku, shoppingKey, cartType) => {
method: 'app.Shopping.selectedAndQryCart',
product_sku_list: sku,
uid: uid,
shopping_key: shoppingKey
shopping_key: shoppingKey,
is_support_mlp: 'Y'
}).then((data) => {
return data.code === 200 ? cartProcess.processData(data, cartType) : void 0;
});
... ... @@ -59,7 +61,8 @@ const removeFromCart = (uid, sku, shoppingKey, cartType) => {
method: 'app.Shopping.removeAndQryCart',
product_sku_list: sku,
uid: uid,
shopping_key: shoppingKey
shopping_key: shoppingKey,
is_support_mlp: 'Y'
}).then((data) => {
return data.code === 200 ? cartProcess.processData(data, cartType) : void 0;
});
... ... @@ -170,7 +173,8 @@ const addToFav = (uid, sku, shoppingKey, cartType) => {
method: 'app.Shopping.addfavoriteAndQryCart',
product_sku_list: sku,
uid: uid,
shopping_key: shoppingKey
shopping_key: shoppingKey,
is_support_mlp: 'Y'
}).then((data) => {
return data.code === 200 ? cartProcess.processData(data, cartType) : void 0;
});
... ...
... ... @@ -164,7 +164,8 @@ exports.orderSub = (uid, addressId, cartType, deliveryTime,
payment_type: paymentType,
remark: remark,
uid: uid,
udid: otherParams.udid
udid: otherParams.udid,
is_print_price: otherParams.isPrintPrice
};
/* tar add 161130 结算优化 */
... ...
... ... @@ -8,8 +8,8 @@
</p>
{{/unless}}
<div class="cart-box">
</div>
<div class="recommend-for-you box hide"></div>
<div class="recommend-for-you box hide"></div>
<div id="chose-panel"></div>
</div>
... ...
... ... @@ -150,6 +150,15 @@
<form id="msg" action="" method="post">
<input type="text" name="msg" value="{{msg}}" maxlength="40" placeholder="留言">
</form>
<ul class="sale-invoice">
<li class="no-print-price">
<span class="title">不打印价格</span>
<span class="desc">送朋友可不打印价格哦</span>
<span class="check">
<i class="iconfont checkbox{{#if isPrintPrice}} icon-radio{{else}} icon-cb-radio{{/if}}"></i>
</span>
</li>
</ul>
</section>
<section class="price-cal block">
<ul class="total">
... ...
... ... @@ -29,6 +29,9 @@ let index = (req, res, next) => {
};
let channel;
// 唤起 APP 的路径
res.locals.appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.attention","params":{"actiontype":"1"}}';
if (!req.query.channel) {
channel = '1';
} else if (!typeLib.channels[req.query.channel]) {
... ...
... ... @@ -7,6 +7,8 @@ const footerModel = require('../../../doraemon/models/footer_tab'); // 底部tab
const helpers = global.yoho.helpers;
let index = (req, res, next) => {
// 唤起 APP 的路径
res.locals.appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.attention","params":{"actiontype":"0"}}';
cateModel.getCateData(req.yoho.channel).then((result) => {
res.render('cate', {
... ...
/**
* 逛详情页
* @author: chenfeng<feng.chen@yoho.cn>
* @date: 2016/09/07
*/
'use strict';
const co = require('bluebird').coroutine;
const helpers = global.yoho.helpers;
const mRoot = '../models';
const typeLib = require('../../../config/type-lib');
const _ = require('lodash');
const DetailModel = require(`${mRoot}/detail`);
const stringProcess = require(`${global.utils}/string-process`);
const guangProcess = require(`${global.utils}/guang-process`);
const headerModel = require('../../../doraemon/models/header'); // 头部model
const aboutModel = require('../../../doraemon/models/about');
const qs = require('querystring');
const channels = {
boys: 1,
girl: 2,
kids: 3,
lifestyle: 4
};
/**
* [处理品牌数据]
* @param {[array]} getBrand [品牌原数据]
*/
const _relatedBrand = (getBrand, isApp) => {
let relatedBrand = getBrand;
relatedBrand.forEach(brand => {
brand.thumb = brand.thumb.replace('http://', '//');
if (isApp) {
brand.url = brand.url + '?openby:yohobuy={"action":"go.brand","params":{"brand_id":"' + brand.id + '"}}';
}
});
return relatedBrand;
};
/**
* [处理标签数据]
* @param {[array]} tags [标签原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedTag = (tags, isApp) => {
let relatedTag = [];
let tagUrl;
tags.forEach(value => {
tagUrl = helpers.urlFormat('/tags/index', {query: value.name}, 'guang');
if (!isApp) {
value.url = tagUrl;
} else {
if (value.url.indexOf('openby') >= 0) {
value.url = value.url;
} else {
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"}}';
}
}
relatedTag.push(value);
});
return relatedTag;
};
/**
* [处理相关文章数据]
* @param {[array]} getOtherArticle [相关文章原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedInfo = (getOtherArticle, isApp) => {
let relatedInfo = [];
let articleUrl;
getOtherArticle.forEach(value => {
articleUrl = helpers.urlFormat('/info/index', {
id: value.id
}, 'guang');
if (isApp) {
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 + '"}}}';
} else {
value.url = articleUrl;
}
value.thumb = helpers.image(value.thumb, 279, 175);
relatedInfo.push(value);
});
return relatedInfo;
};
/**
* [处理分享内容]
* @param {[int]} id [资讯id]
* @param {[array]} getArticle [资讯内容]
*/
const _shareInfo = (id, getArticle) => {
let shareInfo = {};
shareInfo.shareLink = 'http:' + helpers.urlFormat('/info/index', {
id: id
}, 'guang');
shareInfo.shareTitle = getArticle.article_title;
shareInfo.shareDesc = getArticle.article_summary;
if (getArticle.cover_image_type === 1) {
shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 640);
} else {
shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 320);
}
return shareInfo;
};
/**
* [逛资讯详情页]
*/
const index = (req, res, next) => {
let id = req.query.id || req.params[0] || req.params.id,
gender = req.query.gender ||
req.query.channel && typeLib.channels[req.query.channel] ||
req.cookies._Channel && channels[req.cookies._Channel] ||
1,
isApp = req.query.app_version || req.query.appVersion || false, // 标识是不是APP访问的
parameter = {},
title = '逛',
isWeixin = req.yoho.isWechat,
channel = req.query.channel || req.cookies._Channel,
isqq = req.yoho.isqq,
isWeibo = req.yoho.isWeibo,
isShare;
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}"}}}`;
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
parameter = {
pageHeader: headerModel.setNav({
navTitle: title
})
};
isShare = isWeixin || isqq || isWeibo ? true : false;
co(function* () {
let detail = yield req.ctx(DetailModel).packageData(id, isApp, isWeixin, channel, isShare);
let data = {
guangDetail: true,
guang: {}
};
data.guang.isWeixin = isWeixin;
data.guang.channel = channel;
data.guang.isShare = isShare;
if (detail.code === 400) {
return next();
}
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
if (isShare && detail && detail.sideNav) {
data.sideNav = detail.sideNav;
}
// 作者信息数据
if (detail && detail.getAuthor && (typeof detail.getAuthor.name !== 'undefined')) {
data.guang.author = {
avatar: detail.getAuthor.avatar.replace('http://', '//'),
name: detail.getAuthor.name,
intro: detail.getAuthor.author_desc
};
// guang双头部的问题 20160601
// 正确的URL
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
data.guang.author.url = helpers.https(url);
}
let guang = data.guang;
guang.detail = {
id: _.get(detail, 'getArticle.id'),
title: detail.getArticle.article_title,
publishTime: detail.getArticle.publishTime,
pageView: detail.getArticle.pageViews,
content: []
};
if (!detail.getArticleContent) {
return next();
}
let processContents = guangProcess.processArticleDetail(detail.getArticleContent,
isApp,
gender,
isWeixin,
isqq,
isWeibo);
let goodsList = yield req.ctx(DetailModel).productInfoBySkns(processContents.allgoods);
guang.detail.content = guangProcess.pushGoodsInfo(processContents.finalDetail, goodsList, isApp);
// 相关品牌
if (detail.getBrand && detail.getBrand.length) {
guang.relatedBrand = _relatedBrand(detail.getBrand, isApp);
}
// 相关标签
if (detail.getArticle.tags && detail.getArticle.tags.length) {
guang.relatedTag = _relatedTag(detail.getArticle.tags, isApp);
}
// 相关文章
if (detail.getOtherArticle && detail.getOtherArticle.length) {
guang.relatedInfo = _relatedInfo(detail.getOtherArticle, isApp);
}
// 分享参数
if (detail.getArticle.cover_image) {
let shareInfo = _shareInfo(id, detail.getArticle);
Object.assign(guang, shareInfo);
data.title = detail.getArticle.article_title + ' | Yoho!Buy有货 | 潮流购物逛不停';
data.title_more = true;
data.description = detail.getArticle.article_summary;
data.description_more = true;
}
// 标识有微信分享
data.hasWxShare = true;
let resu = yield aboutModel.about(req.yoho.isApp);
data.guang.wxFooter = resu;
res.render('info/index', Object.assign({
page: 'info-index',
gender: gender,
wechatShare: true,
isWeixin: isWeixin,
localCss: true,
isShare: isShare
}, data, parameter));
})().catch(next);
};
// 301到新路由
const indexRedirect = (req, res, next) => {
let id = req.query.id;
if (id) {
let redirectUrl = '/guang/info/';
if (req.yoho.channel !== req.cookies._Channel) {
redirectUrl += `${req.yoho.channel}-`;
}
delete req.query.id;
let param = qs.stringify(req.query);
if (param) {
param = '?' + param;
}
redirectUrl += `${id}.html${param}`;
res.redirect(301, redirectUrl);
} else {
return next();
}
};
/**
* [逛mini内容页]
*/
const mini = (req, res, next) => {
let id = req.query.id,
gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1,
isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
co(function* () {
let detail = yield req.ctx(DetailModel).packageData(id, isApp);
let data = {
guangEzine: true,
guang: {}
};
if (detail.code !== 400) {
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
let guang = data.guang;
guang.detail = {
title: detail.getArticle.article_title,
publishTime: detail.getArticle.publishTime,
pageView: detail.getArticle.pageViews,
content: []
};
if (detail.getArticleContent) {
let processContents = guangProcess.processArticleDetail(detail.getArticleContent,
isApp,
gender);
let goodsList = yield req.ctx(DetailModel).productInfoBySkns(processContents.allgoods);
guang.detail.content = guangProcess.pushGoodsInfo(processContents.finalDetail, goodsList, isApp);
// 相关品牌
if (detail.getBrand && detail.getBrand.length) {
guang.relatedBrand = _relatedBrand(detail.getBrand, isApp);
}
// 分享参数
if (detail.getArticle.cover_image) {
let shareInfo = _shareInfo(id, detail.getArticle);
Object.assign(guang, shareInfo);
}
// 标识有微信分享
data.hasWxShare = true;
res.render('info/index', Object.assign({
page: 'info-index',
title: '逛',
gender: gender,
wechatShare: true
}, data));
} else {
return next();
}
}
})().catch(next);
};
/**
* [提供给YOHO资讯站调用的接口]
*/
const foryoho = (req, res, next) => {
let id = req.query.id,
gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1,
isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
co(function* () {
let detail = yield req.ctx(DetailModel).packageData(id, isApp);
let data = {};
if (detail.code !== 400) {
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
data.brand = detail.getBrand;
if (detail.getArticleContent) {
// 生成内容部分
let processContents = guangProcess.processArticleDetail(detail.getArticleContent,
isApp,
gender);
let goodsList = yield req.ctx(DetailModel).productInfoBySkns(processContents.allgoods);
data.content = guangProcess.pushGoodsInfo(processContents.finalDetail, goodsList, isApp);
// 内容中的相关推荐和悬浮商品移到data层级
let relatedRecoIndex = data.content.findIndex((cont) => {
return typeof cont.relatedReco !== 'undefined';
});
let collocationIndex = data.content.findIndex((cont) => {
return typeof cont.collocation !== 'undefined';
});
if (relatedRecoIndex > 0) {
data.goods = data.content[relatedRecoIndex].relatedReco;
data.content.splice(relatedRecoIndex, 1);
}
if (collocationIndex > 0) {
data.group = data.content[collocationIndex].collocation;
data.content.splice(collocationIndex, 1);
}
res.json(data);
} else {
return next();
}
}
})().catch(next);
};
module.exports = {
index,
mini,
foryoho,
indexRedirect
};
... ...
... ... @@ -7,7 +7,7 @@
const mRoot = '../models';
const typeLib = require('../../../config/type-lib');
const indexModel = require(`${mRoot}/index`);
const IndexModel = require(`${mRoot}/index`);
const headerModel = require('../../../doraemon/models/header'); // 头部model
const footerModel = require('../../../doraemon/models/footer_tab'); // 底部tab
const guangProcess = require(`${global.utils}/guang-process`);
... ... @@ -44,8 +44,8 @@ const editor = (req, res, next) => {
};
}
return Promise.all([
indexModel.getAuthor(id),
indexModel.getArticleList(gender, 0, uid, udid, 1, null, id)]
req.ctx(IndexModel).getAuthor(id),
req.ctx(IndexModel).getArticleList(gender, 0, uid, udid, 1, null, id)]
).then(datas => {
let authorData = datas[0],
articleListData = datas[1];
... ... @@ -67,7 +67,9 @@ const editor = (req, res, next) => {
res.render('index/list', Object.assign({
page: 'index-editor',
title: title,
title: `潮流编辑${authorData.data.name}|YOHO!BUY有货`,
keywords: `潮流编辑${authorData.data.name}`,
description: `YOHO!BUY有货潮流编辑${authorData.data.name}!`,
guangList: true,
gender: gender,
guang: {
... ... @@ -157,7 +159,7 @@ const pageData = (req, res, next) => {
if (!authorId && isNaN(authorId)) {
showAuthor = true;
}
return indexModel.getPageData(gender,
return req.ctx(IndexModel).getPageData(gender,
sortId,
uid,
udid,
... ... @@ -193,7 +195,9 @@ const index = (req, res, next) => {
let responseData = {
module: 'guang',
page: 'index',
title: '逛 | Yoho!Buy有货 | 潮流购物逛不停',
title: '逛|逛潮流,逛购物,官方授权正品潮流购物中心|YOHO!BUY有货',
keywords: '逛,逛潮流,逛购物',
description: 'YOHO!BUY有货逛频道,来YOHO!玩潮流!潮搭大解析!年轻人潮流购物中心,中国潮流购物风向标,吴亦凡重磅代言!YOHO!BUY有货100%正品保证,支持货到付款。',
showFooterTab: footerModel.getUrlData('guang')
};
... ... @@ -204,12 +208,16 @@ const index = (req, res, next) => {
gender: req.query.gender || req.query.channel && typeLib.gender[req.query.channel] || '1,3'
};
indexModel.getArticle(param).then(result => {
req.ctx(IndexModel).getArticle(param).then(result => {
if (result && result.guang && result.guang.infos) {
if (!result.guang.infos.length) {
res.set('Cache-Control', 'no-cache');
}
}
// 唤起 APP 的路径
res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy= {"action":"go.guangchannel","params":{"id":${param.type}}}`;
res.render('guang', Object.assign(responseData, result, {
localCss: true
}));
... ... @@ -234,7 +242,9 @@ const tag = (req, res, next) => {
pageHeader: headerData,
module: 'guang',
page: 'index-editor',
title: tagTitle + ' | Yoho!Buy有货 | 潮流购物逛不停'
title: tagTitle + ' | Yoho!Buy有货 | 潮流购物逛不停',
keywords: tagTitle,
description: 'YOHO!BUY有货潮流' + tagTitle + '!'
};
let param = {
... ... @@ -250,8 +260,10 @@ const tag = (req, res, next) => {
responseData.pageHeader.navTitle = param.tag || '标签';
indexModel.getTagEditor(param).then(result => {
res.render('index/list', Object.assign(responseData, result));
req.ctx(IndexModel).getTagEditor(param).then(result => {
res.render('index/list', Object.assign(responseData, result, {
localCss: true
}));
}).catch(next);
};
... ... @@ -281,7 +293,7 @@ const listDynamicData = (req, res) => {
other.type = type;
}
indexModel.getDynamicDataByIds(ids, udid, other).then(ret => {
req.ctx(IndexModel).getDynamicDataByIds(ids, udid, other).then(ret => {
res.send(ret);
});
};
... ... @@ -297,7 +309,7 @@ const detailDynamicData = (req, res) => {
uid = req.user.uid || req.query.uid,
udid = req.sessionID;
indexModel.getDynamicDataById(id, uid, udid).then((ret) => {
req.ctx(IndexModel).getDynamicDataById(id, uid, udid).then((ret) => {
res.status(200).send(ret);
}).catch(() => {
res.status(400);
... ...
/**
* 逛详情页
* @author: chenfeng<feng.chen@yoho.cn>
* @date: 2016/09/07
*/
'use strict';
const helpers = global.yoho.helpers;
const mRoot = '../models';
const typeLib = require('../../../config/type-lib');
const _ = require('lodash');
const infoModel = require(`${mRoot}/info`);
const stringProcess = require(`${global.utils}/string-process`);
const guangProcess = require(`${global.utils}/guang-process`);
const productDetailModel = require('../../product/models/detail');
const headerModel = require('../../../doraemon/models/header'); // 头部model
const aboutModel = require('../../../doraemon/models/about');
const qs = require('querystring');
const channels = {
boys: 1,
girl: 2,
kids: 3,
lifestyle: 4
};
/**
* [生成逛资讯内容]
* @param {[array]} articleContent [迭代内容]
* @param {Boolean} isApp [是否在app]
* @param {[Boolean]} gender [性别]
*/
const _pageArticleContent = (articleContent, isApp, gender, isWeixin, isqq, isWeibo) => {
let contents = [];
return new Promise((resolve) => {
let joinContentFunc = (i, len) => {
if (i < len) {
let build = {};
let art = articleContent[i];
// 文字
if (art.text && art.text.data && art.text.data.text) {
build.text = art.text.data.text;
contents.push(build);
joinContentFunc(++i, len);
} else if (art.singleImage && art.singleImage.data && art.singleImage.data.length) { // 单张图
build.bigImage = helpers.image(art.singleImage.data[0].src, 640, 640);
// 前三张图片不使用懒加载,下同
if (i <= 3) {
build.noLazy = true;
}
contents.push(build);
joinContentFunc(++i, len);
} else if (art.smallPic && art.smallPic.data && art.smallPic.data.length > 1) {
let imgs = art.smallPic.data;
if (i <= 3) {
build.noLazy = true;
}
build.smallImage = [{
src: helpers.image(imgs[0].src, 315, 420)
}, {
src: helpers.image(imgs[1].src, 315, 420)
}];
contents.push(build);
joinContentFunc(++i, len);
} else if (art.weixinPublic) {
build.weixinPublic = art.weixinPublic;
contents.push(build);
joinContentFunc(++i, len);
} else if (art.shareCode) {
let shareCode;
if (art.shareCode.qqShareImgUrl ||
art.shareCode.wechatShareImgUrl ||
art.shareCode.showShareImgUrl) {
if (isWeixin) {
shareCode = art.shareCode.wechatShareImgUrl;
} else if (isqq) {
shareCode = art.shareCode.qqShareImgUrl;
} else if (isWeibo) {
shareCode = art.shareCode.showShareImgUrl;
}
}
if (shareCode) {
build.shareCode = [{
codeShare: shareCode
}];
} else {
build.shareCode = false;
}
contents.push(build);
joinContentFunc(++i, len);
} else if (art.goods && art.goods.data) { // 相关推荐
let reco = [],
skns = [],
arr = [];
// 遍历取得SKN
art.goods.data.forEach(goods => {
skns.push(goods.id);
arr[goods.id] = goods.src;
});
// 通过SKN获取商品信息
productDetailModel.productInfoBySkns(skns).then((product) => {
if (product && product.data) {
if (product.data.product_list) {
let d = [];
for (let o = 0; o < product.data.product_list.length; o++) {
let goods = product.data.product_list[o];
// 最多显示4个
if (o > 3) {
break;
}
d.push(guangProcess.formatProduct(goods,
false,
true,
true,
235,
314,
isApp,
true,
gender));
}
d.forEach(p => {
if (arr[p.id]) {
p.thumb = helpers.image(arr[p.id], 235, 314);
reco.push(p);
}
});
}
// 多个商品
if (product.data.product_list &&
product.data.product_list.length &&
(product.data.product_list.length > 1)) {
build.relatedReco = reco;
} else if (product.data.product_list && product.data.product_list.length === 1) { // 单个商品
build.relatedReco = reco[0];
}
}
contents.push(build);
joinContentFunc(++i, len);
});
} else if (art.goodsGroup && art.goodsGroup.data) { // 悬停浮动商品
let callArtGoodGroup = (ii, len2) => {
if (ii < len2) {
let goods = art.goodsGroup.data[ii];
if (goods) {
let good = {
thumb: goods.cover ? helpers.image(goods.cover.cover, 235, 314) : '',
type: goods.cover ? guangProcess.getProductIcon(goods.cover.maxSortId) : '',
goods: []
};
let skns = [];
let arr = [];
goods.list.forEach((mini) => {
if (mini) {
skns.push(mini.id);
arr[mini.id] = mini.src;
}
});
// 通过SKN获取商品信息
productDetailModel.productInfoBySkns(skns).then((product) => {
if (product && product.data && product.data.product_list) {
let g = [];
product.data.product_list.forEach(p => {
g.push(guangProcess.formatProduct(p,
false,
true,
true,
235,
314,
isApp,
gender));
});
g.forEach(p => {
if (arr[p.id]) {
p.thumb = helpers.image(arr[p.id], 235, 314);
good.goods.push(p);
}
});
if (!build.collocation) {
build.collocation = [];
}
build.collocation.push(good);
}
callArtGoodGroup(++ii, len2);
});
} else {
callArtGoodGroup(++ii, len2);
}
} else {
contents.push(build);
joinContentFunc(++i, len);
}
};
callArtGoodGroup(0, art.goodsGroup.data.length);
} else if (art.link) { // 更多商品链接
build.moreLink = art.link.data[0].url;
contents.push(build);
joinContentFunc(++i, len);
} else {
joinContentFunc(++i, len);
}
} else {
resolve(contents);
}
};
joinContentFunc(0, articleContent.length);
});
};
/**
* [处理品牌数据]
* @param {[array]} getBrand [品牌原数据]
*/
const _relatedBrand = (getBrand, isApp) => {
let relatedBrand = getBrand;
relatedBrand.forEach(brand => {
brand.thumb = brand.thumb.replace('http://', '//');
if (isApp) {
brand.url = brand.url + '?openby:yohobuy={"action":"go.brand","params":{"brand_id":"' + brand.id + '"}}';
}
});
return relatedBrand;
};
/**
* [处理标签数据]
* @param {[array]} tags [标签原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedTag = (tags, isApp) => {
let relatedTag = [];
let tagUrl;
tags.forEach(value => {
tagUrl = helpers.urlFormat('/tags/index', {query: value.name}, 'guang');
if (!isApp) {
value.url = tagUrl;
} else {
if (value.url.indexOf('openby') >= 0) {
value.url = value.url;
} else {
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"}}';
}
}
relatedTag.push(value);
});
return relatedTag;
};
/**
* [处理相关文章数据]
* @param {[array]} getOtherArticle [相关文章原数据]
* @param {[Boolean]} isApp [是否app]
*/
const _relatedInfo = (getOtherArticle, isApp) => {
let relatedInfo = [];
let articleUrl;
getOtherArticle.forEach(value => {
articleUrl = helpers.urlFormat('/info/index', {
id: value.id
}, 'guang');
if (isApp) {
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 + '"}}}';
} else {
value.url = articleUrl;
}
value.thumb = helpers.image(value.thumb, 279, 175);
relatedInfo.push(value);
});
return relatedInfo;
};
/**
* [处理分享内容]
* @param {[int]} id [资讯id]
* @param {[array]} getArticle [资讯内容]
*/
const _shareInfo = (id, getArticle) => {
let shareInfo = {};
shareInfo.shareLink = 'http:' + helpers.urlFormat('/info/index', {
id: id
}, 'guang');
shareInfo.shareTitle = getArticle.article_title;
shareInfo.shareDesc = getArticle.article_summary;
if (getArticle.cover_image_type === 1) {
shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 640);
} else {
shareInfo.shareImg = 'http:' + helpers.image(getArticle.cover_image, 640, 320);
}
return shareInfo;
};
/**
* [逛资讯详情页]
*/
const index = (req, res, next) => {
let id = req.query.id || req.params[0] || req.params.id,
gender = req.query.gender ||
req.query.channel && typeLib.channels[req.query.channel] ||
req.cookies._Channel && channels[req.cookies._Channel] ||
1,
isApp = req.query.app_version || req.query.appVersion || false, // 标识是不是APP访问的
parameter = {},
title = '逛',
isWeixin = req.yoho.isWechat,
channel = req.query.channel || req.cookies._Channel,
isqq = req.yoho.isqq,
isWeibo = req.yoho.isWeibo,
isShare;
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}"}}}`;
// pagecache 前端做
// userAgent = req.get('User-Agent'),
// isWeixin = userAgent.includes('MicroMessenger'); // 标识是否是微信访问
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
parameter = {
pageHeader: headerModel.setNav({
navTitle: title
})
};
isShare = isWeixin || isqq || isWeibo ? true : false;
// WAP上设置头部导航 pagecache
// if (!isApp && !isWeixin) {
// parameter = {
// pageHeader: headerModel.setNav({
// navTitle: title
// })
// };
// }
// 获取详情内容信息, 异常则跳到错误页面
return infoModel.packageData(id, isApp, isWeixin, channel, isShare).then(detail => {
let data = {
guangDetail: true,
guang: {}
};
data.guang.isWeixin = isWeixin;
data.guang.channel = channel;
data.guang.isShare = isShare;
if (detail.code === 400) {
return next();
}
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
if (isShare && detail && detail.sideNav) {
data.sideNav = detail.sideNav;
}
// 作者信息数据
if (detail && detail.getAuthor && (typeof detail.getAuthor.name !== 'undefined')) {
data.guang.author = {
avatar: detail.getAuthor.avatar.replace('http://', '//'),
name: detail.getAuthor.name,
intro: detail.getAuthor.author_desc
};
// guang双头部的问题 20160601
// 正确的URL
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
data.guang.author.url = helpers.https(url);
}
let guang = data.guang;
guang.detail = {
id: _.get(detail, 'getArticle.id'),
title: detail.getArticle.article_title,
publishTime: detail.getArticle.publishTime,
pageView: detail.getArticle.pageViews,
content: []
};
if (!detail.getArticleContent) {
return next();
}
// 生成内容部分
return _pageArticleContent(detail.getArticleContent,
isApp,
gender,
isWeixin,
isqq,
isWeibo).then((contents) => {
guang.detail.content = contents;
// 相关品牌
if (detail.getBrand && detail.getBrand.length) {
guang.relatedBrand = _relatedBrand(detail.getBrand, isApp);
}
// 相关标签
if (detail.getArticle.tags && detail.getArticle.tags.length) {
guang.relatedTag = _relatedTag(detail.getArticle.tags, isApp);
}
// 相关文章
if (detail.getOtherArticle && detail.getOtherArticle.length) {
guang.relatedInfo = _relatedInfo(detail.getOtherArticle, isApp);
}
// 分享参数
if (detail.getArticle.cover_image) {
let shareInfo = _shareInfo(id, detail.getArticle);
Object.assign(guang, shareInfo);
data.title = detail.getArticle.article_title + ' | Yoho!Buy有货 | 潮流购物逛不停';
data.title_more = true;
data.description = detail.getArticle.article_summary;
data.description_more = true;
}
// 标识有微信分享
data.hasWxShare = true;
aboutModel.about(req.yoho.isApp).then((resu) => {
data.guang.wxFooter = resu;
res.render('info/index', Object.assign({
page: 'info-index',
title: '逛',
gender: gender,
wechatShare: true,
isWeixin: isWeixin,
localCss: true,
isShare: isShare
}, data, parameter));
});
}).catch(next);
}).catch(next);
};
// 301到新路由
const indexRedirect = (req, res, next) => {
let id = req.query.id;
if (id) {
let redirectUrl = '/guang/info/';
if (req.yoho.channel !== req.cookies._Channel) {
redirectUrl += `${req.yoho.channel}-`;
}
delete req.query.id;
let param = qs.stringify(req.query);
if (param) {
param = '?' + param;
}
redirectUrl += `${id}.html${param}`;
res.redirect(301, redirectUrl);
} else {
return next();
}
};
/**
* [逛mini内容页]
*/
const mini = (req, res, next) => {
let id = req.query.id,
gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1,
isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
// 获取详情内容信息, 异常则跳到错误页面
return infoModel.packageData(id, isApp).then(detail => {
let data = {
guangEzine: true,
guang: {}
};
if (detail.code !== 400) {
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
let guang = data.guang;
guang.detail = {
title: detail.getArticle.article_title,
publishTime: detail.getArticle.publishTime,
pageView: detail.getArticle.pageViews,
content: []
};
if (detail.getArticleContent) {
// 生成内容部分
return _pageArticleContent(detail.getArticleContent, isApp, gender).then((contents) => {
guang.detail.content = contents;
// 相关品牌
if (detail.getBrand && detail.getBrand.length) {
guang.relatedBrand = _relatedBrand(detail.getBrand, isApp);
}
// 分享参数
if (detail.getArticle.cover_image) {
let shareInfo = _shareInfo(id, detail.getArticle);
Object.assign(guang, shareInfo);
}
// 标识有微信分享
data.hasWxShare = true;
res.render('info/index', Object.assign({
page: 'info-index',
title: '逛',
gender: gender,
wechatShare: true
}, data));
});
} else {
next();
return;
}
}
}).catch(next);
};
/**
* [提供给YOHO资讯站调用的接口]
*/
const foryoho = (req, res, next) => {
let id = req.query.id,
gender = req.query.gender || req.cookies._Channel && channels[req.cookies._Channel] || 1,
isApp = req.query.app_version || req.query.appVersion || false; // 标识是不是APP访问的
// 判断参数是否有效, 无效会跳转到错误页面
if (!stringProcess.isNumeric(id)) {
res.json({
code: 400,
message: '非法请求',
data: ''
});
return;
}
// 获取详情内容信息, 异常则跳到错误页面
return infoModel.packageData(id, isApp).then(detail => {
let data = {};
if (detail.code !== 400) {
if (!detail.getArticle) {
// TODO 跳转到逛首页
return;
}
data.brand = detail.getBrand;
if (detail.getArticleContent) {
// 生成内容部分
return _pageArticleContent(detail.getArticleContent, isApp, gender).then((contents) => {
data.content = contents;
// 内容中的相关推荐和悬浮商品移到data层级
let relatedRecoIndex = data.content.findIndex((cont) => {
return typeof cont.relatedReco !== 'undefined';
});
let collocationIndex = data.content.findIndex((cont) => {
return typeof cont.collocation !== 'undefined';
});
if (relatedRecoIndex > 0) {
data.goods = data.content[relatedRecoIndex].relatedReco;
data.content.splice(relatedRecoIndex, 1);
}
if (collocationIndex > 0) {
data.group = data.content[collocationIndex].collocation;
data.content.splice(collocationIndex, 1);
}
res.json(data);
});
} else {
next();
return;
}
}
}).catch(next);
};
module.exports = {
index,
mini,
foryoho,
indexRedirect
};
... ... @@ -58,6 +58,9 @@ exports.index = (req, res, next) => {
break;
}
// 唤起 APP 的路径
res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.h5","params":{"url":"http://guang.m.yohobuy.com${req.path}","param":${JSON.stringify(req.query)}}}`;
plusstarModel.getAllChannels({
gender: gender,
app_type: 0
... ...
... ... @@ -45,6 +45,8 @@ const getListData = (req, res, next) => {
});
});
// 唤起 APP 的路径
res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.h5","type": 7,"params":{"url":"http://guang.m.yohobuy.com${req.path}","param":${JSON.stringify(req.query)}}}`;
res.render('plustar/list', {
module: 'guang',
... ...
... ... @@ -6,7 +6,7 @@
'use strict';
const mRoot = '../models';
const rssModel = require(`${mRoot}/rss`);
const RssModel = require(`${mRoot}/rss`);
const Feed = require('feed');
const _ = require('lodash');
const moment = require('moment');
... ... @@ -17,7 +17,7 @@ const moment = require('moment');
const index = (req, res, next) => {
let gender = req.query.gender || '1,2,3';
return rssModel.getRssArticle(gender).then((result) => {
return req.ctx(RssModel).getRssArticle(gender).then((result) => {
if (!result) {
return next();
}
... ... @@ -55,7 +55,7 @@ const rss = (req, res, next, gmt) => {
let gender = req.query.gender || '1,2,3';
res.setHeader('Content-Type', 'text/xml; charset=utf-8');
return rssModel.getRssArticle(gender).then((result) => {
return req.ctx(RssModel).getRssArticle(gender).then((result) => {
if (!result) {
return next();
}
... ...
... ... @@ -12,201 +12,224 @@ const helpers = global.yoho.helpers;
const URI_PACKAGE_ARTICLE = 'guang/service/v2/article/';
const URI_PACKAGE_AUTHOR = 'guang/service/v1/author/';
/**
* 获取二级菜单顶部颜色
* @param {[string]} choosed
* @return {[string]}
*/
const _getSidebarColor = (choosed) => {
let color = false;
if (choosed === 'girls') {
color = '#FF88AE';
} else if (choosed === 'kids') {
color = '#7ad9f9';
} else if (choosed === 'lifestyle') {
color = '#4f4138';
}
return color;
};
// 微信侧边栏导航数据
const _processSideBar = (list, choosed) => {
const formatData = [];
let offset = 0; // 分割数组用到的游标
list = list || [];
_.forEach(list, (item, i) => {
if (item.sub) {
item.sub.unshift({
sort_name: item.sort_name,
sort_name_en: item.sort_name_en,
back: true,
isSelect: false,
bgColor: _getSidebarColor(choosed)
});
}
class DetailModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
// 如果有分隔符,分割数组
if (item.separative_sign === 'Y') {
formatData.push(list.slice(offset, i));
offset = i;
/**
* 获取二级菜单顶部颜色
* @param {[string]} choosed
* @return {[string]}
*/
_getSidebarColor(choosed) {
let color = false;
if (choosed === 'girls') {
color = '#FF88AE';
} else if (choosed === 'kids') {
color = '#7ad9f9';
} else if (choosed === 'lifestyle') {
color = '#4f4138';
}
});
// 数组被分割剩余的部分
formatData.push(list.slice(offset));
return formatData;
};
const _getLeftNav = (choosed) => {
choosed = choosed || 'all';
return serviceAPI.get('operations/api/v6/category/getCategory', {}, {
cache: true
}).then(result => {
if (result && result.code === 200) {
return color;
}
return _processSideBar(result.data, choosed);
}
});
};
/**
* 微信侧边栏导航数据
* @param {*} list
* @param {*} choosed
*/
_processSideBar(list, choosed) {
const formatData = [];
let offset = 0; // 分割数组用到的游标
list = list || [];
_.forEach(list, (item, i) => {
if (item.sub) {
item.sub.unshift({
sort_name: item.sort_name,
sort_name_en: item.sort_name_en,
back: true,
isSelect: false,
bgColor: this._getSidebarColor(choosed)
});
}
const _getShareData = (id) => {
// 如果有分隔符,分割数组
if (item.separative_sign === 'Y') {
formatData.push(list.slice(offset, i));
offset = i;
}
});
return serviceAPI.get('guang/api/v6/share/guang', {
id: id
}).then(result => {
if (result && result.code === 200) {
// 数组被分割剩余的部分
formatData.push(list.slice(offset));
return formatData;
}
return result.data;
}
});
};
_getLeftNav(choosed) {
choosed = choosed || 'all';
return serviceAPI.get('operations/api/v6/category/getCategory', {}, {
cache: true
}).then(result => {
if (result && result.code === 200) {
/**
* [逛资讯详情页数据封装]
* @param {[int]} id [内容ID]
* @param {Boolean} isApp [标识是否是APP访问]
* @return {[array]}
*/
const packageData = (id, isApp, isWeixin, channel, isShare) => {
let result = {
getAuthor: {},
getArticle: {},
getArticleContent: {},
getBrand: {},
getOtherArticle: {}
};
// 获取资讯
let param = {
article_id: id
// private_key: sign.privateKey[clientType]
};
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticle`, param, {
cache: true
}).then(data => {
// 接口要判断一下返回状态是否成功
if (!data || data.code !== 200) {
result.code = 400;
return result;
}
let article = data.data || {};
return this._processSideBar(result.data, choosed);
}
});
}
result.getArticle = article;
_getShareData(id) {
return serviceAPI.get('guang/api/v6/share/guang', {
id: id
}).then(result => {
if (result && result.code === 200) {
let promises = [];
return result.data;
}
});
}
// 获取作者信息
param = {
author_id: article.author_id
};
/**
* 获取文章接口调用
* @param {*} articleId
*/
_getArticle(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticle`, {
article_id: articleId
}, {
cache: true
});
}
// param.client_secret = sign.apiSign(param);
promises.push(serviceAPI.get(`${URI_PACKAGE_AUTHOR}getAuthor`, param, {
/**
* 获取作者接口调用
* @param {*} authorId
*/
_getAuthor(authorId) {
return serviceAPI.get(`${URI_PACKAGE_AUTHOR}getAuthor`, {
author_id: authorId
}, {
cache: true
}));
});
}
// 获取资讯内容
param = {
article_id: id
/**
* 获取文章详情接口调用
* @param {*} articleId
*/
_getArticleContent(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, {
article_id: articleId
}, {
cache: true
});
}
// private_key: sign.privateKey[clientType]
};
/**
* 获取文章相关品牌接口调用
* @param {*} articleId
*/
_getBrand(articleId) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getBrand`, {
article_id: articleId
}, {
cache: true
});
}
// param.client_secret = sign.apiSign(param);
promises.push(serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, param, {
/**
* 获取资讯相关的其它资讯接口调用
* @param {*} articleId
* @param {*} tag
*/
_getOtherArticle(articleId, tag) {
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getOtherArticle`, {
article_id: articleId,
tags: tag,
offset: 0,
limit: 3
}, {
cache: true
}));
});
}
// 获取资讯相关的品牌
param = {
article_id: id
/**
* APP 获取微信模块
*/
_getSingleTemplateWechat() {
return api.get('', {
method: 'app.resources.getSingleTemplate',
module: 'wechat',
key: 'guang_detail_wechat'
});
}
// private_key: sign.privateKey[clientType]
/**
* [逛资讯详情页数据封装]
* @param {[int]} id [内容ID]
* @param {Boolean} isApp [标识是否是APP访问]
* @return {[array]}
*/
packageData(id, isApp, isWeixin, channel, isShare) {
let result = {
getAuthor: {},
getArticle: {},
getArticleContent: {},
getBrand: {},
getOtherArticle: {}
};
// param.client_secret = sign.apiSign(param);
promises.push(serviceAPI.get(`${URI_PACKAGE_ARTICLE}getBrand`, param, {
cache: true
}));
// 获取资讯相关的其它资讯
if (typeof article.tag !== 'undefined') {
param = {
article_id: id,
tags: article.tag,
offset: 0,
limit: 3
// private_key: sign.privateKey[clientType]
};
// param.client_secret = sign.apiSign(param);
promises.push(serviceAPI.get(`${URI_PACKAGE_ARTICLE}getOtherArticle`, param, {
cache: true
}));
}
if (isApp) {
promises.push(api.get('', {
method: 'app.resources.getSingleTemplate',
module: 'wechat',
key: 'guang_detail_wechat'
}));
}
// 获取资讯
return this._getArticle(id).then(data => {
// 调用接口失败
if (!data || data.code !== 200) {
result.code = 400;
return result;
}
let article = result.getArticle = data && data.data || {};
let promises = [
this._getAuthor(article.author_id),
this._getArticleContent(id),
this._getBrand(id)
];
// 获取资讯相关的其它资讯
if (typeof article.tag !== 'undefined') {
promises.push(this._getOtherArticle(id, article.tag));
}
if (isShare) {
let navGender = _.cloneDeep(channel);
// APP 获取微信模块
if (isApp) {
promises.push(this._getSingleTemplateWechat());
}
promises.push(_getLeftNav(navGender));
}
if (isShare) {
let navGender = _.cloneDeep(channel);
if (isShare) {
promises.push(_getShareData(id));
}
promises.push(
this._getLeftNav(navGender),
this._getShareData(id)
);
}
return Promise.all(promises).then(datas => {
return Promise.all(promises).then(datas => {
let getArticleContent = [];
let getArticleContent = [];
if (!datas) {
return result;
}
if (datas) {
if (datas[1]) {
getArticleContent = datas[1].data;
result.getArticleContent = getArticleContent;
result.getArticleContent = getArticleContent = datas[1].data;
}
if (isApp && datas[4] && datas[4].data) {
let preCount = 0;
let i;
... ... @@ -227,16 +250,17 @@ const packageData = (id, isApp, isWeixin, channel, isShare) => {
}
if (isShare && datas[5]) {
if (datas[5].wechatShareImgUrl) {
datas[5].wechatShareImgUrl =
datas[5].wechatShareImgUrl.substring(datas[5].wechatShareImgUrl.indexOf('//'));
if (datas[5].wechatShareImgUrl.indexOf('?') === -1) {
datas[5].wechatShareImgUrl = datas[5].wechatShareImgUrl + '?imageView2/2/interlace/1/q/75';
datas[5].wechatShareImgUrl = datas[5].wechatShareImgUrl +
'?imageView2/2/interlace/1/q/75';
}
} else if (datas[5].qqShareImgUrl) {
datas[5].qqShareImgUrl = datas[5].qqShareImgUrl.substring(datas[5].qqShareImgUrl.indexOf('//'));
datas[5].qqShareImgUrl =
datas[5].qqShareImgUrl.substring(datas[5].qqShareImgUrl.indexOf('//'));
if (datas[5].qqShareImgUrl.indexOf('?') === -1) {
datas[5].qqShareImgUrl = datas[5].wechatShareImgUrl + '?imageView2/2/interlace/1/q/75';
... ... @@ -263,7 +287,6 @@ const packageData = (id, isApp, isWeixin, channel, isShare) => {
getArticleContent.splice(preCount, 0, {
shareCode: datas[5]
});
}
if (datas[0]) {
... ... @@ -284,30 +307,47 @@ const packageData = (id, isApp, isWeixin, channel, isShare) => {
result.getOtherArticle = datas[3].data;
}
}
}
return result;
return result;
});
});
});
};
}
/**
* [获取详情信息]
* @param {[int]} id [资讯id]
* @return {[object]}
*/
const intro = (id) => {
let param = {
article_id: id,
client_type: 'h5'
};
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, param, {
cache: true
});
};
module.exports = {
packageData,
intro
};
/**
* [获取详情信息]
* @param {[int]} id [资讯id]
* @return {[object]}
*/
intro(id) {
let param = {
article_id: id,
client_type: 'h5'
};
return serviceAPI.get(`${URI_PACKAGE_ARTICLE}getArticleContent`, param, {
cache: true
});
}
/**
* [根据商品SKN获取商品的简要信息]
* @param {[array]} sknString [skns]
* @return {[type]}
*/
productInfoBySkns(sknString) {
// 调用搜索接口
let param = {
method: 'h5.product.batch',
productSkn: sknString,
order: 's_t_desc'
};
return api.get('', param, {
cache: true
}).then(result => {
return _.get(result, 'data.product_list', []);
});
}
}
module.exports = DetailModel;
... ...
... ... @@ -11,354 +11,351 @@ const helpers = global.yoho.helpers;
const guangProcess = require(`${global.utils}/guang-process`);
const _ = require('lodash');
/**
* [获取作者信息]
* @param {[int]} id [作者id]
* @return {[object]}
*/
const getAuthor = (id) => {
return serviceAPI.get('guang/service/v1/author/getAuthor', {
author_id: id
}, {
cache: true
}).then((result) => {
if (result && result.code === 200) {
return result;
} else {
logger.error('getAuthor code no 200');
return {};
}
});
};
class IndexModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 逛分类
*/
const _category = () => {
return serviceAPI.get('/guang/api/v1/category/get', {
/**
* [获取作者信息]
* @param {[int]} id [作者id]
* @return {[object]}
*/
getAuthor(id) {
return serviceAPI.get('guang/service/v1/author/getAuthor', {
author_id: id
}, {
cache: true
}).then((result) => {
if (result && result.code === 200) {
return result;
} else {
logger.error('getAuthor code no 200');
return {};
}
});
}
}, {
cache: true,
code: 200
});
};
/**
* [逛内容列表]
* @param {[string]} gender ["1,3"表示男, "2,3"表示女, "1,2,3"表示所有]
* @param {[int]} sortId [分类ID]
* @param {Number} uid [用户ID]
* @param {String} udid [客户端唯一标识]
* @param {Number} page [分页第几页, 默认第1页]
* @param {[string]} tag [标签]
* @param {[int]} authorId [作者ID]
* @param {[int]} limit [返回的限制数]
* @param {Boolean} useCache [是否使用缓存]
* @return {[array]}
*/
getArticleList(gender, sortId, uid, udid, page, tag, authorId, limit, useCache) {
let param = {
page: page || 1,
uid: uid || 0,
udid: udid || '',
gender: gender || '',
sort_id: sortId,
tag: tag,
author_id: authorId,
limit: 4
};
/**
* [逛内容列表]
* @param {[string]} gender ["1,3"表示男, "2,3"表示女, "1,2,3"表示所有]
* @param {[int]} sortId [分类ID]
* @param {Number} uid [用户ID]
* @param {String} udid [客户端唯一标识]
* @param {Number} page [分页第几页, 默认第1页]
* @param {[string]} tag [标签]
* @param {[int]} authorId [作者ID]
* @param {[int]} limit [返回的限制数]
* @param {Boolean} useCache [是否使用缓存]
* @return {[array]}
*/
const getArticleList = (gender, sortId, uid, udid, page, tag, authorId, limit, useCache) => {
let param = {
page: page || 1,
uid: uid || 0,
udid: udid || '',
gender: gender || '',
sort_id: sortId,
tag: tag,
author_id: authorId,
limit: 4
};
return serviceAPI.get('guang/api/v2/article/getList', param, {
cache: useCache
}).then((result) => {
if (result && result.code === 200) {
return result;
} else {
logger.error('getAuthor code no 200');
return [];
}
});
return serviceAPI.get('guang/api/v2/article/getList', param, {
cache: useCache
}).then((result) => {
if (result && result.code === 200) {
return result;
} else {
logger.error('getAuthor code no 200');
return [];
}
});
};
}
/**
* [获取切换逛类别或者分页时的文章数据]
* @param {[string]} gender ["1,3"表示男, "2,3"表示女]
* @param {[int]} sortId [分类ID]
* @param {[int]} uid [用户ID]
* @param {[string]} udid [客户端唯一标识]
* @param {[int]} page [分页第几页, 默认第1页]
* @param {[string]} tag [标签]
* @param {[string]} authorId [作者ID]
* @param {Boolean} isApp [是否是APP]
* @param {[Boolean]} showAuthor [是否显示作者]
* @param {Boolean} isTab [是否为tab切换操作]
* @return {[array]}
*/
const getPageData = (gender, sortId, uid, udid, page, tag, authorId, isApp, showAuthor, isTab) => {
return getArticleList(gender, sortId, uid, udid, page, tag, authorId).then(article => {
let result = {};
/**
* [获取切换逛类别或者分页时的文章数据]
* @param {[string]} gender ["1,3"表示男, "2,3"表示女]
* @param {[int]} sortId [分类ID]
* @param {[int]} uid [用户ID]
* @param {[string]} udid [客户端唯一标识]
* @param {[int]} page [分页第几页, 默认第1页]
* @param {[string]} tag [标签]
* @param {[string]} authorId [作者ID]
* @param {Boolean} isApp [是否是APP]
* @param {[Boolean]} showAuthor [是否显示作者]
* @param {Boolean} isTab [是否为tab切换操作]
* @return {[array]}
*/
getPageData(gender, sortId, uid, udid, page, tag, authorId, isApp, showAuthor, isTab) {
return this.getArticleList(gender, sortId, uid, udid, page, tag, authorId).then(article => {
let result = {};
if (!_.get(article, 'data.list.artList', false)) {
return result;
}
if (!_.get(article, 'data.list.artList', false)) {
return result;
}
let adList = article.data.list.adlist;
let adList = article.data.list.adlist;
// 广告列表
if (isTab && adList) {
result.swiper = adList.map(function(ad) {
return {
url: guangProcess.getFilterUrl(ad.url),
img: helpers.image(ad.src, 830, 327)
};
});
}
// 广告列表
if (isTab && adList) {
result.swiper = adList.map(function(ad) {
return {
url: guangProcess.getFilterUrl(ad.url),
img: helpers.image(ad.src, 830, 327)
};
});
}
/* 构建资讯文章内容 */
let artList = article.data.list.artList;
/* 构建资讯文章内容 */
let artList = article.data.list.artList;
result.infos = artList.map(function(art) {
return guangProcess.formatArticle(art, true, isApp, showAuthor, uid);
});
result.infos = artList.map(function(art) {
return guangProcess.formatArticle(art, true, isApp, showAuthor, uid);
return result;
});
}
return result;
});
};
/**
* 逛
* @param params
*/
getArticle(param) {
/**
* 逛内容列表
*/
const _article = (param) => {
return serviceAPI.get('/guang/api/v2/article/getList', {
gender: param.gender,
page: param.page || 1,
uid: param.uid,
udid: param.udid,
sort_id: param.type || 0,
tag: param.tag ? param.tag : null,
limit: 4
let page = param.page ? param.page : 1;
// author_id: param.authorId ? param.authorId : null,
// limit: param.limit ? param.limit : null
}, {
cache: true,
code: 200
}).then(result => {
Object.assign(param, {
page: page
});
return result;
return api.all([
this._category(),
this._article(param)
]).then(result => {
});
};
let type = param.type;
let resu = {
guang: {
gender: param.gender,
}
};
/**
* 逛
* @param params
*/
const getArticle = (param) => {
// 顶部的分类列表
let curIndex = 0; // 当前tab顺序
let page = param.page ? param.page : 1;
let indexTmp = 0;
Object.assign(param, {
page: page
});
if (result[0] && result[0].data) {
return api.all([
_category(),
_article(param)
]).then(result => {
indexTmp = 0;
let type = param.type;
let cateList = result[0].data;
let resu = {
guang: {
gender: param.gender,
}
};
let build = [];
// 顶部的分类列表
let curIndex = 0; // 当前tab顺序
let inf = [];
let indexTmp = 0;
cateList.forEach(val => {
build.push({
typeId: val.id,
type: val.name,
focus: (val.id === type)
});
if (result[0] && result[0].data) {
inf.push({
show: (val.id === type),
typeId: type,
info: []
});
indexTmp = 0;
if ((val.id === type)) {
curIndex = indexTmp;
}
let cateList = result[0].data;
indexTmp++;
let build = [];
resu.guang.navs = build;
let inf = [];
resu.guang.infos = inf;
cateList.forEach(val => {
build.push({
typeId: val.id,
type: val.name,
focus: (val.id === type)
});
inf.push({
show: (val.id === type),
typeId: type,
info: []
});
}
if ((val.id === type)) {
curIndex = indexTmp;
}
if (result && result[1] && result[1].data && result[1].data.list) {
indexTmp++;
let swp = [];
resu.guang.navs = build;
let swiperList = _.get(result[1], 'data.list.adlist', []);
resu.guang.infos = inf;
});
swiperList.forEach(val => {
swp.push({
url: guangProcess.getFilterUrl(val.url),
img: helpers.image(val.src, 640, 275)
});
});
}
resu.guang.swiper = swp;
if (result && result[1] && result[1].data && result[1].data.list) {
}
let swp = [];
if (result && result[1] && result[1].data && result[1].data.list && result[1].data.list.artList) {
let swiperList = _.get(result[1], 'data.list.adlist', []);
let inf = [];
let infoList = result[1].data.list.artList;
swiperList.forEach(val => {
swp.push({
url: guangProcess.getFilterUrl(val.url),
img: helpers.image(val.src, 640, 275)
infoList.forEach(val => {
inf.push(guangProcess.formatArticle(val, true, false, true));
});
});
resu.guang.swiper = swp;
resu.guang.infos[curIndex].info = inf;
}
}
if (result && result[1] && result[1].data && result[1].data.list && result[1].data.list.artList) {
return resu;
let inf = [];
});
let infoList = result[1].data.list.artList;
}
infoList.forEach(val => {
inf.push(guangProcess.formatArticle(val, true, false, true));
});
getTagEditor(param) {
resu.guang.infos[curIndex].info = inf;
let page = param.page ? param.page : 1;
}
Object.assign(param, {
page: page
});
return resu;
return api.all([
this._article(param)
]).then(result => {
});
let resu = {
guang: {
tag: param.tag,
gender: param.gender,
isApp: param.isApp ? 1 : 0,
guangList: true
}
};
if (result && result[0] && result[0].data && result[0].data.list && result[0].data.list.artList) {
let inf = [];
let infoList = result[0].data.list.artList;
infoList.forEach(val => {
val.colparam = {
urlpath: param.path,
param: ''
};
if (param.tag) {
val.colparam.param = `?query=${param.tag}`;
}
inf.push(guangProcess.formatArticle(val, true, param.isApp, true));
});
};
resu.guang.infos = inf;
const getTagEditor = (param) => {
}
let page = param.page ? param.page : 1;
return resu;
Object.assign(param, {
page: page
});
});
return api.all([
_article(param)
]).then(result => {
}
let resu = {
guang: {
tag: param.tag,
gender: param.gender,
isApp: param.isApp ? 1 : 0,
guangList: true
}
/**
* 获取制指定文章的动态信息
* @param ids
* @param udid
* @param other [Obejct] 包含uid,query,type等非必传参数
* @returns {Promise.<T>|*}
*/
getDynamicDataByIds(ids, udid, other) {
let params = {
articleIds: ids,
udid: udid
};
if (result && result[0] && result[0].data && result[0].data.list && result[0].data.list.artList) {
let inf = [];
let infoList = result[0].data.list.artList;
infoList.forEach(val => {
val.colparam = {
urlpath: param.path,
param: ''
};
if (param.tag) {
val.colparam.param = `?query=${param.tag}`;
}
inf.push(guangProcess.formatArticle(val, true, param.isApp, true));
if (other.uid) {
_.assign(params, {
uid: other.uid
});
resu.guang.infos = inf;
}
return resu;
});
};
/**
* 获取制指定文章的动态信息
* @param ids
* @param udid
* @param other [Obejct] 包含uid,query,type等非必传参数
* @returns {Promise.<T>|*}
*/
if (other.query) {
_.assign(params, {
query: other.query
});
}
const getDynamicDataByIds = (ids, udid, other) => {
let params = {
articleIds: ids,
udid: udid
};
if (other.type) {
_.assign(params, {
type: other.type
});
}
if (other.uid) {
_.assign(params, {
uid: other.uid
});
return serviceAPI.get('guang/api/v6/article/getSimpleArticleList', params);
}
if (other.query) {
_.assign(params, {
query: other.query
/**
* 获取制指定文章的动态信息
* @param ids
* @returns {Promise.<T>|*}
*/
getDynamicDataById(id, uid, udid) {
return serviceAPI.get('guang/api/v6/article/getArticlePraiseAndFavor', {
id: id,
uid: uid,
udid: udid
});
}
if (other.type) {
_.assign(params, {
type: other.type
/**
* 逛分类
*/
_category() {
return serviceAPI.get('/guang/api/v1/category/get', {
}, {
cache: true,
code: 200
});
}
return serviceAPI.get('guang/api/v6/article/getSimpleArticleList', params);
};
/**
* 逛内容列表
*/
_article(param) {
return serviceAPI.get('/guang/api/v2/article/getList', {
gender: param.gender,
page: param.page || 1,
uid: param.uid,
udid: param.udid,
sort_id: param.type || 0,
tag: param.tag ? param.tag : null,
limit: 4
// author_id: param.authorId ? param.authorId : null,
// limit: param.limit ? param.limit : null
}, {
cache: true,
code: 200
}).then(result => {
/**
* 获取制指定文章的动态信息
* @param ids
* @returns {Promise.<T>|*}
*/
return result;
});
}
}
const getDynamicDataById = (id, uid, udid) => {
return serviceAPI.get('guang/api/v6/article/getArticlePraiseAndFavor', {
id: id,
uid: uid,
udid: udid
});
};
module.exports = {
getAuthor,
getArticleList,
getPageData,
getArticle,
getTagEditor,
getDynamicDataByIds,
getDynamicDataById
};
module.exports = IndexModel;
... ...
... ... @@ -5,95 +5,101 @@
*/
'use strict';
const mRoot = '../models';
const indexModel = require(`${mRoot}/index`);
const infoModel = require(`${mRoot}/info`);
const IndexModel = require(`${mRoot}/index`);
const DetailModel = require(`${mRoot}/detail`);
const guangProcess = require(`${global.utils}/guang-process`);
const htmlProcess = require(`${global.utils}/html-process`);
const helpers = global.yoho.helpers;
/**
* [构建信息内容]
* @param {[int]} id [资讯id]
* @return {[string]}
*/
const _genIntro = (id) => {
let result = '';
class RssModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
return infoModel.intro(id).then((resData) => {
if (resData.data) {
resData.data.forEach((value) => {
if (value.text) { // 文字
result += htmlProcess.removeHtml(htmlProcess.escapeToHtml(value.text.data.text)) + '<br/>';
} else if (value.singleImage) { // 单张图
result += `<img src="${helpers.image(value.singleImage.data[0].src, 640, 640)}"/><br/>`;
} else if (value.smallPic && value.smallPic.data) { // 多张小图
value.smallPic.data.forEach((small) => {
result += `<img src="${helpers.image(small.src, 315, 420)}"/>`;
});
result += '<br/>';
}
});
this.indexModel = new IndexModel(ctx);
this.detailModel = new DetailModel(ctx);
}
result += `<a href="http://guang.m.yohobuy.com/info/index?id=${id}">查看原文</a>`;
return result;
}
});
/**
* [构建信息内容]
* @param {[int]} id [资讯id]
* @return {[string]}
*/
_genIntro(id) {
let result = '';
};
return this.detailModel.intro(id).then((resData) => {
if (resData.data) {
resData.data.forEach((value) => {
if (value.text) { // 文字
result += htmlProcess.removeHtml(htmlProcess.escapeToHtml(value.text.data.text)) + '<br/>';
} else if (value.singleImage) { // 单张图
result += `<img src="${helpers.image(value.singleImage.data[0].src, 640, 640)}"/><br/>`;
} else if (value.smallPic && value.smallPic.data) { // 多张小图
value.smallPic.data.forEach((small) => {
result += `<img src="${helpers.image(small.src, 315, 420)}"/>`;
});
result += '<br/>';
}
});
/**
* [获取订阅的资讯文章列表]
* @param {[int]} gender [性别参数(1,3表示男, 2,3表示女, 默认为所有)]
* @return {[array]}
*/
const getRssArticle = (gender) => {
let result = [],
articlePromise;
result += `<a href="http://guang.m.yohobuy.com/info/index?id=${id}">查看原文</a>`;
return result;
}
});
switch (gender) {
case '1,3':
articlePromise = indexModel.getArticleList('1,3', 0, 0, '', 1, null, null, 100, false);
break;
case '2,3':
articlePromise = indexModel.getArticleList('2,3', 0, 0, '', 1, null, null, 100, false);
break;
default:
articlePromise = indexModel.getArticleList('1,2,3', 0, 0, '', 1, null, null, 100, false);
break;
}
return articlePromise.then((article) => {
// 内容列表
if (article && article.data && article.data.list && article.data.list.artList) {
let build = {};
let artListFunc = (i, len, resolve) => {
if (i < len) {
let value = article.data.list.artList[i];
/**
* [获取订阅的资讯文章列表]
* @param {[int]} gender [性别参数(1,3表示男, 2,3表示女, 默认为所有)]
* @return {[array]}
*/
getRssArticle(gender) {
let result = [],
articlePromise;
if (typeof value.id !== 'undefined') {
build = guangProcess.formatArticle(value, false, false, true);
build.author = build.author || {};
build.author.name = (build.author && build.author.name) || '';
return _genIntro(value.id).then((intro) => {
build.intro = intro;
result.push(build);
artListFunc(++i, len, resolve);
});
}
} else {
resolve(result);
}
};
switch (gender) {
case '1,3':
articlePromise = this.indexModel.getArticleList('1,3', 0, 0, '', 1, null, null, 100, false);
break;
case '2,3':
articlePromise = this.indexModel.getArticleList('2,3', 0, 0, '', 1, null, null, 100, false);
break;
default:
articlePromise = this.indexModel.getArticleList('1,2,3', 0, 0, '', 1, null, null, 100, false);
break;
}
return articlePromise.then((article) => {
// 内容列表
if (article && article.data && article.data.list && article.data.list.artList) {
let build = {};
return new Promise((resolve) => {
artListFunc(0, article.data.list.artList.length, resolve);
});
let artListFunc = (i, len, resolve) => {
if (i < len) {
let value = article.data.list.artList[i];
}
});
};
if (typeof value.id !== 'undefined') {
build = guangProcess.formatArticle(value, false, false, true);
build.author = build.author || {};
build.author.name = (build.author && build.author.name) || '';
return this._genIntro(value.id).then((intro) => {
build.intro = intro;
result.push(build);
artListFunc(++i, len, resolve);
});
}
} else {
resolve(result);
}
};
return new Promise((resolve) => {
artListFunc(0, article.data.list.artList.length, resolve);
});
}
});
}
}
module.exports = {
getRssArticle
};
module.exports = RssModel;
... ...
... ... @@ -12,10 +12,11 @@ const star = require(cRoot + '/star');
const homeController = require(`${cRoot}/index`);
const plusstar = require(cRoot + '/plusstar');
const rewrite = require('../../doraemon/middleware/rewrite');
const mip = require('../../doraemon/middleware/mip');
const index = require(cRoot + '/index');
const opt = require(cRoot + '/opt');
const info = require(cRoot + '/info');
const detail = require(cRoot + '/detail');
const plustar = require(cRoot + '/plustar');
const rss = require(cRoot + '/rss');
const brand = require(cRoot + '/brand-list');
... ... @@ -51,12 +52,12 @@ router.post('/opt/praiseArticle', opt.praiseArticle); // 资讯文章点赞 (H5
router.post('/opt/collectArticle', opt.collectArticle); // 资讯文章收藏 (H5里显示收藏)
router.post('/opt/favoriteBrand', opt.favoriteBrand); // 品牌收藏
router.get('/info/index', rewrite.channel, info.indexRedirect); // 逛详情页
router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, info.index); // 逛详情页 SEO优化
router.get('/info/index', rewrite.channel, detail.indexRedirect); // 逛详情页
router.get(/^\/info\/(.*?)\.html/, rewrite.resolve, mip, detail.index); // 逛详情页 SEO优化
router.get('/:id.html', info.index); // 逛详情页(兼容 PC 跳转过来的链接)
router.get('/info/mini', info.mini); // 逛mini内容页
router.get('/info/foryoho', info.foryoho); // 逛foryoho内容页
router.get('/:id.html', detail.index); // 逛详情页(兼容 PC 跳转过来的链接)
router.get('/info/mini', detail.mini); // 逛mini内容页
router.get('/info/foryoho', detail.foryoho); // 逛foryoho内容页
router.get('/plustar', plustar.getListData); // 国际优选列表页
router.get('/plustar/brandinfo', plustar.getDetailData); // 国际优选详情页
... ...
<div class="guang-list-page guang-page yoho-page">
<div class="guang-list-page guang-page yoho-page" id="guangList">
{{# guang}}
<ul id="guang-nav" class="guang-nav clearfix">
<ul id="guang-nav" class="guang-nav">
{{# navs}}
<li class="guang-nav-item {{#focus}}focus{{/focus}}" data-type={{typeId}}>
{{type}}
... ...
<div class="guang-detail-page guang-page yoho-page {{#if guangDetail}}guang-detail{{/if}} {{#if guangEzine}}guang-ezine{{/if}}">
<div class="guang-detail-page guang-page yoho-page {{#if guangDetail}}guang-detail{{/if}} {{#if guangEzine}}guang-ezine{{/if}}" id="guangDetail">
{{# guang}}
<div id="wrapper" >
<div id="scroller" class="{{channel}}">
... ... @@ -35,6 +35,13 @@
{{else}}
<img class="lazy" data-original={{image2 bigImage q=60}}>
{{/if}}
{{#if tagList}}
<div class="tag-list-box">
{{#each tagList}}
{{> detail/img-label}}
{{/each}}
</div>
{{/if}}
</div>
{{/if}}
... ... @@ -49,6 +56,10 @@
<img class="lazy" data-original={{image2 src q=60}}>
{{/ smallImage}}
{{/if}}
{{#tagList}}
{{> detail/img-label}}
{{/tagList}}
</div>
{{/if}}
... ... @@ -84,7 +95,7 @@
{{#each collocation}}
<div class="prod {{#unless @first}}hide{{/unless}}">
{{# goods}}
{{> good}}
{{> common/goods}}
{{/ goods}}
</div>
{{/each}}
... ... @@ -100,42 +111,37 @@
{{/if}}
{{#if relatedReco}}
<div class="post-block related-reco-block clearfix">
<h2>相关推荐</h2>
{{#if relatedReco.id}}
{{#with relatedReco}}
<div class="one-good">
<img class="thumb lazy" data-original={{thumb}}>
<div class="content-container">
<p>
<span class="reco-name">{{name}}</span>
</p>
<p class="price">
<span class="sale-price {{^price}}no-price{{/price}}">&yen;{{salePrice}}</span>
{{#price}}
<span class="market-price">&yen;{{.}}</span>
{{/price}}
<a class="check-detail" href={{url}}>
查看详情
</a>
</p>
</div>
</div>
{{/with}}
{{^}}
<div class="good-list clearfix">
{{# relatedReco}}
{{> good}}
{{/ relatedReco}}
</div>
{{/if}}
<div class="post-block related-reco clearfix">
<div class="related-reco-block related-reco-hide">
{{#each relatedReco.goods}}
{{> detail/related-reco isApp=../relatedReco/isApp}}
{{/each}}
</div>
{{#if relatedReco.moreNum}}
<div class="related-reco-more">
<span>展开剩余{{relatedReco.moreNum}}个商品</span>
</div>
{{/if}}
</div>
{{/if}}
{{/ content}}
</div>
</div>
{{/ detail}}
{{#detail.content}}
{{#if recommendProducts}}
<div class="recommend-products-box">
<div class="recommend-products-content">
{{#each recommendProducts}}
{{> detail/recommend-products}}
{{/each}}
</div>
</div>
{{/if}}
{{/detail.content}}
{{#if relatedBrand}}
<div class="related-brand">
<h2>相关品牌</h2>
... ... @@ -154,22 +160,8 @@
</div>
{{/if}}
{{#if relatedTag}}
<div class="related-tag">
<div class="tag-bg"></div>
<ul class="tag-list clearfix">
{{# relatedTag}}
<li class="buriedpoint" data-bp-id="guang_tab_{{name}}_0">
<a href={{url}}>{{name}}</a>
</li>
{{/ relatedTag}}
</ul>
</div>
{{/if}}
{{#if relatedInfo}}
<div class="related-info">
<h2>相关文章</h2>
<ul class="info-list">
{{# relatedInfo}}
<li data-bp-id="guang_article_{{title}}_0" class="buriedpoint">
... ... @@ -187,6 +179,18 @@
</div>
{{/if}}
{{#if relatedTag}}
<div class="related-tag">
<ul class="tag-list clearfix">
{{# relatedTag}}
<li class="buriedpoint" data-bp-id="guang_tab_{{name}}_0">
<a href={{url}}>{{name}}</a>
</li>
{{/ relatedTag}}
</ul>
</div>
{{/if}}
{{#if isShare}}
<div class="down-bottom"></div>
{{/if}}
... ...
{{#unless isApp}}
<div class="label-box" data-skn="{{product_skn}}">
<div class="lable-focus">
<div class="focus-big">
<div class="focus-small"></div>
</div>
</div>
<div class="lable-info-box{{#if isApp}} lable-infobox-borderadius{{/if}}"><a href="{{href}}">{{tagName}}</a></div>
<div class="lable-btn add-to-cart" data-skn="{{product_skn}}">
<span class="iconfont">&#xe62c;</span>
<span class="iconfont plus">&#xe624;</span>
</div>
</div>
{{/unless}}
\ No newline at end of file
... ...
<div class="recommend-goods">
<a href="{{href}}"><img src="" alt="" class="lazy" data-original="{{image2 pic_url w=152 h=204}}"></a>
<div class="recommend-goods-cover">&yen;{{price}}</div>
</div>
\ No newline at end of file
... ...
<div class="one-good clearfix">
<a href="{{url}}">
<img class="thumb lazy" data-original="{{image2 default_images w=152 h=204}}">
</a>
<div class="content-container">
<a href="{{url}}">
<p class="reco-name">
<span>{{product_name}}</span>
</p>
<p class="price">
<span class="sale-price">&yen;{{sales_price}}</span>
</p>
</a>
{{#unless isApp}}
<p>
<span class="check-detail add-to-cart" data-skn="{{product_skn}}">
<span class="iconfont">&#xe62c;</span>
<span class="iconfont plus">&#xe624;</span>
</span>
</p>
{{/unless}}
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -51,4 +51,16 @@
<p class="info-text">{{text}}</p>
{{> index/tvls}}
</div>
{{#unless @root.isApp}}
{{#if productList}}
<div class="product-list-box">
<ul class="product-list">
{{#productList}}
{{> index/product-list}}
{{/productList}}
</ul>
</div>
{{/if}}
{{/unless}}
</div>
... ...
<li class="goods-box">
<div class="goods-img">
<a href="{{href}}">
<img class="lazy" data-original="{{image2 pic_url w=106 h=138}}" />
</a>
</div>
<div class="goods-info">
<a href="{{href}}">
<p class="title">{{product_name}}</p>
<p class="price">¥{{price}}</p>
</a>
</div>
</li>
\ No newline at end of file
... ...
'use strict';
const mRoot = '../models';
const headerModel = require('../../../doraemon/models/header'); // 头部model
const gradeNewModel = require(`${mRoot}/grade-new`);
exports.index = (req, res, next) => {
let responseData = {
module: 'home',
page: 'grade-new',
pageHeader: headerModel.setNav({
navTitle: '会员等级'
}),
title: '会员等级',
width750: true,
localCss: true,
pageFooter: true
};
let params = {
uid: req.user.uid,
channel: req.query.channel || 1
};
req.ctx(gradeNewModel).index(params).then(result => {
res.render('grade-new/index', Object.assign(responseData, result));
}).catch(next);
};
exports.content = (req, res, next) => {
let responseData = {
module: 'home',
page: 'grade-new',
pageHeader: headerModel.setNav({
navTitle: '会员等级'
}),
title: '会员等级',
width750: true,
localCss: true,
pageFooter: true
};
let params = {
uid: req.user.uid,
channel: req.query.channel || 1
};
req.ctx(gradeNewModel).index(params).then(result => {
res.render('grade-new/content', Object.assign(responseData, result));
}).catch(next);
};
exports.grow = (req, res, next) => {
let responseData = {
module: 'home',
page: 'grade-new',
pageHeader: headerModel.setNav({
navTitle: '成长记录'
}),
title: '成长记录',
width750: true,
localCss: true,
pageFooter: true
};
let params = {
uid: req.user.uid,
page: 1
};
req.ctx(gradeNewModel).grow(params).then(result => {
res.render('grade-new/grow', Object.assign(responseData, result));
}).catch(next);
};
exports.getHis = (req, res, next) => {
let params = {
uid: req.user.uid,
page: req.query.page
};
req.ctx(gradeNewModel).getHisAjax(params).then(result => {
res.json(result);
}).catch(next);
};
... ...
... ... @@ -26,6 +26,9 @@ exports.index = (req, res, next) => {
let studentSwitch = !_.get(req.app.locals.wap, 'user.removeStudentIdentification', true);
// 唤起 APP 的路径
res.locals.appPath = 'yohobuy://yohobuy.com/goapp?openby:yohobuy= {"action":"go.mine"}';
indexModel.index(params).then(result => {
if (result) {
res.render('home', Object.assign(result, {
... ... @@ -181,7 +184,8 @@ exports.grade = (req, res, next) => {
module: 'home',
page: 'grade',
title: '会员等级',
pageFooter: true
pageFooter: true,
width750: true
};
let param = {
... ... @@ -213,7 +217,8 @@ exports.preferential = (req, res, next) => {
module: 'home',
page: 'grade',
title: '会员特权详情',
pageFooter: true
pageFooter: true,
width750: true
};
let param = {
... ...
... ... @@ -60,7 +60,7 @@ const index = (req, res, next) => {
Promise.all([
installmentModel.getStauts(uid),
installmentModel.getSearchIntallment({
page: 1
uid: uid
})
]).then((result) => {
... ... @@ -157,7 +157,9 @@ const getInstallmentGoods = (req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', allowOrigin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
let params = req.query || {};
let params = {
uid: req.user.uid
};
installmentModel.getSearchIntallment(params).then((result) => {
if (result) {
... ...
... ... @@ -79,3 +79,20 @@ exports.pickCoupon = (req, res, next) => {
res.end();
}).catch(next);
};
// 生日卷
exports.birthCoupon = (req, res, next) => {
let responseData = {
module: 'home',
page: 'message',
pageHeader: headerModel.setNav({
navTitle: '生日卷'
}),
title: '生日卷',
pageFooter: true
};
model._getBirthCouponById(req.user.uid).then(result => {
res.render('birth-coupon', Object.assign(responseData, result));
}).catch(next);
};
... ...
... ... @@ -14,16 +14,11 @@ const couponData = (params) => {
return result.data.couponList.map(function(elem) {
delete elem.id;
elem.isNoLimit = elem.isNoLimit === 'true';// 全场通用
elem.isDiscount = (`,${elem.shopPriceLimits},`).indexOf(',1,') !== -1;// 三折以下
elem.isLimited = (`,${elem.shopPriceLimits},`).indexOf(',2,') !== -1;// 限量
elem.brandNameLimits = elem.brandNameLimit && elem.brandNameLimit.join('、');
elem.sortNameLimits = elem.sortNameLimit && elem.sortNameLimit.join('、');
if (status0) {
elem.bestowLink = helpers.urlFormat('/product/index/index',
{
coupon_id: elem.couponId,
coupon_code: elem.couponCode,
title: '优惠活动商品',
intro_text: `以下商品可使用【${elem.couponDetailInfomation}】优惠券`
}
... ...