Authored by htoooth

Merge remote-tracking branch 'origin/release/1.0' into release/1.0

Conflicts:
	apps/passport/controllers/reg.js
/**
* 微信分享签名
* Bi Kai <kai.bi@yoho.cn>
*/
'use strict';
const wechatModel = require('../models/wechat');
... ...
... ... @@ -27,80 +27,80 @@ const ticketCacheKey = 'wechatShare:ticket';
// 微信 JS 接口签名校验工具 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign
const wechat = {
getAccessToken: Promise.coroutine(function* () {
let accessToken = yield cache.get(accessTokenCacheKey);
if (accessToken) {
return accessToken;
}
logger.info('调用微信 API 获取 accessToken');
return request({
url: 'https://api.weixin.qq.com/cgi-bin/token',
qs: {
grant_type: 'client_credential',
appid: appId,
secret: secret
},
json: true
}).then((res) => {
// accessToken 有效期 7200s,缓存 7100s
cache.set(accessTokenCacheKey, res.access_token, 7100).catch((err) => {
logger.error('微信分享 Token, 缓存 accessToken 时出错', JSON.stringify(err));
});
return res.access_token;
}).catch((err) => {
logger.error('微信分享 Token, 获取 accessToken 时出错', JSON.stringify(err));
let _getAccessToken = Promise.coroutine(function* () {
let accessToken = yield cache.get(accessTokenCacheKey);
if (accessToken) {
return accessToken;
}
logger.info('get accessToken from wechat API');
return request({
url: 'https://api.weixin.qq.com/cgi-bin/token',
qs: {
grant_type: 'client_credential',
appid: appId,
secret: secret
},
json: true
}).then((res) => {
// accessToken 有效期 7200s,缓存 7100s
cache.set(accessTokenCacheKey, res.access_token, 7100).catch((err) => {
logger.error('set wechat accessToken cache error', JSON.stringify(err));
});
}),
getTicket: Promise.coroutine(function* () {
let ticket = yield cache.get(ticketCacheKey);
if (ticket) {
return ticket;
}
logger.info('调用微信 API 获取 ticket');
return request({
url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
qs: {
access_token: yield this.getAccessToken(),
type: 'jsapi'
},
json: true
}).then(res => {
return res.access_token;
}).catch((err) => {
logger.error('get accessToken from wechat API error', JSON.stringify(err));
});
});
let _getTicket = Promise.coroutine(function* () {
let ticket = yield cache.get(ticketCacheKey);
if (ticket) {
return ticket;
}
logger.info('get ticket from wechat API');
return request({
url: 'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
qs: {
access_token: yield _getAccessToken(),
type: 'jsapi'
},
json: true
}).then(res => {
// ticket 有效期 7200s,缓存 7100s
cache.set(ticketCacheKey, res.ticket, 7100).catch((err) => {
logger.error('微信分享 Token, 缓存 ticket 时出错', JSON.stringify(err));
});
return res.ticket;
}).catch((err) => {
logger.error('微信分享 Token, 获取 ticket 时出错', JSON.stringify(err));
cache.set(ticketCacheKey, res.ticket, 7100).catch((err) => {
logger.error('set wechat Token cache error', JSON.stringify(err));
});
}),
calcSignature: Promise.coroutine(function* (data) {
data = Object.assign({
nonceStr: Math.random().toString(36).substr(2, 15),
timestamp: Math.floor(Date.now() / 1000) + '',
ticket: yield this.getTicket(),
appId: appId
}, data);
const str = `jsapi_ticket=${data.ticket}&noncestr=${data.nonceStr}&timestamp=${data.timestamp}&url=${data.url}`;
data.signature = sha1(str);
return data;
})
};
return res.ticket;
}).catch((err) => {
logger.error('get ticket from wechat API error', JSON.stringify(err));
});
});
let calcSignature = Promise.coroutine(function* (data) {
data = Object.assign({
nonceStr: Math.random().toString(36).substr(2, 15),
timestamp: Math.floor(Date.now() / 1000) + '',
ticket: yield _getTicket(),
appId: appId
}, data);
const str = `jsapi_ticket=${data.ticket}&noncestr=${data.nonceStr}&timestamp=${data.timestamp}&url=${data.url}`;
data.signature = sha1(str);
return data;
});
// 测试
// wechat.calcSignature({
// calcSignature({
// url: 'http://www.yohobuy.com/'
// }).then(console.log);
module.exports = wechat;
module.exports = {
calcSignature
};
... ...
... ... @@ -15,7 +15,7 @@ const RegService = require('../models/reg-service');
const AuthHelper = require('../models/auth-helper');
let index = (req, res) => {
// 设置注册有效时间30分钟, 防机器刷
// 设置注册有效时间30分钟, 防机器刷
req.session._REG_EXPIRE = Date.now() + 1800000;
let refer = req.query.refer;
... ... @@ -43,13 +43,13 @@ let verifyMobile = (req, res, next) => {
let mobile = +req.body.phoneNum;
let area = +(req.body.areaCode || 86);
/* 判断参数是否合法 */
// 判断参数是否合法
if (!_.isNumber(mobile) || !_.isNumber(area)) {
data.message = '手机号错误';
return res.json(data);
}
/* 设置注册有效时间30分钟, 防机器刷 */
// 设置注册有效时间30分钟, 防机器刷
let expire = req.session._REG_EXPIRE;
if (!expire || expire < Date.now()) {
... ... @@ -57,13 +57,13 @@ let verifyMobile = (req, res, next) => {
return res.json(data);
}
/* 向手机发送注册验证码 */
// 向手机发送注册验证码
RegService.sendCodeToMobile(area, mobile).then((result) => {
if (!result.code) {
return res.json(data);
}
/* 返回跳转到验证页面的链接 */
// 返回跳转到验证页面的链接
if (result.code === 200) {
let token = sign.makeToken(mobile);
... ... @@ -82,7 +82,7 @@ let codeAction = (req, res, next) => {
let mobile = +req.query.phoneNum;
let area = +(req.query.areaCode || 86);
// 判断是否允许访问, 不允许则跳转到错误页面
// 判断是否允许访问, 不允许则跳转到错误页面
if (!_.isString(token) || !_.isNumber(mobile) || !sign.verifyToken(mobile, token)) {
return next({
code: 403,
... ... @@ -112,13 +112,13 @@ let sendCode = (req, res, next) => {
let mobile = +req.body.phoneNum;
let area = +(req.body.areaCode || 86);
/* 判断参数是否合法 */
// 判断参数是否合法
if (!_.isNumber(mobile) || !_.isNumber(area)) {
data.message = '手机号错误';
return res.json(data);
}
/* 设置注册有效时间30分钟, 防机器刷 */
// 设置注册有效时间30分钟, 防机器刷
let expire = req.session._REG_EXPIRE;
if (!expire || expire < Date.now()) {
... ... @@ -126,7 +126,7 @@ let sendCode = (req, res, next) => {
return res.json(data);
}
/* 向手机发送注册验证码 */
// 向手机发送注册验证码
RegService.sendCodeToMobile(area, mobile).then((result) => {
return result.code ? res.json(result) : res.json(data);
}).catch(next);
... ... @@ -148,7 +148,7 @@ let verifyCode = (req, res, next) => {
return res.json(data);
}
/* 设置注册有效时间30分钟, 防机器刷 */
// 设置注册有效时间30分钟, 防机器刷
let expire = req.session._REG_EXPIRE;
if (!expire || expire < Date.now()) {
... ... @@ -156,13 +156,13 @@ let verifyCode = (req, res, next) => {
return res.json(data);
}
/* 验证注册的标识码是否有效 */
// 验证注册的标识码是否有效
RegService.validMobileCode(area, mobile, code).then((result) => {
if (!result.code) {
return res.json(data);
}
/* 返回跳转到设置密码的链接 */
// 返回跳转到设置密码的链接
if (result.code === 200) {
let token = sign.makeToken(mobile);
... ... @@ -183,7 +183,7 @@ let passwordAction = (req, res, next) => {
let mobile = +req.query.phoneNum;
let area = +(req.query.areaCode || 86);
// 判断是否允许访问, 不允许则跳转到错误页面
// 判断是否允许访问, 不允许则跳转到错误页面
if (!_.isString(token) || !_.isNumber(mobile) || !_.isNumber(area) || !sign.verifyToken(mobile, token)) {
return next({
code: 403,
... ... @@ -214,27 +214,27 @@ let setPassword = (req, res, next) => {
let password = req.body.password;
let token = req.body.token;
/* 判断参数是否合法 */
// 判断参数是否合法
if (!_.isString(token) || !_.isNumber(mobile) || !_.isNumber(area) || !password) {
data.message = '请求参数不合法';
return res.json(data);
}
/* 判断是否允许访问 */
// 判断是否允许访问
if (!sign.verifyToken(mobile, token)) {
data.message = '非法 token';
return res.json(data);
}
/* 判断密码是否符合规则 */
// 判断密码是否符合规则
if (!helpers.verifyPassword(password)) {
return res.json(data);
}
// 购物车key
// 购物车key
let shoppingKey = cookie.getShoppingKey(req);
// 验证注册的标识码是否有效
// 验证注册的标识码是否有效
RegService.regMobile(area, mobile, password, shoppingKey).then((result) => {
if (!result.code || result.code !== 200) {
return Promise.reject(result);
... ... @@ -245,7 +245,7 @@ let setPassword = (req, res, next) => {
return AuthHelper.syncUserSession(result.data.uid, req, res);
}).then(() => {
// 返回跳转到来源页面
// 返回跳转到来源页面
let refer = req.cookies.refer;
if (refer) {
... ...
... ... @@ -27,7 +27,7 @@ const saleModel = require(`${mRoot}/sale`);
* @param {[string]} page js文件page名称
* @return {[type]}
*/
const processPublicData = (req, title, page) => {
const _processPublicData = (req, title, page) => {
let data = {};
let headerData = headerModel.setNav({
navTitle: title
... ... @@ -53,8 +53,8 @@ const processPublicData = (req, title, page) => {
* @param {[object]} res
* @return {[type]}
*/
exports.index = (req, res, next) => {
let params = processPublicData(req, 'SALE', 'sale');
let index = (req, res, next) => {
let params = _processPublicData(req, 'SALE', 'sale');
saleModel.getSaleData(params.channel).then((result) => {
res.render('sale/index', Object.assign(params.renderData, {
... ... @@ -74,8 +74,8 @@ exports.index = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.breakingYards = (req, res, next) => {
let params = processPublicData(req, '断码区', 'break-code');
let breakingYards = (req, res, next) => {
let params = _processPublicData(req, '断码区', 'break-code');
saleModel.getBreakCodeData({
yhChannel: params.channel
... ... @@ -90,8 +90,8 @@ exports.breakingYards = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.discount = (req, res, next) => {
let params = processPublicData(req, '折扣专场', 'discount');
let discount = (req, res, next) => {
let params = _processPublicData(req, '折扣专场', 'discount');
saleModel.getDiscountData(params.channel).then((result) => {
res.render('sale/discount', Object.assign(params.renderData, result));
... ... @@ -105,9 +105,9 @@ exports.discount = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.discountDetail = (req, res, next) => {
let discountDetail = (req, res, next) => {
let id = req.query.id;
let params = processPublicData(req, '', 'discount-detail');
let params = _processPublicData(req, '', 'discount-detail');
saleModel.getDiscountDetailData(id, params.channel).then((result) => {
params.renderData.pageHeader.navTitle = result.title;
... ... @@ -121,8 +121,8 @@ exports.discountDetail = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.vip = (req, res, next) => {
let params = processPublicData(req, '会员专享', 'vip');
let vip = (req, res, next) => {
let params = _processPublicData(req, '会员专享', 'vip');
saleModel.getVipData(params.channel).then((result) => {
res.render('sale/vip', Object.assign(params.renderData, {
... ... @@ -137,7 +137,7 @@ exports.vip = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.filter = (req, res, next) => {
let filter = (req, res, next) => {
let params = Object.assign({}, req.query);
saleModel.getFilterData(params).then((result) => {
... ... @@ -156,7 +156,7 @@ exports.filter = (req, res, next) => {
* @param {[object]} res
* @return {[type]}
*/
exports.search = (req, res, next) => {
let search = (req, res, next) => {
let params = Object.assign({}, req.query);
// uid = 9239279
... ... @@ -184,3 +184,13 @@ exports.search = (req, res, next) => {
}, vipObj));
}).catch(next);
};
module.exports = {
index,
breakingYards,
discount,
discountDetail,
vip,
filter,
search
};
... ...
... ... @@ -353,11 +353,11 @@ const getDiscountDetailData = (id, yhChannel) => {
};
module.exports = {
getSaleData: getSaleData,
getBreakCodeData: getBreakCodeData,
getDiscountData: getDiscountData,
getDiscountDetailData: getDiscountDetailData,
getVipData: getVipData,
getFilterData: getFilterData,
getSearchData: getSearchData
getSaleData,
getBreakCodeData,
getDiscountData,
getDiscountDetailData,
getVipData,
getFilterData,
getSearchData
};
... ...
... ... @@ -31,6 +31,8 @@ module.exports = function(specificGender) {
var $footer;
var bottomBannerLoaded;
// ajax url
if (kidsType) {
url = '/product/recom/maylikekids';
... ... @@ -95,12 +97,14 @@ module.exports = function(specificGender) {
},
success: function(data) {
if (data === ' ') {
searching = false;
if (!data.length) {
loading.hideLoadingMask();
// 有货币页面不加载底部
if (gender && !specificGender) {
if (bottomBannerLoaded) {
return;
}
url = '/channel/bottomBanner';
$.ajax({
type: 'GET',
... ... @@ -109,6 +113,8 @@ module.exports = function(specificGender) {
gender: gender
},
success: function(res) {
res = res.data;
bottomBannerLoaded = true;
if (res && res.img) {
$('#load-more-img').show();
$('#load-more-img a').attr('href', res.url);
... ...
... ... @@ -35,6 +35,10 @@
z-index: 2;
background: #f0f0f0;
transition: transform 0.3s;
.creative-life .classify-name {
display: none;
}
}
.mobile-wrap.menu-open {
... ...
... ... @@ -189,4 +189,4 @@
}
}
@import "home" ;
@import "home";
... ...