Showing 68 changed files with 1562 additions and 1460 deletions

Too many changes to show.

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

... ... @@ -7,25 +7,29 @@
const config = require('./config/common');
global.Promise = require('bluebird');
const yohoLib = require('yoho-node-lib');
// 全局注册library
yohoLib.global(config);
const express = require('express');
const compression = require('compression');
const path = require('path');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const favicon = require('serve-favicon');
const session = require('yoho-express-session');
const _ = require('lodash');
const fp = require('lodash/fp');
const memcached = require('connect-memcached');
const hbs = require('express-handlebars');
const session = require('cookie-session');
const pkg = require('./package.json');
const yohoLib = require('yoho-node-lib');
const app = express();
const helpers = global.yoho.helpers;
const MemcachedStore = memcached(session);
// 全局注册library
yohoLib.global(config);
// NOTE: 这里修改了图片质量的参数
helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90'));
global.middleware = path.resolve('./doraemon/middleware');
global.utils = path.resolve('./utils');
... ... @@ -35,45 +39,34 @@ global.appRoot = path.resolve(__dirname);
app.locals.devEnv = app.get('env') === 'development';
app.locals.version = pkg.version;
// zookeeper
if (config.zookeeperServer) {
require('yoho-zookeeper')(config.zookeeperServer, 'pc', app.locals.pc = {});
}
app.set('subdomain offset', 2);
app.set('view engine', '.hbs');
app.set('views', './doraemon/views');
app.set('view cache', true);
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: './doraemon/views',
partialsDir: './doraemon/views/partial',
layoutsDir: path.join(__dirname, 'doraemon/views'),
partialsDir: path.join(__dirname, 'doraemon/views/partial'),
views: path.join(__dirname, 'doraemon/views'),
helpers: global.yoho.helpers
}));
app.use(global.yoho.middleware());
app.use(favicon(path.join(__dirname, '/public/favicon.ico')));
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
app.use(compression());
app.use(session({
proxy: true,
resave: false,
saveUninitialized: true,
unset: 'destroy',
name: 'yohobuy_session_cookie',
secret: '82dd7e724f2c6870472c89dfa43cf48d',
name: 'yohobuy_session',
cookie: {
domain: 'yohobuy.com',
httpOnly: false
},
store: new MemcachedStore({
hosts: config.memcache.session,
prefix: 'yohobuy_session:',
poolSize: 25,
reconnect: 5000,
timeout: 1000,
retries: 1,
retry: 3000
})
domain: config.cookieDomain
}));
app.use((req, res, next) => {
... ... @@ -88,6 +81,7 @@ const logger = global.yoho.logger;
// dispatcher
try {
const subDomain = require('./doraemon/middleware/sub-domain');
const mobileRefer = require('./doraemon/middleware/mobile-refer');
const itemNameHandler = require('./doraemon/middleware/item-name-handler');
const mobileCheck = require('./doraemon/middleware/mobile-check');
const user = require('./doraemon/middleware/user');
... ... @@ -95,9 +89,11 @@ try {
const setYohoData = require('./doraemon/middleware/set-yoho-data');
const errorHanlder = require('./doraemon/middleware/error-handler');
const setPageInfo = require('./doraemon/middleware/set-pageinfo');
const pageCache = require('./doraemon/middleware/page-cache');
// YOHO 前置中间件
app.use(subDomain());
app.use(mobileRefer());
app.use(itemNameHandler);
app.use(mobileCheck());
app.use(setYohoData());
... ... @@ -105,6 +101,7 @@ try {
app.use(seo());
app.use(setPageInfo());
app.use(pageCache());
require('./dispatch')(app);
app.all('*', errorHanlder.notFound()); // 404
... ...
... ... @@ -5,7 +5,7 @@
*/
'use strict';
const _ = require('lodash');
const couponModel = require('../models/coupon');
exports.index = (req, res, next) => {
... ... @@ -15,6 +15,12 @@ exports.index = (req, res, next) => {
uid: req.user.uid,
contentCode: req.query.contentCode
}).then(result => {
// 无结果不缓存
if (_.isEmpty(result.categories)) {
res.set('Cache-Control', 'no-cache');
}
res.render('coupon', Object.assign({
module: 'activity',
page: 'coupon'
... ...
... ... @@ -5,8 +5,7 @@
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
... ... @@ -17,12 +16,12 @@ app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -19,7 +19,7 @@ router.get(/^\/special\/(\d+)_(.*)\.html$/, specialController.special);
// 领券中心
router.get('/coupon/index', coupon.index);
router.get('/coupon/couponstatus', coupon.getCouponStatus);
router.get('/coupon/couponstatus', auth, coupon.getCouponStatus);
router.get('/coupon/sendcoupon', auth, coupon.sendcoupon);
module.exports = router;
... ...
... ... @@ -20,7 +20,10 @@ exports.index = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'boys';
brandsService.getBrandViewList(channel, req).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cashe-Control', 'no-cashe');
}
res.render('brands/brands', result);
}).catch(next);
... ... @@ -50,6 +53,10 @@ exports.brandInfo = (req, res, next) => {
let brandId = req.query.brandId || 0;
brandsService.brandInfo(brandId, req.user.uid).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cashe-Control', 'no-cashe');
}
res.json(result);
}).catch(next);
};
... ... @@ -61,6 +68,10 @@ exports.plusstarList = (req, res, next) => {
let channel = req.query.channel || req.cookies._Channel || 'boys';
brandsService.plusstarList(channel, req).then(result => {
// 返回null,不cashe
if (result.noCashe) {
res.set('Cashe-Control', 'no-cashe');
}
res.render('brands/plusstar', result);
}).catch(next);
};
... ...
... ... @@ -5,8 +5,7 @@
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
... ... @@ -18,12 +17,12 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -6,6 +6,7 @@
'use strict';
const api = global.yoho.API;
const serviceAPI = global.yoho.ServiceAPI;
const config = global.yoho.config;
/**
* 分开取数,品牌一览 顶部的轮翻广告及热门品牌数据-PC
... ... @@ -15,7 +16,7 @@ const serviceAPI = global.yoho.ServiceAPI;
const getBrandTopData = (contentCode) => {
return serviceAPI.get('operations/api/v5/resource/get', {
content_code: contentCode
}, {cache: 3600});
}, config.apiCache);
};
/**
... ... @@ -28,7 +29,7 @@ const getBrandListData = channel => {
if (!isNaN(channel)) {
params.yh_channel = channel;
}
return api.get('', params);
return api.get('', params, config.apiCache);
};
/**
... ... @@ -48,7 +49,7 @@ const getBrandIntro = (brandId, uid) => {
method: 'app.brand.getBrandIntro',
brand_id: brandId,
uid: uid
}, param);
}, param, config.apiCache);
};
/**
... ... @@ -61,7 +62,7 @@ const getProductByBrand = (brandId, limit) => {
method: 'web.search.search',
brand: brandId,
limit: limit
});
}, config.apiCache);
};
/**
... ... @@ -74,7 +75,7 @@ const getBrandInfoByIds = (ids) => {
return api.get('', {
method: 'web.brand.info',
ids: ids instanceof Array ? ids.join(',') : parseInt(ids, 10)
}, {cache: 3600});
}, config.apiCache);
};
/**
... ... @@ -89,7 +90,7 @@ const getPlusstarList = (brandType, gender) => {
return serviceAPI.get('guang/api/v3/plustar/getlist', {
gender: gender,
brand_type: brandType
}, {cache: 3600});
}, config.apiCache);
};
module.exports = {
... ...
... ... @@ -101,13 +101,14 @@ exports.getBrandViewList = (channel) => {
let apiMethod = [
headerModel.requestHeaderData(channel),
brandsModel.getBrandViewTop(channel),
brandsModel.getBrandViewList(channel, 1, 5) // 分屏加载
brandsModel.getBrandViewList(channel) // 分屏加载
];
return api.all(apiMethod).then(result => {
let responseData = {
module: 'brands',
page: 'brands'
page: 'brands',
noCashe: false
};
// 头部数据
... ... @@ -135,6 +136,10 @@ exports.getBrandViewList = (channel) => {
// SEO
Object.assign(responseData, seoMap[channel]);
// 数据出错不cashe
if (_.isEmpty(result[0].headerData) || _.isEmpty(result[1]) || _.isEmpty(result[2])) {
responseData.noCashe = true;
}
return responseData;
});
};
... ... @@ -168,11 +173,17 @@ exports.brandInfo = (brandId, uid) => {
];
return api.all(apiMethod).then(result => {
return {
let responseData = {
code: _.isEmpty(result[0]) ? 400 : 200,
brand: _.isEmpty(result[0]) ? '' : result[0]
brand: _.isEmpty(result[0]) ? '' : result[0],
noCashe: false
};
// 数据出错不cashe
if (_.isEmpty(result[0])) {
responseData.noCashe = true;
}
return responseData;
});
};
... ... @@ -189,7 +200,8 @@ exports.plusstarList = (channel, req) => {
let responseData = {
module: 'brands',
page: 'brands',
brandsHomePage: true
brandsHomePage: true,
noCashe: false
};
let id = req.query.id || '',
... ... @@ -208,6 +220,10 @@ exports.plusstarList = (channel, req) => {
let list = plustarList.data;
// 数据出错不cashe
if (_.isEmpty(headerData.headerData) || _.isEmpty(items) || _.isEmpty(list)) {
responseData.noCashe = true;
}
let brandIds = [],
brands = [],
pageList = {};
... ... @@ -232,6 +248,11 @@ exports.plusstarList = (channel, req) => {
}
brands.push(list[brandId]);
});
// 数据出错不cashe
if (_.isEmpty(brandsInfo)) {
responseData.noCashe = true;
}
}
let data = {
brandsHomePage: true,
... ...
... ... @@ -48,7 +48,7 @@
{{/each}}
</div>
</div>
<div class="brands-list" >
<div class="brands-list" data-ishover="{{@root.pc.brands.disBrandNameHover}}">
{{> brand-list}}
</div>
{{/ brands}}
... ...
... ... @@ -7,8 +7,7 @@
'use strict';
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
... ... @@ -20,12 +19,12 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -17,6 +17,11 @@ exports.index = (req, res, next) => {
channelType === 'woman' ? channelType = 'girls' : null;
channelModel.getContent(channelType).then(data => {
// channel为空不缓存
if (_.isEmpty(data.channel)) {
res.set('Cache-Control', 'no-cache');
}
res.render('channel', data);
}).catch(next);
};
... ...
... ... @@ -5,14 +5,12 @@
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
var partials = path.join(__dirname, './views'); // parent view root
app.on('mount', function(parent) {
... ... @@ -20,16 +18,15 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
... ...
... ... @@ -10,6 +10,7 @@ const _ = require('lodash');
const dataMap = require('../../../config/data-map');
const helpers = global.yoho.helpers;
const config = global.yoho.config;
const processProduct = require(`${global.utils}/product-process`).processProduct;
const searchApi = require('../../product/models/search-api');
... ... @@ -335,7 +336,7 @@ const _getGirlsSingleHot = (args, type) => {
page: 1,
gender: channelMap[type].gender,
limit: 60
});
}, config.apiCache);
};
... ... @@ -592,18 +593,18 @@ const _processFloorData = (rawData, type) => {
let queryParam = '';
if (data.template_name === 'recommend_content_three' ||
(data.template_intro === '焦点图' && index === 0)) { // 处理banner
(data.template_intro === '焦点图' && index === 0)) { // 处理banner
floorData = floorMap.slide.call(null, data.data);
} else if (data.template_intro === '热门品类') { // 处理热门品类
floorData = floorMap.hot.call(null, rawData.slice(index, index + hotCategoryLength), type);
} else if (data.data && data.data.text) { // 处理一般楼层
let text = _getText(data.data.text);
let lastIndex = index + bigFloorLength < rawData.length ?
index + bigFloorLength : index + (rawData.length - index - 1);
index + bigFloorLength : index + (rawData.length - index - 1);
floorData = floorMap[text] &&
floorMap[text].call(null, rawData.slice(index, lastIndex), type);
floorMap[text].call(null, rawData.slice(index, lastIndex), type);
if (needQuery[text]) {
queryParam = getQuery(rawData.slice(index, lastIndex));
... ... @@ -657,9 +658,7 @@ const _processFloorData = (rawData, type) => {
};
const _formatResourceParams = (channel, code) => {
return serviceApi.get('operations/api/v5/resource/get', {content_code: code}, {
cache: true
}).then(data => {
return serviceApi.get('operations/api/v5/resource/get', {content_code: code}, config.apiCache).then(data => {
let result = data && data.data[0] && data.data[0].data[0];
if (result) {
... ... @@ -834,8 +833,6 @@ const getNewArrival = channel => {
};
/**
* 获取频道页数据
* @param {String} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
... ... @@ -956,9 +953,7 @@ const getIndexGuideData = () => {
private_key: '0ed29744ed318fd28d2c07985d3ba633'
};
return serviceApi.get('operations/api/v6/category/getCategory', params, {
cache: true
});
return serviceApi.get('operations/api/v6/category/getCategory', params, config.apiCache);
};
module.exports = {
... ...
... ... @@ -13,10 +13,10 @@ const index = (req, res, next) => {
let limit = req.query.limit;
let browserSkn = decodeURIComponent(req.cookies._browseskn);
let browserSkn = req.cookies._browseskn;
// 拆解skn
let skn = browserSkn ? browserSkn.replace(/\-(\d)+(\,){0,1}/g, ',') : '';
let skn = browserSkn ? decodeURIComponent(browserSkn).replace(/\-(\d)+(\,){0,1}/g, ',') : '';
// 去除skn字符串的最后一个多余的,
if (skn && skn.lastIndexOf(',') === skn.length - 1) {
... ...
... ... @@ -4,28 +4,15 @@
* @date: 2016/10/11
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
var express = require('express');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
helpers: global.yoho.helpers
}));
// router
app.use(require('./router'));
... ...
... ... @@ -42,7 +42,7 @@ const index = (skn, limit) => {
price: ${helper.round(sp, 2)}`,
product_name: hp.product_name,
url: helper.urlFormat(
`/product/pro_${hp.product_id}_${defaultGoods.goods_id}/${hp.cn_alphabet}.html`, '', 'item'),
`/product/pro_${hp.product_id}_${defaultGoods.goods_id}/${hp.cn_alphabet}.html`, null, 'item'),
pic_url: helper.image(defaultGoods.images_url, 150, 200, 2, 70)
});
});
... ...
... ... @@ -12,6 +12,7 @@ const guangModel = require('../models/index');
const headerModel = require('../../../doraemon/models/header');
const ghelper = require('../models/guang-helper');
const querystring = require('querystring');
const helpers = global.yoho.helpers;
/**
* 首页文章列表 类型列表
... ... @@ -26,16 +27,23 @@ exports.index = (req, res, next) => {
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
let gender = ghelper.getGenderByCookie(req);
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
Promise.all([
guangModel.getBanner(channel),
guangModel.getCategory(type, channel),
guangModel.getArticleList(gender, type, uid, udid, page, '', '', pageSize, channel, true),
guangModel.getHotTags(page, pageSize, channel),
guangModel.getAds(channel),
guangModel.getHotTags(page, pageSize, channel, isHotDegrade),
guangModel.getAds(channel, isAdDegrade),
guangModel.getRecoArticles(gender, 1, 10, channel),
headerModel.requestHeaderData(channel)
]).then(ret => {
if (_.isEmpty(ret[2]) || _.isEmpty(ret[2].msgs)) {
res.set('Cache-Control', 'no-cache');
}
res.render('guang/index', {
title: '逛' + (res.locals.title || ''),
guang: {
... ... @@ -77,17 +85,23 @@ exports.tags = (req, res, next) => {
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
let pathNav = guangModel.getPathNav(channel, query);
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
Promise.all([
guangModel.getBanner(channel),
guangModel.getArticleList(gender, 0, uid, udid, page, query, '', pageSize, channel, true),
guangModel.getHotTags(1, 20, channel),
guangModel.getAds(channel),
guangModel.getHotTags(1, 20, channel, isHotDegrade),
guangModel.getAds(channel, isAdDegrade),
guangModel.getRecoArticles(gender, 1, 10, channel),
headerModel.requestHeaderData(channel)
]).then(ret => {
if (_.isEmpty(ret[1]) || _.isEmpty(ret[1].msgs)) {
res.set('Cache-Control', 'no-cache');
}
res.render('guang/tag', {
title: query + (res.locals.title || ''),
guang: {
... ... @@ -121,6 +135,8 @@ exports.editor = (req, res, next) => {
let authorId = req.query.author_id;
let channel = req.yoho.channel;
let gender = ghelper.getGenderByCookie(req);
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
let uid = req.user.uid;
let udid = ghelper.getUdid(req, res);
... ... @@ -133,11 +149,16 @@ exports.editor = (req, res, next) => {
Promise.all([
guangModel.getAuthor(authorId),
guangModel.getArticleList(gender, null, uid, udid, page, '', authorId, pageSize, channel, true),
guangModel.getHotTags(1, 20, channel),
guangModel.getAds(channel),
guangModel.getHotTags(1, 20, channel, isHotDegrade),
guangModel.getAds(channel, isAdDegrade),
guangModel.getRecoArticles(gender, 1, 10, channel),
headerModel.requestHeaderData(channel)
]).then(ret => {
if (_.isEmpty(ret[1]) || _.isEmpty(ret[1].msgs)) {
res.set('Cache-Control', 'no-cache');
}
res.render('guang/editor', {
title: _.get(ret[0], 'name', '') + (res.locals.title || ''),
guang: {
... ... @@ -175,14 +196,17 @@ exports.detail = (req, res, next) => {
let udid = ghelper.getUdid(req, res);
let gender = ghelper.getGenderByCookie(req);
let channel = req.yoho.channel;
let isHotDegrade = _.get(req.app.locals.pc, 'guang.removeHotTag', false);
let isAdDegrade = _.get(req.app.locals.pc, 'guang.removeAd', false);
if (!_.isNumber(id)) {
id = parseInt(id);
id = _.parseInt(id);
}
if (pjax) {
guangModel.getArticleComments(id, page, pageSize).then(ret => {
res.set('Cache-Control', 'no-cache');
res.render('guang/detail-comment', {
layout: false,
comment: ret
... ... @@ -212,12 +236,12 @@ exports.detail = (req, res, next) => {
let promises = [
headerModel.requestHeaderData(channel),
guangModel.getArticleContent(id),
guangModel.getHotTags(1, 20, channel),
guangModel.getHotTags(1, 20, channel, isHotDegrade),
guangModel.getArticleComments(id, page, pageSize),
guangModel.getArticleBaseInfo(id, uid, udid),
guangModel.getArticleRelateBrand(id),
guangModel.getRecoArticles(gender, 1, 10, channel),
guangModel.getAds(channel)
guangModel.getAds(channel, isAdDegrade)
];
if (info.authorId) {
... ... @@ -236,6 +260,10 @@ exports.detail = (req, res, next) => {
Promise.all(promises).then(ret => {
if (_.isEmpty(ret[1])) {
res.set('Cache-Control', 'no-cache');
}
res.render('guang/detail', Object.assign({
module: 'guang',
page: 'detail',
... ... @@ -262,7 +290,11 @@ exports.detail = (req, res, next) => {
shareImg: info.shareImg,
sharedTitle: info.title,
shareDesc: info.desc,
weixinUrl: info.weixinUrl
weixinUrl: info.weixinUrl,
commentFirstPageUrl: helpers.urlFormat('/info/index', {
id: id,
pageSize: 10
}, 'guang')
}
}, {
title: `${info.title} | YOHO!BUY有货 | 年轻人潮流购物中心,中国潮流购物风向标,官方授权正品保证`,
... ...
... ... @@ -44,7 +44,7 @@ exports.pager = function() {
base = base.replace(clearSizeReg, '');
}
base += (base.indexOf('?') < 0 ? '?' : (base.charAt(base.length - 1) !== '?' ? '&' : '')) +
base += (base.indexOf('?') < 0 ? '?' : (/(\?|&)$/.test(base) ? '' : '&')) +
(options.hash.pageSize ? (pageSizeVar + '=' + pageSize + '&') : '') +
pageVar + '=';
... ...
... ... @@ -6,27 +6,24 @@
'use strict';
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
// set view engin
var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root
var partials = path.join(__dirname, './views'); // parent view root
app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [`${partials}/partial`, `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: Object.assign(require('./helpers/pager'), global.yoho.helpers)
}));
... ...
... ... @@ -121,7 +121,8 @@ const _formatArticle = (articleData, showTag, showAuthor, channel) => {
let result = {
id: articleData.id,
classification: articleData.category_name,
isReco: articleData.is_recommended ? true : false,
// isReco: articleData.is_recommended && Number(articleData.is_recommended) === 1 ? true : false,
url: ghelper.getArticleUrl(articleData.url, articleData.id, channel),
img: helpers.image(articleData.src, width, height, 1),
isSquareImg: isSquareImage,
... ... @@ -133,6 +134,26 @@ const _formatArticle = (articleData, showTag, showAuthor, channel) => {
comment: articleData.comment_num
};
if (showTag && articleData.category_id) {
switch (String(articleData.category_id)) {
case '1': // 话题
result.isTopic = true;
break;
case '2': // 搭配
result.isCollocation = true;
break;
case '3': // 潮人
result.isFashionMan = true;
break;
case '4': // 潮品
result.isFashionGood = true;
break;
case '19': // 专题
result.isSpecialTopic = true;
break;
}
}
if (!articleData.author) {
articleData.author = {
name: '',
... ... @@ -305,7 +326,7 @@ const getArticleList = (gender, sortId, uid, udid, page, tag, authorId, limit, c
* @param {String} type 传入频道页类型,值可以是: boys, girls, kids, lifestyle
* @return {Object}
*/
const getHotTags = (page, limit, channel) => {
const getHotTags = (page, limit, channel, isDegrade) => {
let data = {
client_type: 'web',
... ... @@ -313,6 +334,10 @@ const getHotTags = (page, limit, channel) => {
limit: limit || 10
};
if (isDegrade) {
return null;
}
return serviceApi.get('guang/api/v2/article/getTagTop', data, {
cache: true
}).then(res => {
... ... @@ -338,10 +363,14 @@ const getHotTags = (page, limit, channel) => {
* @param {String} channelType 传入频道页类型,值可以是: boys, girls, kids, lifestyle
* @return {Object}
*/
const getAds = channelType => {
const getAds = (channelType, isDegrade) => {
let contentCode = ADS_CODE[channelType] || ADS_CODE.boys;
if (isDegrade) {
return null;
}
return serviceApi.get(URL_OPERATIONS_RESOURCE_GET, {
content_code: contentCode
}, {cache: true}).then(res => {
... ... @@ -919,7 +948,7 @@ const getDynamicDataByIds = (ids, udid, other) => {
});
}
return serviceApi.get('guang/api/*/article/getSimpleArticleList', params, {cache: true});
return serviceApi.get('guang/api/*/article/getSimpleArticleList', params);
};
module.exports = {
... ...
... ... @@ -96,7 +96,7 @@
<div class="article-bottom-info clearfix">
{{#if tag}}
<div class="article-tag clearfix">
<i class="tag-icon iconfont">&#xe624;</i>
<i class="tag-icon iconfont">&#xe630;</i>
<ul class="clearfix">
{{# tag}}
<li>
... ... @@ -130,18 +130,21 @@
</div>
{{/if}}
<div id="comment-area" class="comment-area">
<div class="comment-textarea">
<textarea id="comment-info" placeholder="我有话要说。。。">{{commentInfo}}</textarea>
</div>
<div class="comment-publish clearfix">
<span id="word-count-tip" class="word-count-tip"></span>
<a id="comment-btn" class="publish-btn disable">评论</a>
</div>
<div id="pjax-container" class="comments-wrap">
{{> comment}}
{{#unless @root.pc.guang.removeItemComment}}
<div id="comment-area" class="comment-area">
<div class="comment-textarea">
<textarea id="comment-info" placeholder="我有话要说。。。">{{commentInfo}}</textarea>
</div>
<div class="comment-publish clearfix">
<span id="word-count-tip" class="word-count-tip"></span>
<a id="comment-btn" class="publish-btn disable">评论</a>
</div>
<div id="pjax-container" class="comments-wrap">
{{> comment}}
</div>
<a href="{{commentFirstPageUrl}}" data-role="comment-first-url" class="hide"></a>
</div>
</div>
{{/unless}}
</div>
<div class="right-side detail-side">
{{> right-side}}
... ...
... ... @@ -3,9 +3,21 @@
<div class="classification">
{{classification}}
</div>
{{#if isReco}}
<div class="reco"></div>
{{/if}}
{{# isCollocation}}
<div class="type-icon collocation"></div>
{{/ isCollocation}}
{{# isFashionMan}}
<div class="type-icon fashion-man"></div>
{{/ isFashionMan}}
{{# isFashionGood}}
<div class="type-icon fashion-good"></div>
{{/ isFashionGood}}
{{# isTopic}}
<div class="type-icon topic"></div>
{{/ isTopic}}
{{# isSpecialTopic}}
<div class="type-icon special-topic"></div>
{{/ isSpecialTopic}}
<a href="{{url}}" target="_blank">
<img class="lazy{{#if isSquareImg}} square{{/if}}" data-original="{{img}}">
</a>
... ... @@ -46,4 +58,4 @@
</div>
</div>
</div>
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -14,16 +14,18 @@
</div>
</div>
<div class="hot">
<h1 class="hot-title">热门标签</h1>
<div class="hot-tag-list">
{{#hotTags}}
<a class="hot-tag" href="{{url}}" target="_blank">
{{tagName}}
</a>
{{/hotTags}}
{{#unless @root.pc.guang.removeHotTag}}
<div class="hot">
<h1 class="hot-title">热门标签</h1>
<div class="hot-tag-list">
{{#hotTags}}
<a class="hot-tag" href="{{url}}" target="_blank">
{{tagName}}
</a>
{{/hotTags}}
</div>
</div>
</div>
{{/unless}}
<div class="ads">
{{# ads}}
... ... @@ -31,4 +33,4 @@
<img class="lazy" data-original="{{img}}">
</a>
{{/ ads}}
</div>
\ No newline at end of file
</div>
... ...
... ... @@ -15,21 +15,21 @@ const convertUnitTime = (src) => {
return moment.unix(src).format('YYYY-MM-DD');
};
const index=(req, res, next)=>{
let $uid='8041246'
let $condition={
page:req.query.page||1,
queryType:req.query.type||0,
beginTime:req.query.beginTime || convertUnitTime(new Date() / 1000 - 3600 * 24 * 90)
}
co(function*(){
let data=yield CurrencyModel.currencyData($uid, $condition);
res.render('currency',{
content:data
const index = (req, res, next)=>{
let $uid = '8041246';
let $condition = {
page: req.query.page || 1,
queryType: req.query.type || 0,
beginTime: req.query.beginTime || convertUnitTime(new Date() / 1000 - 3600 * 24 * 90)
};
co(function*() {
let data = yield CurrencyModel.currencyData($uid, $condition);
res.render('currency', {
content: data
});
})().catch(next)
}
})().catch(next);
};
module.exports={
module.exports = {
index
}
};
... ...
... ... @@ -8,37 +8,49 @@ const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const FavoriteModel=require('../models/FavoriteModel');
const favoriteService = require('../models/favorite-service');
const index=(req, res, next)=>{
const index = (req, res, next)=> {
let uid = '8041246';
let udid='8041246';
co(function*(){
let page=req.query.page||1;
let type=req.query.type||'article';
let sort=req.query.sort_id||0;
let reduction=req.query.is_reduction||'N';
let promotion=req.query.is_promotion||'N';
let limit=10,data={};
data.tabs= FavoriteModel.getFavoriteTabs(type);
switch(type){
case 'brand':data.favBrands=yield FavoriteModel.favoriteBrandList(uid,page,limit,type);break;
case 'article':data.favArticles=yield FavoriteModel.favoriteArticleList(uid,udid,page,limit,type);break;
default:data.favProducts= yield FavoriteModel.favoriteProductList(uid,page,limit,type,sort,'N',reduction,promotion);break;
let udid = '8041246';
co(function*() {
let page = req.query.page || 1;
let type = req.query.type || 'article';
let sort = req.query.sort_id || 0;
let reduction = req.query.is_reduction || 'N';
let promotion = req.query.is_promotion || 'N';
let limit = 10;
let data = {};
data.tabs = favoriteService.getFavoriteTabs('product');
switch (type) {
case 'brand':
data.favBrands = yield favoriteService.favoriteBrandList(uid, page, limit, type);
break;
case 'article':
data.favArticles = yield favoriteService.favoriteArticleListAsync(uid, udid, page, limit);
break;
default:
data.favProducts = yield favoriteService.favoriteProductList(uid, page, limit, type, sort, 'N', reduction, promotion);
break;
}
console.log(data);
res.render("favorite",{
meFavoritePage:true,
meFavorite:data
res.render('favorite', {
meFavoritePage: true,
meFavorite: data
});
})();
}
})().then(next);
};
const reductionAction=()=>{
const reductionAction = ()=> {
}
};
module.exports ={
module.exports = {
index
}
};
... ...
... ... @@ -7,10 +7,10 @@ const index = (req, res, next)=>{
let $uid = '8041246';// req.user.uid;
let $udid = 'abcdrf';// req.sessionID;
co(function*(){
co(function*() {
let result = yield RedenvelopesModel.redenvelopesList($uid);
res.render('Redenvelopes',{
meRedEnvelopes:result
res.render('Redenvelopes', {
meRedEnvelopes: result
});
})().catch(next);
};
... ...
... ... @@ -4,68 +4,68 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
let CouponsModel=require('../models/CouponsModel');
let CouponsModel = require('../models/CouponsModel');
const helpers = global.yoho.helpers;
const index=(req,res,next)=>{
let uid='8041246';
let type=req.query.type||CouponsModel.UNUSED;
let page='';
let limit='';
co(function*(){
let coupons= yield CouponsModel.getCouponsList(uid,type,page,limit);
let data={};
data.pager={
hasCheckAll:false,
count:coupons.pager.total||0,
curPage:coupons.pager.page||0,
totalPages:coupons.pager.pageTotal||0
const index = (req, res, next)=>{
let uid = '8041246';
let type = req.query.type || CouponsModel.UNUSED;
let page = '';
let limit = '';
co(function*() {
let coupons = yield CouponsModel.getCouponsList(uid, type, page, limit);
let data = {};
data.pager = {
hasCheckAll: false,
count: coupons.pager.total || 0,
curPage: coupons.pager.page || 0,
totalPages: coupons.pager.pageTotal || 0
};
if(type===CouponsModel.UNUSED){
if(!coupons.list.length){
data.unUseCoupons={empty:'您没有优惠券'};
}else{
data.unUseCoupons=coupons.list;
if (type === CouponsModel.UNUSED) {
if (!coupons.list.length) {
data.unUseCoupons = {empty: '您没有优惠券'};
} else {
data.unUseCoupons = coupons.list;
}
data.unUse=true;
}else if(type===CouponsModel.USED){
if(!coupons.list.length){
data.usedCoupons={empty:'您没有优惠券'};
}else{
data.usedCoupons=coupons.list;
data.unUse = true;
} else if (type === CouponsModel.USED) {
if (!coupons.list.length) {
data.usedCoupons = {empty: '您没有优惠券'};
} else {
data.usedCoupons = coupons.list;
}
data.used=true;
data.used = true;
}
else if(type===CouponsModel.INVALID){
if(!coupons.list.length){
data.noValidCoupons={empty:'您没有优惠券'};
}else{
data.noValidCoupons=coupons.list;
else if (type === CouponsModel.INVALID) {
if (!coupons.list.length) {
data.noValidCoupons = {empty: '您没有优惠券'};
} else {
data.noValidCoupons = coupons.list;
}
data.noValid=true;
data.noValid = true;
}
data.tabs=[
data.tabs = [
{
active:type===CouponsModel.UNUSED?true:false,
url:helpers.urlFormat('/home/coupons',{type:CouponsModel.UNUSED}),
name:'未使用优惠券'
active: type === CouponsModel.UNUSED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.UNUSED}),
name: '未使用优惠券'
},
{
ctive:type===CouponsModel.USED?true:false,
url:helpers.urlFormat('/home/coupons',{type:CouponsModel.USED}),
name:'已使用优惠券'
ctive: type === CouponsModel.USED ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.USED}),
name: '已使用优惠券'
},
{
ctive:type===CouponsModel.INVALID?true:false,
url:helpers.urlFormat('/home/coupons',{type:CouponsModel.INVALID}),
name:'已失效优惠券'
ctive: type === CouponsModel.INVALID ? true : false,
url: helpers.urlFormat('/home/coupons', {type: CouponsModel.INVALID}),
name: '已失效优惠券'
}
];
res.render("coupons",data);
res.render('coupons', data);
})();
}
};
module.exports = {
index
... ...
... ... @@ -2,59 +2,60 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
const UserData=require('../models/UserData');
const moment =require('moment');
const UserData = require('../models/UserData');
const moment = require('moment');
const helpers = global.yoho.helpers;
const index=(req, res, next)=>{
const index = (req, res, next)=>{
let uid = '8041246';// req.user.uid;
co(function*(){
let vipInfo=yield UserData.getVIPInfoByUid(uid);
let data=vipInfo.data,proportion='0%';
if(+data.next_need_cost!=0){
proportion=data.current_year_cost*100/data.next_need_cost;
proportion=proportion>100?100:proportion;
proportion=proportion+'%';
co(function*() {
let vipInfo = yield UserData.getVIPInfoByUid(uid);
let data = vipInfo.data, proportion = '0%';
if (+data.next_need_cost != 0) {
proportion = data.current_year_cost * 100 / data.next_need_cost;
proportion = proportion > 100 ? 100 : proportion;
proportion = proportion + '%';
}
let remainDays=Math.floor((Date.now()-(+data.vip_end_time)*1000)/86400);
let remainDays = Math.floor((Date.now() - (+data.vip_end_time) * 1000) / 86400);
// let preferences={};
// enjoyPreferences=data.enjoy_preferential;
if(data.enjoy_preferential){
data.enjoy_preferential=data.enjoy_preferential.map(function(item,inex){
if (data.enjoy_preferential) {
data.enjoy_preferential = data.enjoy_preferential.map(function(item, inex) {
return {
id:item.id,
favTxt:item.title,
imgType:helpers.https(item.pic),
description:item.description
}
id: item.id,
favTxt: item.title,
imgType: helpers.https(item.pic),
description: item.description
};
});
}
let vip={
title:data.current_vip_title,
level:data.current_vip_level,
totalCost:(+data.current_total_cost).toFixed(2),
nextTitle:data.next_vip_title,
nextLevel:data.next_vip_level,
nextCost:data.next_need_cost,
enjoyPreferences:data.enjoy_preferential,
yearCost:data.current_year_cost,
upgradeCost:data.upgrade_need_cost,
proportion:proportion,
reach:moment(data.vip_reach_time*1000).format("YYYY-MM-DD"),
start:moment(data.vip_start_time*1000).format("YYYY-MM-DD"),
end:moment(data.vip_end_time*1000).format("YYYY-MM-DD"),
remainDays:remainDays,
platinum:data.upgrade_need_cost>0?false:true,
isVip:data.current_vip_level>0?true:false
}
res.render("vip",vip);
let vip = {
title: data.current_vip_title,
level: data.current_vip_level,
totalCost: (+data.current_total_cost).toFixed(2),
nextTitle: data.next_vip_title,
nextLevel: data.next_vip_level,
nextCost: data.next_need_cost,
enjoyPreferences: data.enjoy_preferential,
yearCost: data.current_year_cost,
upgradeCost: data.upgrade_need_cost,
proportion: proportion,
reach: moment(data.vip_reach_time * 1000).format('YYYY-MM-DD'),
start: moment(data.vip_start_time * 1000).format('YYYY-MM-DD'),
end: moment(data.vip_end_time * 1000).format('YYYY-MM-DD'),
remainDays: remainDays,
platinum: data.upgrade_need_cost > 0 ? false : true,
isVip: data.current_vip_level > 0 ? true : false
};
res.render('vip', vip);
})().catch(next);
}
};
module.exports = {
index
... ...
... ... @@ -5,8 +5,7 @@
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
... ... @@ -17,12 +16,13 @@ app.on('mount', function(parent) {
delete parent.locals.settings; // 不继承父 App 的设置
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -4,79 +4,80 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
const UserData=require('./UserData');
const UserData = require('./UserData');
const helpers = global.yoho.helpers;
const UNUSED='notuse';
const USED='use';
const INVALID='overtime';
const UNUSED = 'notuse';
const USED = 'use';
const INVALID = 'overtime';
const getCouponsList=(uid,type,page,limit)=>{
return co(function*(){
let couponsInfo= yield UserData.getCouponsList(uid,type,page,limit);
let result=[];
if(!couponsInfo.data.couponList){
const getCouponsList = (uid, type, page, limit)=>{
return co(function*() {
let couponsInfo = yield UserData.getCouponsList(uid, type, page, limit);
let result = [];
if (!couponsInfo.data.couponList) {
return result;
}
let coupons=couponsInfo.data.couponList;
if(coupons){
coupons.forEach(function(item,i){
result[i]={};
result[i].id=item.couponId;
result[i].code=item.couponCode;
let coupons = couponsInfo.data.couponList;
if (coupons) {
coupons.forEach(function(item, i) {
result[i] = {};
result[i].id = item.couponId;
result[i].code = item.couponCode;
// 格式化有效日期 "couponValidity": "2016.03.15-2016.03.31"
let dates=item.couponValidity.split('-');
let dates = item.couponValidity.split('-');
result[i].beginTime=dates[0].replace('.','-');
result[i].endTime=dates[1].replace('.','-');
result[i].beginTime = dates[0].replace('.', '-');
result[i].endTime = dates[1].replace('.', '-');
if(!item.couponImageUrl){
result[i].img='//static.yohobuy.com/images/v2/activity/default_coupon.jpg';
}else{
result[i].img=item.couponImageUrl;
if (!item.couponImageUrl) {
result[i].img = '//static.yohobuy.com/images/v2/activity/default_coupon.jpg';
} else {
result[i].img = item.couponImageUrl;
}
if((item.overTime-Date.now())<259200){
result[i].endSoon=true;
}else{
result[i].endSoon=false;
if ((item.overTime - Date.now()) < 259200) {
result[i].endSoon = true;
} else {
result[i].endSoon = false;
}
result[i].value=item.couponValue.toFixed(2);
result[i].validity=item.couponValidity;
result[i].useRemark=item.couponDetailInfomation;
result[i].value = item.couponValue.toFixed(2);
result[i].validity = item.couponValidity;
result[i].useRemark = item.couponDetailInfomation;
if(type===USED){
result[i].orderNum=item.orderCode?item.orderCode:'';
result[i].orderDetailUrl=helpers.urlFormat('/home/orders/detail',{orderCode:item.orderCode||''});
result[i].orderSum=item.orderPrice.toFixed(2)?item.orderPrice:0;
result[i].payment=item.actuallyPaid.toFixed(2)?item.actuallyPaid:0;
let data=result[i].usedTime?moment(result[i].usedTime).format("YYYY-MM-DD"):0;
if(data){
result[i].useTime=new Date(date).getTime();
}else{
result[i].useTime='';
if (type === USED) {
result[i].orderNum = item.orderCode ? item.orderCode : '';
result[i].orderDetailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: item.orderCode || ''});
result[i].orderSum = item.orderPrice.toFixed(2) ? item.orderPrice : 0;
result[i].payment = item.actuallyPaid.toFixed(2) ? item.actuallyPaid : 0;
let data = result[i].usedTime ? moment(result[i].usedTime).format('YYYY-MM-DD') : 0;
if (data) {
result[i].useTime = new Date(date).getTime();
} else {
result[i].useTime = '';
}
}else{
result[i].status=item.isValidity?'可使用' : '已过期';
} else {
result[i].status = item.isValidity ? '可使用' : '已过期';
}
if(item.couponType){
result[i].type=item.couponType;
if(item.couponType==5){
result[i].value='免邮';
if (item.couponType) {
result[i].type = item.couponType;
if (item.couponType == 5) {
result[i].value = '免邮';
}
}
});
}
return {list:result,pager:{
total:couponsInfo.data.total,
pageTotal:couponsInfo.data.totalPageNum,
page:page
return {list: result, pager: {
total: couponsInfo.data.total,
pageTotal: couponsInfo.data.totalPageNum,
page: page
}};
})();
}
};
module.exports = {
getCouponsList,
... ...
... ... @@ -6,25 +6,25 @@
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const yohoCoinList=(uid, condition)=>{
condition=condition||{};
const yohoCoinList = (uid, condition)=>{
condition = condition || {};
let options = {
method: 'app.yohocoin.lists',
uid: uid,
page: 1,
limit: 15
};
Object.assign(options,condition);
Object.assign(options, condition);
return api.get('', options);
}
};
const yohoCoinTotal=uid=>{
const yohoCoinTotal = uid=>{
let options = {
method: 'app.yoho.yohocoin',
uid: uid
};
return api.get('', options);
}
};
module.exports = {
yohoCoinList,
... ...
... ... @@ -6,13 +6,13 @@
const Promise = require('bluebird');
const co = Promise.coroutine;
const path=require('path');
const path = require('path');
const helpers = global.yoho.helpers;
const api = global.yoho.API;
const _ = require('lodash');
const Image = require('../../../utils/images');
const CurrencyData=require('./CurrencyData');
const SearchData=require('./SearchData');
const CurrencyData = require('./CurrencyData');
const SearchData = require('./SearchData');
// 使用 product中的分页逻辑
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
... ... @@ -24,54 +24,56 @@ const convertUnitTime = (src) => {
return moment.unix(src).format('YYYY-MM-DD');
};
const currencyData=(uid, condition)=>{
return co(function*(){
let result={};
let yohoCoinInfo=yield CurrencyData.yohoCoinTotal(uid);
const currencyData = (uid, condition)=>{
return co(function*() {
let result = {};
let yohoCoinInfo = yield CurrencyData.yohoCoinTotal(uid);
console.log(yohoCoinInfo);
if(yohoCoinInfo.code&& yohoCoinInfo.code == 200){
let yohoCoinInfoData=yohoCoinInfo.data;
if (yohoCoinInfo.code && yohoCoinInfo.code == 200) {
let yohoCoinInfoData = yohoCoinInfo.data;
result.myCurrency = yohoCoinInfoData.yohocoin_num ? yohoCoinInfoData.yohocoin_num : 0;
if (yohoCoinInfoData.nearExpCoinNum && yohoCoinInfoData.nearExpCoinNum > 0) {
result.tip.count =yohoCoinInfoData.nearExpCoinNum;
result.tip.date ='Y年12月31日';
result.tip.count = yohoCoinInfoData.nearExpCoinNum;
result.tip.date = 'Y年12月31日';
}
}
let currency =yield currencyList(uid, condition);
let currency = yield currencyList(uid, condition);
result.currency = currency.list;
result.pager = currency.pager;
result.coinHelperUrl = '//www.yohobuy.com/help/?category_id=87';//yoho币帮助
result.coinHelperUrl = '//www.yohobuy.com/help/?category_id=87';// yoho币帮助
result.tabs = currencyTabs(condition.queryType);
result.options = currencyOptions(condition);
return result;
})();
}
};
const currencyList=(uid,condition)=>{
return co(function*(){
let result={'list':[], 'pager':[]};
condition.limit=condition.limit||15;
const currencyList = (uid, condition)=>{
return co(function*() {
let result = {'list': [], 'pager': []};
condition.limit = condition.limit || 15;
let data = yield CurrencyData.yohoCoinList(uid, condition);
if (data.code&& data.code ==200 && data.data.coinlist && !_.isEmpty(data.data.coinlist)) {
if (data.code && data.code == 200 && data.data.coinlist && !_.isEmpty(data.data.coinlist)) {
// data.data.coinlist.forEach(function(val,key){
for(let key=0;key<data.data.coinlist.length;key++){
let val=data.data.coinlist[key];
result.list[key]={
date:val['date'],
desc:val['message'],
isIncome:true
}
//2:订单取消退还,9:下单使用,10:退货退还
if ([2,9,10].indexOf(val.type)>-1 && val.key) {
result.list[key].detailUrl = helpers.urlFormat('/home/orders/detail', {orderCode:val['key']});
for (let key = 0; key < data.data.coinlist.length; key++) {
let val = data.data.coinlist[key];
result.list[key] = {
date: val['date'],
desc: val['message'],
isIncome: true
};
// 2:订单取消退还,9:下单使用,10:退货退还
if ([2, 9, 10].indexOf(val.type) > -1 && val.key) {
result.list[key].detailUrl = helpers.urlFormat('/home/orders/detail', {orderCode: val['key']});
}
//晒单奖励
// 晒单奖励
else if (val.type == 14 && val.key) {
let product = yield SearchData.searchAll({query:Number(val.key),viewNum:1});
if (product.code && product.code== 200 && !_.isEmpty(product.data.product_list) && !_.isEmpty(product.data.product_list[0].goods_list)) {
let product = yield SearchData.searchAll({query: Number(val.key), viewNum: 1});
if (product.code && product.code == 200 && !_.isEmpty(product.data.product_list) && !_.isEmpty(product.data.product_list[0].goods_list)) {
productId = product.data.product_list[0].product_id;
goodsId = product.data.product_list[0].goods_list[0].goods_id;
result.list[key].detailUrl = helpers.getUrlBySkc(productId, goodsId, product.data.product_list[0].cn_alphabet);
... ... @@ -80,14 +82,16 @@ const currencyList=(uid,condition)=>{
if (Number(val['num']) < 0) {
result.list[key].isIncome = false;
}
result.list[key].value = val['num'] > 0 ? '+'+val['num'] : val['num'] ;
result.list[key].value = val['num'] > 0 ? '+' + val['num'] : val['num'];
}
//分页
// 分页
let total = data.data.total;
let pagerObj = pager(total, {
page: data['data']['page'],
limit: condition['limit']
});
// result['pager']={};
// result['pager']['hasCheckAll'] = false;
// result['pager']['count'] = data['data']['total'];
... ... @@ -97,33 +101,33 @@ const currencyList=(uid,condition)=>{
}
return result;
})();
}
const currencyTabs=(type)=>{
let result=['全部明细', '全部收入', '全部支出'];
result=result.forEach(function(val,key){
};
const currencyTabs = (type)=>{
let result = ['全部明细', '全部收入', '全部支出'];
result = result.forEach(function(val, key) {
return {
active:key == type ? true : false,
url:helpers.urlFormat('/home/currency',{type:key})
}
active: key == type ? true : false,
url: helpers.urlFormat('/home/currency', {type: key})
};
});
return result;
}
const currencyOptions=(condition)=>{
let result=[],paramUrl={};
let tabs={'90':'最近3个月明细','180':'最近半年明细','360':'最近一年明细'};
for(let name in tabs){
if(condition.queryType){
};
const currencyOptions = (condition)=>{
let result = [], paramUrl = {};
let tabs = {'90': '最近3个月明细', '180': '最近半年明细', '360': '最近一年明细'};
for (let name in tabs) {
if (condition.queryType) {
paramUrl.type = condition.queryType;
}
paramUrl.beginTime = convertUnitTime(new Date() / 1000 - 3600 * 24 );
paramUrl.beginTime = convertUnitTime(new Date() / 1000 - 3600 * 24);
result.push({
url:helpers.urlFormat('/home/currency',paramUrl),
name:tabs[name],
selected:condition.beginTime&&paramUrl.beginTime == condition.beginTime ? true : false
url: helpers.urlFormat('/home/currency', paramUrl),
name: tabs[name],
selected: condition.beginTime && paramUrl.beginTime == condition.beginTime ? true : false
});
}
return result;
}
};
module.exports = {
currencyData
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const path=require('path');
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
const pager = require(pagerPath).handlePagerData;
const FavoriteData=require('./FavoriteData');
const TABS=[
{type:'product',name:'商品收藏'},
{type:'brand',name:'品牌收藏'},
{type:'article',name:'文章收藏'}
];
const getFavoriteTabs=type=>{
type=type||'product';
return TABS.map((item)=>{
if(item.type===type){
item.active=true;
}
item.url=helpers.urlFormat('/home/favorite',{type:item['type']});
return item;
})
}
const favoriteProductList=(uid,page,limit,type,sort,subscribe,reduction,promotion)=>{
return co(function*(){
let data={},product={},result={
sort:{},reduction:{},filter:{},goods:{},pager:{}
};
product=yield FavoriteData.getFavoriteProductList(uid);
if(product.data.category_list){
result.sort= getSortInfo(product.data.category_list,sort);
}
result.reduction=yield redutionCount(uid);
let productList=[];
if(product.data.product_list){
product.data.product_list.forEach(function(product){
if(
(reduction==='Y'&&promotion=='Y'&&product.is_price_down=='Y'&&promotion=='Y')||
(sort&&product.category_id==sort)||
(subscribe&&product.is_subscribe_reduction=='Y')||
(reduction=='Y'&&product.is_price_down=='Y')||
(promotion=='Y'&&product.is_join_promotion=='Y')
){
productList.push(product);
}
});
productList=product.data.product_list;
}
if(reduction=='N'&&promotion=='N'){
result.filter={
reductionUrl:helpers.urlFormat('/home/favorite',{is_reduction:'Y'}),
reductionChecked:'',
activityUrl:helpers.urlFormat('/home/favorite',{is_promotion:'Y'}),
activityChecked:''
};
}else
if(reduction=='N'&&promotion=='Y'){
result.filter={
reductionUrl:helpers.urlFormat('/home/favorite',{is_reduction:'Y',is_promotion:'Y'}),
reductionChecked:'',
activityUrl:helpers.urlFormat('/home/favorite',{is_promotion:'Y'}),
activityChecked:''
};
}else
if(reduction=='Y'&&promotion=='N'){
result.filter={
reductionUrl:helpers.urlFormat('/home/favorite',{is_reduction:'Y',is_promotion:'Y'}),
reductionChecked:'',
activityUrl:helpers.urlFormat('/home/favorite',{is_promotion:'Y',is_promotion:'Y'}),
activityChecked:''
}
}else{
result.filter={
reductionUrl:helpers.urlFormat('/home/favorite',{is_reduction:'Y',is_promotion:'Y'}),
reductionChecked:'',
activityUrl:helpers.urlFormat('/home/favorite',{is_promotion:'Y',is_promotion:'Y'}),
activityChecked:''
}
}
let total=productList;
let pageTotal=Math.ceil(total/limit);
result.pager=getPager(page,total,pageTotal);
result.goods=getGoodsInfo(productList,page,limit);
return result;
})();
}
const favoriteBrandList=(uid,page,limit,type)=>{
return co(function*(){
let result={
brands:{
empty:'您没有收藏品牌',
pager:{}
}
};
let brand=yield FavoriteData.favoriteBrandData(uid,page,limit);
if(!brand.data||!brand.data.page_total){
return result;
}
if(brand.data.page_total<page){
page=brand.data.page_total;
brand=yield FavoriteData.favoriteBrandData(uid,page,limit);
}
if(!brand.data.brand_list){
return result;
}
let brands=[];
brand.data.brand_list.forEach((item,i)=>{
brands.push({
id:item.brand_id,
brandOrShopType:item.brandOrShopType||'',
shop_id:item.shop_id||'',
img:helpers.image(item.brand_ico,100,100),
url:helpers.urlFormat('',{shopId:item.shop_id||''},item.brand_domain),
name:item.brand_name,
naCount:item.new_product_num,
colCount:item.brand_favorite_num
});
});
result.brands=brands;
let total=brand.data.total||0;
let pageTotal=brand.data.page_total||0;
page=brand.data.page||0;
result.pager=getPager(page,total,pageTotal);
return result;
})();
}
const favoriteArticleList=(uid,udid,page,limit,type)=>{
return co(function*(){
let result={articles:[],pager:{}};
let article=yield FavoriteData.favoriteArticleData(uid,udid,page,limit);
if(!article.data&&!article.data.data){
article.data.data.forEach((item,i)=>{
result.articles.push({
id:item.id,
name:item.title,
img:helpers.image(item.src,146,96),
desc:item.intro,
url:helpers.urlFormat('/'+item.id+'.html','','guang')
});
});
let total=article.data.total||0;
let pageTotal=article.data.totalPage||0;
let page=article.data.page||0;
result.pager=getPager(page,total,pageTotal);
}else{
result.articles={empty:'你尚未收藏任何文章!'};
}
return result;
})();
}
const getPager=(page,total,totalPage,size,type)=>{
let result={};
if(page&&total&&totalPage){
result={
count:total,
curPage:page,
totalPages:totalPage,
hasCheckAll:true
};
}
return result;
}
const getGoodsInfo=(data,page,limit)=>{
let result=[];
let begin=(page-1)*limit;
if(!data){
data=data.slice(begin,limit);
data.forEach((item,i)=>{
let obj={
skn:item.product_id,
img:helpers.img(item.image,100,100),
name:item.product_name,
url:helpers.getUrlBySkc(item.product_id,item.goodsId,item.cnAlphabet),
price:item.sales_price,
priceDown:item.price_down,
buyNow:helpers.getUrlBySkc(item.product_id,item.goodsId,item.cnAlphabet),
soldOut:item.storage==0?true:'',
hadNoticed:item.is_subscribe_reduction=='Y'?true:'',
count:item.promotion_list?item.promotion_list.length:0
}
if(item.promotion_list){
item.promotion_list.forEach(function(item1){
obj.activites.list.push({
type:item1.promotion_type,
name:item1.promotion_title
});
});
}
result.push(obj);
});
}else{
result={empty:'您没有收藏商品'};
}
return result;
}
const redutionCount=(uid)=>{
return co(function*(){
let result={count:0,url:'/home/favorite/reduction',phone:''};
let data=yield FavoriteData.redutionCount(uid);
if(data.data.num){
result.count=+data.data.num;
result.phone=data.data.mobile;
}
return result;
})();
}
const getSortInfo=(categoryList,sort)=>{
let result={default:{},all:[]};
let defaultCategory={name:'全部',url:helpers.urlFormat('/home/favorite'),count:0,focus:''};
categoryList.forEach(function(category){
result.all.push({
name:category.category_name,
url:helpers.urlFormat('/home/favorite',{sort_id:category.category_id}),
count:category.num,
focus:category.category_id==sort?true:''
});
defaultCategory.count+=category.num;
defaultCategory.focus=sort==0?true:'';
});
result.all.unshift(defaultCategory);
result.default=result.all.slice(result.all,0,7);
return result;
}
module.exports ={
getFavoriteTabs,
favoriteProductList,
favoriteArticleList
}
... ... @@ -31,10 +31,10 @@ const formatNew = (product)=>{
let result = [];
product.forEach(function(val, key) {
result[key] = {
href:helpers.getUrlBySkc(val['product_id'], val['goods_list'][0]['product_skc'], val['cn_alphabet']),
thumb:val['default_images'] ? Images.getImageUrl(val['default_images'], 400, 500) : '',
name:val['product_name'],
price:val['sales_price']
href: helpers.getUrlBySkc(val['product_id'], val['goods_list'][0]['product_skc'], val['cn_alphabet']),
thumb: val['default_images'] ? Images.getImageUrl(val['default_images'], 400, 500) : '',
name: val['product_name'],
price: val['sales_price']
};
});
return result;
... ...
... ... @@ -6,25 +6,25 @@ const api = global.yoho.API;
* 获取红包列表
* $uid 用户ID
*/
const getRedenvelopes=uid=>{
const getRedenvelopes = uid=>{
let options = {
method: 'app.yoho.redpacketList',
uid: uid
};
return api.get('', options);
}
};
/**
* 获取红包列表
* uid 用户ID
*/
const getRedenvelopesTotal=uid=>{
const getRedenvelopesTotal = uid=>{
let options = {
method: 'app.yoho.redpacketInfo',
uid: uid
};
return api.get('', options);
}
};
module.exports = {
getRedenvelopes,
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const RedenvelopesData=require('./RedenvelopesData.js');
const RedenvelopesData = require('./RedenvelopesData.js');
const redenvelopesList=uid=>{
return co(function*(){
let result={};
let data= yield RedenvelopesData.getRedenvelopesTotal(uid);
if(data.code && data.code==200 && data.data.redpacket_num){
result.money=data.data.redpacket_num;
result.termOfValidity=data.data.useable_time;
const redenvelopesList = uid=>{
return co(function*() {
let result = {};
let data = yield RedenvelopesData.getRedenvelopesTotal(uid);
if (data.code && data.code == 200 && data.data.redpacket_num) {
result.money = data.data.redpacket_num;
result.termOfValidity = data.data.useable_time;
}
result.useRemark="1.红包活动,全场通用(预售商品除外);<br>2.结算时折抵现金使用,可以和优惠券叠加使用;<br>3.限有效期内使用,过期清零";
result.useRemark = '1.红包活动,全场通用(预售商品除外);<br>2.结算时折抵现金使用,可以和优惠券叠加使用;<br>3.限有效期内使用,过期清零';
return [result];
})();
}
};
module.exports = {
redenvelopesList
}
};
... ...
... ... @@ -4,7 +4,7 @@
'use strict';
const querystring = require('querystring');
const searchApi=global.yoho.SearchAPI;
const searchApi = global.yoho.SearchAPI;
const getUrl = (type)=>{
... ... @@ -71,9 +71,9 @@ const getProductUrl = (condition, type)=>{
};
const searchAll = (param)=>{
param=param||{};
return searchApi.get(getUrl(type), param,{cache:true});
}
param = param || {};
return searchApi.get(getUrl(type), param, {cache: true});
};
module.exports = {
getProductUrl,
... ...
... ... @@ -2,37 +2,37 @@
const api = global.yoho.API;
const privateKeyList={
'android':'fd4ad5fcfa0de589ef238c0e7331b585',
'iphone':'a85bb0674e08986c6b115d5e3a4884fa',
'ipad':'ad9fcda2e679cf9229e37feae2cdcf80',
'web':'0ed29744ed318fd28d2c07985d3ba633',
'h5':'fd4ad5fcfa0de589ef238c0e7331b585'
}
const privateKeyList = {
'android': 'fd4ad5fcfa0de589ef238c0e7331b585',
'iphone': 'a85bb0674e08986c6b115d5e3a4884fa',
'ipad': 'ad9fcda2e679cf9229e37feae2cdcf80',
'web': '0ed29744ed318fd28d2c07985d3ba633',
'h5': 'fd4ad5fcfa0de589ef238c0e7331b585'
};
const getVIPInfoByUid = (uid)=>{
let options = {
method: 'app.passport.vip',
uid: uid,
private_key:"0ed29744ed318fd28d2c07985d3ba633"
private_key: '0ed29744ed318fd28d2c07985d3ba633'
};
return api.get('', options);
};
const getCouponsList=(uid,type,page,limit)=>{
page=page||1;
type=type||'notuse';
limit=limit||10;
const getCouponsList = (uid, type, page, limit)=>{
page = page || 1;
type = type || 'notuse';
limit = limit || 10;
let options = {
method: 'app.coupons.lists',
uid: uid,
type:type,
page:page,
limit:limit
type: type,
page: page,
limit: limit
};
return api.get('', options);
}
};
module.exports = {
getVIPInfoByUid,
... ...
'use strict';
const api = global.yoho.API;
const service=global.yoho.ServiceAPI;
const service = global.yoho.ServiceAPI;
const URL_PRODUCT_FAVORITE = 'shops/service/v1/favorite/';
const URL_ARTICLE_FAVORITE = '/guang/api/v1/favorite/';
... ... @@ -15,43 +15,48 @@ const URL_ARTICLE_FAVORITE_BRAND = '/guang/service/v2/favorite/toggleBrand';
* @param boolean $isOnlyUrl 是否指返回链接
* @return boolean 收藏 true 未收藏 false
*/
const getUidProductFav=(uid,productId,isOnlyUrl)=>{
isOnlyUrl=(isOnlyUrl===undefined)?false:isOnlyUrl;
const getUidProductFav = (uid, productId, isOnlyUrl)=> {
isOnlyUrl = (isOnlyUrl === undefined) ? false : isOnlyUrl;
let options = {
method: 'web.favorite.isFavorite',
id: productId,
uid: uid,
type:'product'
type: 'product'
};
return api.get('', options);
}
const favoriteArticleData=(uid,udid,page,limit)=>{
};
const favoriteArticleData = (uid, udid, page, limit)=> {
let options = {
uid: uid,
udid: udid,
page: page,
limit:limit
limit: limit
};
return service.get(URL_ARTICLE_FAVORITE+'getUserFavArticleList', options);
}
const getFavoriteProductList = (uid, limit)=>{
limit=limit||500;
return service.get(URL_ARTICLE_FAVORITE + 'getUserFavArticleList', options);
};
const getFavoriteProductList = (uid, limit)=> {
limit = limit || 500;
let options = {
method: 'web.favorite.product',
uid: uid,
limit: limit
};
return api.get('', options);
};
const redutionCount=(uid)=>{
let options={
method:'web.redution.count',
uid:uid
const redutionCount = (uid)=> {
let options = {
method: 'web.redution.count',
uid: uid
};
return api.get('',options);
}
return api.get('', options);
};
module.exports = {
getUidProductFav,
... ...
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const helpers = global.yoho.helpers;
const path = require('path');
const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
const pager = require(pagerPath).handlePagerData;
const favoriteApi = require('./favorite-api');
const TABS = [
{type: 'product', name: '商品收藏'},
{type: 'brand', name: '品牌收藏'},
{type: 'article', name: '文章收藏'}
];
const getFavoriteTabs = (type) => {
type = type || 'product';
return TABS.map((item) => {
item.active = item.type === type;
item.url = helpers.urlFormat('/home/favorite', {type: item.type});
return item;
});
};
const favoriteProductList = (uid, page, limit, type, sort, subscribe, reduction, promotion) => {
return co(function*() {
let data = {};
let product = {};
let result = {
sort: {},
reduction: {},
filter: {},
goods: {},
pager: {}
};
product = yield favoriteApi.getFavoriteProductList(uid);
if (product.data.category_list) {
result.sort = getSortInfo(product.data.category_list, sort);
}
result.reduction = yield redutionCount(uid);
let productList = [];
if (product.data.product_list) {
product.data.product_list.forEach(function(product) {
if (
(reduction === 'Y' && promotion === 'Y' && product.is_price_down === 'Y' && promotion === 'Y') ||
(sort && product.category_id === sort) ||
(subscribe && product.is_subscribe_reduction === 'Y') ||
(reduction === 'Y' && product.is_price_down === 'Y') ||
(promotion === 'Y' && product.is_join_promotion === 'Y')
) {
productList.push(product);
}
});
productList = product.data.product_list;
}
if (reduction === 'N' && promotion === 'N') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
activityChecked: ''
};
} else if (reduction === 'N' && promotion === 'Y') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y'}),
activityChecked: ''
};
} else if (reduction === 'Y' && promotion === 'N') {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y', is_promotion: 'Y'}),
activityChecked: ''
};
} else {
result.filter = {
reductionUrl: helpers.urlFormat('/home/favorite', {is_reduction: 'Y', is_promotion: 'Y'}),
reductionChecked: '',
activityUrl: helpers.urlFormat('/home/favorite', {is_promotion: 'Y', is_promotion: 'Y'}),
activityChecked: ''
};
}
let total = productList;
let pageTotal = Math.ceil(total / limit);
result.pager = getPager(page, total, pageTotal);
result.goods = getGoodsInfo(productList, page, limit);
return result;
})();
};
const favoriteBrandList = (uid, page, limit, type)=> {
return co(function*() {
let result = {
brands: {
empty: '您没有收藏品牌',
pager: {}
}
};
let brand = yield favoriteApi.favoriteBrandData(uid, page, limit);
if (!brand.data || !brand.data.page_total) {
return result;
}
if (brand.data.page_total < page) {
page = brand.data.page_total;
brand = yield favoriteApi.favoriteBrandData(uid, page, limit);
}
if (!brand.data.brand_list) {
return result;
}
let brands = [];
brand.data.brand_list.forEach((item, i)=> {
brands.push({
id: item.brand_id,
brandOrShopType: item.brandOrShopType || '',
shop_id: item.shop_id || '',
img: helpers.image(item.brand_ico, 100, 100),
url: helpers.urlFormat('', {shopId: item.shop_id || ''}, item.brand_domain),
name: item.brand_name,
naCount: item.new_product_num,
colCount: item.brand_favorite_num
});
});
result.brands = brands;
let total = brand.data.total || 0;
let pageTotal = brand.data.page_total || 0;
page = brand.data.page || 0;
result.pager = getPager(page, total, pageTotal);
return result;
})();
};
const favoriteArticleListAsync = (uid, udid, page, limit)=> {
return co(function*() {
let result = {articles: [], pager: {}};
let articles = yield favoriteApi.favoriteArticleData(uid, udid, page, limit);
if (!articles.data && !articles.data.data) {
articles.data.data.forEach((item)=> {
result.articles.push({
id: item.id,
name: item.title,
img: helpers.image(item.src, 146, 96),
desc: item.intro,
url: helpers.urlFormat('/' + item.id + '.html', '', 'guang')
});
});
let total = articles.data.total || 0;
let pageTotal = articles.data.totalPage || 0;
let pageNum = articles.data.page || 0;
result.pager = getPager(pageNum, total, pageTotal);
} else {
result.articles = {empty: '你尚未收藏任何文章!'};
}
return result;
})();
};
const getPager = (page, total, totalPage, size, type)=> {
let result = {};
if (page && total && totalPage) {
result = {
count: total,
curPage: page,
totalPages: totalPage,
hasCheckAll: true
};
}
return result;
};
const getGoodsInfo = (data, page, limit)=> {
let result = [];
let begin = (page - 1) * limit;
if (!data) {
data = data.slice(begin, limit);
data.forEach((item, i)=> {
let obj = {
skn: item.product_id,
img: helpers.img(item.image, 100, 100),
name: item.product_name,
url: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
price: item.sales_price,
priceDown: item.price_down,
buyNow: helpers.getUrlBySkc(item.product_id, item.goodsId, item.cnAlphabet),
soldOut: item.storage === 0 ? true : '',
hadNoticed: item.is_subscribe_reduction === 'Y' ? true : '',
count: item.promotion_list ? item.promotion_list.length : 0
};
if (item.promotion_list) {
item.promotion_list.forEach(function(item1) {
obj.activites.list.push({
type: item1.promotion_type,
name: item1.promotion_title
});
});
}
result.push(obj);
});
} else {
result = {empty: '您没有收藏商品'};
}
return result;
};
const redutionCount = (uid)=> {
return co(function*() {
let result = {count: 0, url: '/home/favorite/reduction', phone: ''};
let data = yield favoriteApi.redutionCount(uid);
if (data.data.num) {
result.count = +data.data.num;
result.phone = data.data.mobile;
}
return result;
})();
};
const getSortInfo = (categoryList, sort)=> {
let result = {default: {}, all: []};
let defaultCategory = {name: '全部', url: helpers.urlFormat('/home/favorite'), count: 0, focus: ''};
categoryList.forEach(function(category) {
result.all.push({
name: category.category_name,
url: helpers.urlFormat('/home/favorite', {sort_id: category.category_id}),
count: category.num,
focus: category.category_id === sort ? true : ''
});
defaultCategory.count += category.num;
defaultCategory.focus = sort === 0 ? true : '';
});
result.all.unshift(defaultCategory);
result.default = result.all.slice(result.all, 0, 7);
return result;
};
module.exports = {
getFavoriteTabs,
favoriteProductList,
favoriteArticleListAsync
};
... ...
... ... @@ -11,21 +11,22 @@ const cRoot = './controllers';
const headerModel = require('../../doraemon/models/header');
const _ = require('lodash');
const helpers = global.yoho.helpers;
// const config = global.yoho.config;
const config = global.yoho.config;
const commentController = require(`${cRoot}/comment`);
const consultController = require(`${cRoot}/consult`);
const complaintsController = require(`${cRoot}/complaints`);
const messageController = require(`${cRoot}/message`);
const returnsController = require(`${cRoot}/returns`);
const IndexController = require(`${cRoot}/Index`);
const CurrencyController = require(`${cRoot}/Currency`);
// const consultController = require(`${cRoot}/consult`);
// const complaintsController = require(`${cRoot}/complaints`);
// const messageController = require(`${cRoot}/message`);
// const returnsController = require(`${cRoot}/returns`);
// const IndexController = require(`${cRoot}/Index`);
// const CurrencyController = require(`${cRoot}/Currency`);
const personalController = require(`${cRoot}/qrcode`);
const RedenvelopesController = require(`${cRoot}/Redenvelopes`);
const VipController = require(`${cRoot}/vip`);
const FavoriteController = require(`${cRoot}/Favorite`);
const CouponsController = require(`${cRoot}/coupons`);
// const RedenvelopesController = require(`${cRoot}/Redenvelopes`);
// const VipController = require(`${cRoot}/vip`);
// const FavoriteController = require(`${cRoot}/Favorite`);
// const CouponsController = require(`${cRoot}/coupons`);
const homeNav = [
{
... ... @@ -33,7 +34,7 @@ const homeNav = [
subNav: [
{name: '我的订单', href: '/home/orders', catchs: ['/home/orders', '/home/index']},
{name: '我的收藏', href: '/home/favorite'},
{name: '我的YOHO币', href: '/home/currency'},
{name: '我的有货币', href: '/home/currency'},
{name: '我的红包', href: '/home/redenvelopes'},
{name: '我的优惠券', href: '/home/coupons'},
{name: '我的VIP', href: '/home/vip'}
... ... @@ -101,36 +102,32 @@ const getHomeNav = (req, res, next) => {
const getCommonHeader = (req, res, next) => {
let channel = req.query.channel ? req.query.channel : 'boys';
headerModel.requestHeaderData(channel).then((result) => {
headerModel.requestHeaderData(channel).then((result)=>{
_.merge(res.locals, result);
next();
});
};
const sessionEffective = (req, res, next) => {
let refer = req.cookies.refer;
// const sessionEffective = (req, res, next) => {
// let refer = req.cookies.refer;
// if (req.user.uid) {
// next();
// return;
// }
// if (refer) {
// refer = decodeURI(req.cookies.refer);
// } else {
// refer = config.siteUrl;
// }
if (req.user.uid) {
next();
return;
}
// res.redirect(helpers.urlFormat('/signin.html', {
// refer: refer
// }));
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = config.siteUrl;
}
// // next();
// };
res.redirect(helpers.urlFormat('/signin.html', {
refer: refer
}));
};
// 查看二维码
router.get('/QRcode', [getCommonHeader, getHomeNav], personalController.QRcode);
router.get('/QRcode', sessionEffective, [getHomeNav, getCommonHeader], personalController.QRcode);
// 我的评论
... ... @@ -139,45 +136,45 @@ router.post('/comment/saveComment', commentController.saveComment);
router.get('/comment/order', [getCommonHeader, getHomeNav], commentController.commentList4Order);
// 我的咨询
router.get('/consult', [getCommonHeader, getHomeNav], consultController.index);
// router.get('/consult', [getCommonHeader, getHomeNav], consultController.index);
// 我的投诉
router.get('/complaints', [getCommonHeader, getHomeNav], complaintsController.index);
router.post('/complaints/submit', complaintsController.submit);
router.post('/complaints/cancel', complaintsController.cancel);
// router.get('/complaints', [getCommonHeader, getHomeNav], complaintsController.index);
// router.post('/complaints/submit', complaintsController.submit);
// router.post('/complaints/cancel', complaintsController.cancel);
// 我的消息
router.get('/message', messageController.index);
router.get('/message/detail', messageController.detail);
router.get('/message/del', messageController.delMsg);
router.get('/message/read', messageController.readMsg);
router.get('/message/pickCoupon', messageController.pickCoupon);
// router.get('/message', messageController.index);
// router.get('/message/detail', messageController.detail);
// router.get('/message/del', messageController.delMsg);
// router.get('/message/read', messageController.readMsg);
// router.get('/message/pickCoupon', messageController.pickCoupon);
// 我的退/换货
router.get('/returns', returnsController.index);
router.get('/refund/apply', returnsController.refundApply);
router.get('/refund/detail', returnsController.refundDetail);
router.get('/exchange/apply', returnsController.exchangeApply);
router.get('/exchange/detail', returnsController.refundDetail);
router.get('/returns/success', returnsController.index);
// router.get('/returns', returnsController.index);
// router.get('/refund/apply', returnsController.refundApply);
// router.get('/refund/detail', returnsController.refundDetail);
// router.get('/exchange/apply', returnsController.exchangeApply);
// router.get('/exchange/detail', returnsController.refundDetail);
// router.get('/returns/success', returnsController.index);
// // 地址管理
// router.get('address', addressController.index);
// router.get('address/area', addressController.area);
router.get('/index', [getCommonHeader, getHomeNav], IndexController.index);
// router.get('/index', [getCommonHeader, getHomeNav], IndexController.index);
router.get('/currency', CurrencyController.index);
// router.get('/currency', CurrencyController.index);
/* 我的红包*/
router.get('/redenvelopes', RedenvelopesController.index);
// router.get('/redenvelopes', RedenvelopesController.index);
/* 我的VIP*/
router.get('/vip', VipController.index);
router.get('/favorite', FavoriteController.index);
router.get('/coupons', CouponsController.index);
// router.get('/vip', VipController.index);
//
// router.get('/favorite', FavoriteController.index);
//
// router.get('/coupons', CouponsController.index);
module.exports = router;
... ...
... ... @@ -15,7 +15,7 @@ const DoubanStrategy = require('passport-douban').Strategy;
const RenrenStrategy = require('passport-renren').Strategy;
const AlipayStrategy = require('./models/passport-alipay').Strategy;
const AuthHelper = require('./models/auth-helper');
const LoginApi = require('./models/login-service');
const config = global.yoho.config;
const helpers = global.yoho.helpers;
... ... @@ -26,6 +26,16 @@ const cache = global.yoho.cache;
let siteUrl = config.siteUrl.indexOf('//') === 0 ? 'http:' + config.siteUrl : config.siteUrl;
function getLoginStat(account) {
let errorLoginKey = 'account_errorlogin_' + account;
let accountKey = 'account_signin_' + account;
let cacheGet = [cache.get(errorLoginKey), cache.get(accountKey)];
return Promise.all(cacheGet).catch(() => {
return [0, 0];
});
}
// 本地登录
passport.use('local', new LocalStrategy({
usernameField: 'account',
... ... @@ -54,25 +64,23 @@ passport.use('local', new LocalStrategy({
let errorLoginKey = 'account_errorlogin_' + account;
let accountKey = 'account_signin_' + account;
let cacheGet = [cache.get(errorLoginKey), cache.get(accountKey)];
Promise.all(cacheGet).then(times => {
getLoginStat(account).then(times => {
let errLoginTimes = _.parseInt(times[0]) || 0;
let accountTimes = _.parseInt(times[1]) || 0;
if (accountTimes >= 10) {
done({message: '您的账号已被暂时锁定,请稍后再试'}, null);
} else {
return AuthHelper.signin(type, area, username, password, shoppingKey).then((result) => {
return LoginApi.signin(type, area, username, password, shoppingKey).then((result) => {
if (result.code && result.code === 200 && result.data.uid) {
cache.del(errorLoginKey);
cache.del(errorLoginKey).catch(() => {});
done(null, result.data);
} else {
errLoginTimes = errLoginTimes + 1;
accountTimes = accountTimes + 1;
cache.set(errorLoginKey, errLoginTimes);
cache.set(accountKey, accountTimes, 1800);
cache.set(errorLoginKey, errLoginTimes).catch(() => {});
cache.set(accountKey, accountTimes, 1800).catch(() => {});
// 再次校验
if (accountTimes >= 10) {
... ... @@ -116,8 +124,8 @@ passport.use('wechat', new WeixinStrategy({
// sina 登录
passport.use('sina', new SinaStrategy({
clientID: '3739328910',
clientSecret: '9d44cded26d048e23089e5e975c93df1',
clientID: config.thirdLogin.sina.appID,
clientSecret: config.thirdLogin.sina.appSecret,
callbackURL: `${siteUrl}/passport/login/sina/callback`,
requireState: false
}, (accessToken, refreshToken, profile, done) => {
... ... @@ -126,8 +134,8 @@ passport.use('sina', new SinaStrategy({
// qq 登录
passport.use('qq', new QQStrategy({
clientID: '100229394',
clientSecret: 'c0af9c29e0900813028c2ccb42021792',
clientID: config.thirdLogin.qq.appID,
clientSecret: config.thirdLogin.qq.appSecret,
callbackURL: `${siteUrl}/passport/login/qq/callback`,
requireState: false
}, (accessToken, refreshToken, profile, done) => {
... ... @@ -136,8 +144,8 @@ passport.use('qq', new QQStrategy({
// alipay 登录
passport.use('alipay', new AlipayStrategy({
partner: '2088701661478015',
key: 'kcxawi9bb07mzh0aq2wcirsf9znusobw',
partner: config.thirdLogin.alipay.appID,
key: config.thirdLogin.alipay.appSecret,
return_url: `${siteUrl}/passport/login/alipay/callback`
}, (profile, done) => {
done(null, profile);
... ... @@ -145,8 +153,8 @@ passport.use('alipay', new AlipayStrategy({
// douban 登录
passport.use('douban', new DoubanStrategy({
clientID: '03b4e36bf13dc75a0b1eaa43d3b9560e',
clientSecret: 'f16d5913e8610672',
clientID: config.thirdLogin.douban.appID,
clientSecret: config.thirdLogin.douban.appSecret,
callbackURL: `${siteUrl}/passport/autosign/doubanback`
}, (accessToken, refreshToken, profile, done) => {
done(null, profile);
... ... @@ -154,8 +162,8 @@ passport.use('douban', new DoubanStrategy({
// renren 登录
passport.use('renren', new RenrenStrategy({
clientID: '783130c654c94a77ace97054ae266019',
clientSecret: '05e430de8c1e40d3a1f39ca8d3f8252c',
clientID: config.thirdLogin.renren.appID,
clientSecret: config.thirdLogin.renren.appSecret,
callbackURL: `${siteUrl}/passport/login/renren/callback`
}, (accessToken, refreshToken, profile, done) => {
done(null, profile);
... ...
... ... @@ -6,6 +6,7 @@
'use strict';
const helpers = global.yoho.helpers;
const config = global.yoho.config;
const service = require('../models/back-service');
const passportHelper = require('../models/passport-helper');
const simpleHeaderModel = require('../../../doraemon/models/simple-header');
... ... @@ -17,12 +18,15 @@ const _ = require('lodash');
const index = (req, res, next) => {
// 清除cookie
res.clearCookie('_UID', {
domain: 'yohobuy.com'
domain: config.cookieDomain
});
res.clearCookie('_TOKEN', {
domain: 'yohobuy.com'
domain: config.cookieDomain
});
// 清除 session
req.session = null;
service.indexPageDataAsync()
.then(result => {
res.render('back/index', Object.assign({
... ... @@ -102,21 +106,18 @@ const sendCodePage = (req, res, next) => {
const saveInSession = (req, res) => {
switch (req.inputInfo.type) {
case 'email': {
case 'email':
req.session.email = req.inputInfo.phone;
res.redirect(helpers.urlFormat('/passport/back/sendEmail'));
break;
}
case 'mobile': {
case 'mobile':
req.session.mobile = req.inputInfo.phone;
req.session.area = req.inputInfo.area;
req.session.verifyCode = req.session.captcha;
res.redirect(helpers.urlFormat('/passport/back/verification'));
break;
}
default: {
default:
res.redirect(helpers.urlFormat('/passport/back/index'));
}
}
};
... ... @@ -133,10 +134,9 @@ const sendBackMobileAPI = (req, res, next) => {
const validateMobileAPI = (req, res, next) => {
let mobile = req.body.mobile || '';
let area = req.body.area || '86';
const ERR = {code: 400, message: '验证失败'};
if (!passportHelper.validator.isAreaMobile(passportHelper.makeAreaMobile(area, mobile))) {
if (!passportHelper.validator.isMobile(mobile)) {
return res.json(ERR);
}
... ...
... ... @@ -8,9 +8,10 @@
const _ = require('lodash');
const helpers = global.yoho.helpers;
const PassportHelper = require('../models/passport-helper');
const BindService = require('../models/bind-service');
const AuthHelper = require('../models/auth-helper');
const passportHelper = require('../models/passport-helper');
const bindService = require('../models/bind-service');
const loginService = require('../models/login-service');
const userService = require('../models/user-service');
// const UserService = require('../models/user-service');
const simpleHeaderModel = require('../../../doraemon/models/simple-header');
... ... @@ -33,7 +34,7 @@ const bind = {
thirdLogin: true,
openId: openId,
sourceType: sourceType,
region: PassportHelper.getCountry(),
region: passportHelper.getCountry(),
serviceUrl: helpers.urlFormat('/help', {
category_id: 9
}),
... ... @@ -80,7 +81,7 @@ const bind = {
// }
// })
PassportHelper.getUserInfo(area, mobile).then(user => {
userService.getUserInfo(area, mobile).then(user => {
let data = _.assign(user, {
phoneNum: mobile,
areaCode: area,
... ... @@ -121,49 +122,59 @@ const bind = {
let sourceType = req.body.sourceType;
if (mobile && openId && area && sourceType) {
BindService.bindCheck(mobile, openId, sourceType, area).then(result => {
/**
* 接口绑定返回值:
* code:200,is_register=0 // 绑定流程:未注册,可绑定
* code:200,is_register=1 // 绑定流程:已注册绑定过其他第三方
* code:200:is_register=3 // 关联流程
* code:505 // 手机号码注册过,而且该第三方也已经绑定过手机号
* code:506 // 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
*/
bindService.bindCheck(mobile, openId, sourceType, area).then(result => {
if (!result || !result.code) {
return { code: 400, message: '', data: '' };
return {code: 400, message: '', data: ''};
} else if (result.code === 200 && result.data.is_register === 0) {
let nextUrl = helpers.urlFormat('/passport/thirdlogin/noregist');
// 绑定流程:code=200 未注册,可绑定
return { code: 200, message: result.message, data: { next: nextUrl } };
return {code: 200, message: result.message, data: {next: nextUrl}};
} else if (result.code === 200 && result.data.is_register === 1) {
return PassportHelper.getUserInfo(area, mobile).then(user => {
return userService.getUserInfo(area, mobile).then(user => {
// 绑定流程:code=201 已注册 绑定过其他第三方
return {code: 201, message: result.message, data: { user: user } };
return {code: 201, message: result.message, data: {user: user}};
});
} else if (result.code === 200 && result.data.is_register === 3) {
let nextUrl = helpers.urlFormat('/passport/thirdlogin/relate');
// 关联流程
return { code: 203, message: result.message, data: { next: nextUrl } };
return {code: 203, message: result.message, data: {next: nextUrl}};
} else if (result.code === 506 || result.code === 505) {
return PassportHelper.getUserInfo(area, mobile).then(user => {
return userService.getUserInfo(area, mobile).then(user => {
// 绑定流程:code=506 手机号码注册过,而且该手机号码也已经绑定过该类型第三方
// code=505 手机号码注册过,而且该第三方也已经绑定过手机号
return { code: 205, message: result.message, data: { user: user } };
return {code: 205, message: result.message, data: {user: user}};
});
} else {
return { code: result.code, message: result.message, data: result.data ? result.data : '' };
return {code: result.code, message: result.message, data: result.data ? result.data : ''};
}
}).then(result => {
res.json(result);
return res.json(result);
}).catch(next);
} else {
res.json({ code: 400, message: '', data: '' });
return res.json({code: 400, message: '', data: ''});
}
},
sendBindMsg: (req, res, next) => {
let mobile = req.body.mobile;
let area = req.body.area;
BindService.sendBindMsg(area, mobile).then(result => {
bindService.sendBindMsg(area, mobile).then(result => {
if (result && result.code) {
res.json(result);
return res.json(result);
} else {
res.json({ code: 400, message: '', data: '' });
return res.json({code: 400, message: '', data: ''});
}
}).catch(next);
},
... ... @@ -172,11 +183,11 @@ const bind = {
let area = req.body.area;
let code = req.body.code;
BindService.checkBindCode(area, mobile, code).then(result => {
bindService.checkBindCode(area, mobile, code).then(result => {
if (result && result.code) {
res.json(result);
return res.json(result);
} else {
res.json({ code: 400, message: '', data: '' });
return res.json({code: 400, message: '', data: ''});
}
}).catch(next);
},
... ... @@ -188,11 +199,11 @@ const bind = {
let code = _.trim(req.body.code);
let password = _.trim(req.body.password) || '';
BindService.checkBindCode(area, mobile, code).then(result => {
bindService.checkBindCode(area, mobile, code).then(result => {
if (result && result.code !== 200) {
return { code: 402, message: '短信验证码不正确', data: '' };
return {code: 402, message: '短信验证码不正确', data: ''};
} else {
return BindService.bindMobile(openId, sourceType, mobile, area, password);
return bindService.bindMobile(openId, sourceType, mobile, area, password);
}
}).then(result => {
if (result && result.code) {
... ... @@ -201,17 +212,17 @@ const bind = {
sourceType: sourceType + '_bind'
});
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
return { code: 200, message: result.message, data: {refer: refer }};
return loginService.syncUserSession(result.data.uid, req, res).then(() => {
return {code: 200, message: result.message, data: {refer: refer}};
});
} else {
return { code: result.code, message: result.message, data: { refer: ''} };
return {code: result.code, message: result.message, data: {refer: ''}};
}
} else {
return {code: 400, message: '', data: ''};
}
}).then(result => {
res.json(result);
return res.json(result);
}).catch(next);
},
relateMobile: (req, res, next) => {
... ... @@ -221,12 +232,12 @@ const bind = {
let sourceType = req.body.sourceType;
let code = req.body.code;
if (_.isNumber(parseInt(mobile, 0)) && openId && areaCode && sourceType && code) {
BindService.checkBindCode(areaCode, mobile, code).then(result => {
if (_.toNumber(mobile) && openId && areaCode && sourceType && code) {
bindService.checkBindCode(areaCode, mobile, code).then(result => {
if (result && result.code && result.code === 200) {
return BindService.relateMobile(openId, sourceType, mobile, areaCode);
return bindService.relateMobile(openId, sourceType, mobile, areaCode);
} else {
return { code: 402, message: '短信验证码错误', data: '' };
return {code: 402, message: '短信验证码错误', data: ''};
}
}).then(result => {
if (result && result.code) {
... ... @@ -235,20 +246,20 @@ const bind = {
sourceType: sourceType + '_relate'
});
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
return { code: 200, message: result.message, data: {refer: refer }};
return loginService.syncUserSession(result.data.uid, req, res).then(() => {
return {code: 200, message: result.message, data: {refer: refer}};
});
} else {
return { code: result.code, message: result.message, data: { refer: ''} };
return {code: result.code, message: result.message, data: {refer: ''}};
}
} else {
return {code: 400, message: '', data: ''};
}
}).then(result => {
res.json(result);
return res.json(result);
}).catch(next);
} else {
res.json({ code: 400, message: '', data: '' });
return res.json({code: 400, message: '', data: ''});
}
}
};
... ...
... ... @@ -6,7 +6,7 @@
'use strict';
const _ = require('lodash');
const Fp = require('lodash/fp');
const Fn = require('lodash/fp');
const Promise = require('bluebird');
const qs = require('querystring');
... ... @@ -17,7 +17,7 @@ const helpers = global.yoho.helpers;
const log = global.yoho.logger;
const config = global.yoho.config;
const cache = global.yoho.cache;
const AuthHelper = require('../models/auth-helper');
const loginService = require('../models/login-service');
const PassportHelper = require('../models/passport-helper');
const simpleHeaderModel = require('../../../doraemon/models/simple-header');
const loginPage = `${config.siteUrl}/signin.html`;
... ... @@ -40,8 +40,9 @@ function doPassportCallback(req, res, user) {
user.openId = user.unionId;
}
return AuthHelper.signinByOpenID(user.nickname, user.openId, user.sourceType, shoppingKey)
return loginService.signinByOpenID(user.nickname, user.openId, user.sourceType, shoppingKey)
.then((result) => {
console.log(result);
if (result.code !== 200) {
return res.redirect(config.siteUrl);
}
... ... @@ -51,8 +52,8 @@ function doPassportCallback(req, res, user) {
sourceType: user.sourceType,
refer: refer
});
} else if (result.code === 200 && result.data.uid) {
return AuthHelper.syncUserSession(result.data.uid, req, res).then(() => {
} else if (result.data['is_bind'] === 'Y' && result.data.uid) {//eslint-disable-line
return loginService.syncUserSession(result.data.uid, req, res, result.data.session_key).then(() => {
return refer;
});
}
... ... @@ -70,7 +71,7 @@ const common = {
let refer = req.query.refer || req.get('Referer');
refer && res.cookie('refer', encodeURI(refer), {
domain: '.yohobuy.com'
domain: config.cookieDomain
});
next();
},
... ... @@ -86,10 +87,10 @@ const common = {
if (!isNaN(errloginTimes) && errloginTimes >= 3) {
result.data = {needCaptcha: true};
}
res.json(result);
return res.json(result);
}).catch(next);
} else {
res.json(result);
return res.json(result);
}
}
};
... ... @@ -98,12 +99,14 @@ const local = {
loginPage: (req, res) => {
// 清除cookie
res.clearCookie('_UID', {
domain: 'yohobuy.com'
domain: config.cookieDomain
});
res.clearCookie('_TOKEN', {
domain: 'yohobuy.com'
domain: config.cookieDomain
});
req.session = null;
let bindMobile = _.trim(req.query.bindMobile || '');
let bindArea = '+' + _.trim(req.query.bindArea || '86');
let areaArr = PassportHelper.getCountry();
... ... @@ -148,52 +151,52 @@ const local = {
login: (req, res, next) => {
passport.authenticate('local', (err, user) => {
if (err) {
res.json({
return res.json({
code: 400,
message: err.message,
data: {
needCaptcha: err.needCaptcha
}
});
} else {
if (_.get(req, 'body.isRemember', false)) {
AuthHelper.rememberAccount({
area: req.body.areaCode || '86',
account: req.body.account,
password: req.body.password
}, req, res);
}
if (_.get(req.body, 'isRemember', 'false') === 'true') {
loginService.rememberAccount({
area: req.body.areaCode || '86',
account: req.body.account,
password: req.body.password
}, req, res);
}
let refer = (function() {
if (/sign|login|reg|passport/.test(_.get(req.cookies, 'refer', ''))) {
return `${config.siteUrl}/home`;
} else if (_.get(req.cookies, 'refer')) {
return decodeURI(req.cookies.refer);
} else {
return `${config.siteUrl}/home`;
}
}());
let refer = (function() {
if (/sign|login|reg|passport/.test(_.get(req, 'cookies.refer', ''))) {
return `${config.siteUrl}/home`;
} else if (_.get(req, 'cookies.refer')) {
return decodeURI(req.cookies.refer);
} else {
return `${config.siteUrl}/home`;
loginService.syncUserSession(user.uid, req, res, user.session_key).then(() => {
return res.json({
code: 200,
data: {
session: refer,
href: refer
}
}());
AuthHelper.syncUserSession(user.uid, req, res).then(() => {
res.json({
code: 200,
data: {
session: refer,
href: refer
}
});
});
}
});
})(req, res, next);
},
logout: (req, res) => {
req.session = null;
res.clearCookie('_UID', {
domain: 'yohobuy.com'
domain: config.cookieDomain
});
res.clearCookie('_TOKEN', {
domain: 'yohobuy.com'
res.clearCookie('TOKEN_', {
domain: config.cookieDomain
});
res.clearCookie('_SPK');
res.clearCookie('_g');
... ... @@ -201,7 +204,7 @@ const local = {
res.clearCookie('remem');
let refer = req.get('Referer') || config.siteUrl;
res.redirect(refer);
return res.redirect(refer);
},
sms: {
send: (req, res, next) => {
... ... @@ -215,7 +218,7 @@ const local = {
});
}
AuthHelper.sendPasswordBySMS(area, mobile).then((result) => {
loginService.sendPasswordBySMS(area, mobile).then((result) => {
return res.json(result);
}).catch(next);
},
... ... @@ -231,7 +234,7 @@ const local = {
});
}
AuthHelper.verifyPasswordBySMS(area, mobile, code).then((result) => {
loginService.verifyPasswordBySMS(area, mobile, code).then((result) => {
if (_.get(result, 'code', 200) !== 200) {
return Promise.reject('error');
}
... ... @@ -261,18 +264,18 @@ const local = {
});
}
AuthHelper.checkUserExitBySMS(area, mobile).then((result) => {
loginService.checkUserExitBySMS(area, mobile).then((result) => {
if (_.get(result, 'code') !== 200) {
return Promise.reject('check user by sms error');
}
if (_.get(result, 'data.is_register', 'N') === 'Y') {
res.json({
return res.json({
code: 200,
message: '用户已注册'
});
} else {
res.json({
return res.json({
code: 402,
message: '手机号尚未注册,请核对后重新输入或<a href="/reg.html?' +
qs.stringify({mobile: mobile, area: (area ? '+' + area : '+86') || '+86'}) +
... ... @@ -284,7 +287,7 @@ const local = {
},
qrcode: {
refresh: (req, res, next) => {
AuthHelper.fetchByQrCode().then((result) => {
loginService.fetchByQrCode().then((result) => {
if (result.code === 200) {
return res.json({
code: 200,
... ... @@ -319,7 +322,7 @@ const local = {
let token = qrcode.substring(qrcode.indexOf('=') + 1);
AuthHelper.checkByQrCode(token).then((result) => {
loginService.checkByQrCode(token).then((result) => {
if (_.isEmpty(result)) {
return res.json({
code: 400,
... ... @@ -366,7 +369,6 @@ const local = {
const wechat = {
login: (req, res, next) => {
req.session = req.session || {};
req.session.authState = uuid.v4();
return passport.authenticate('wechat', {
state: req.session.authState
... ... @@ -389,14 +391,13 @@ const wechat = {
}
})(req, res, next);
} else {
return next(new Error('Auth State Mismatch'));
return next(new Error('Wechat Auth State Mismatch'));
}
}
};
const sina = {
login: (req, res, next) => {
req.session = req.session || {};
req.session.authState = uuid.v4();
return passport.authenticate('sina', {
state: req.session.authState
... ... @@ -419,15 +420,13 @@ const sina = {
}).catch(next);
})(req, res, next);
} else {
return next(new Error('Auth State Mismatch'));
return next(new Error('Sina Auth State Mismatch'));
}
}
};
const qq = {
login: (req, res, next) => {
req.session = req.session || {};
let type = req.query.type || 'yohobuy';
let authState = req.session.authState = (req.query.state || uuid.v4()) + '::' + type;
... ... @@ -436,8 +435,8 @@ const qq = {
})(req, res, next);
},
callback: (req, res, next) => {
let auth = Fp.compose(Fp.head, Fp.split('::'))(req.query.state);
let type = Fp.compose(Fp.nth(1), Fp.split('::'))(req.query.state);
let auth = Fn.compose(Fn.head, Fn.split('::'))(req.query.state);
let type = Fn.compose(Fn.nth(1), Fn.split('::'))(req.query.state);
if (req.session && req.session.authState && req.session.authState === req.query.state) {
passport.authenticate('qq', (err, user) => {
... ... @@ -460,7 +459,7 @@ const qq = {
}
})(req, res, next);
} else {
return next(new Error('Auth State Mismatch'));
return next(new Error('QQ Auth State Mismatch'));
}
}
};
... ... @@ -489,7 +488,6 @@ const alipay = {
const douban = {
login: (req, res, next) => {
req.session = req.session || {};
req.session.authState = uuid.v4();
return passport.authenticate('douban', {
state: req.session.authState
... ... @@ -516,7 +514,6 @@ const douban = {
const renren = {
login: (req, res, next) => {
req.session = req.session || {};
req.session.authState = uuid.v4();
return passport.authenticate('renren', {
state: req.session.authState
... ...
... ... @@ -7,7 +7,7 @@ const Promise = require('bluebird');
const passportHelper = require('../models/passport-helper');
const regService = require('../models/reg-service');
const userService = require('../models/user-service');
const authHelper = require('../models/auth-helper');
const loginService = require('../models/login-service');
const config = require('../../../config/common');
const simpleHeaderModel = require('../../../doraemon/models/simple-header');
let helpers = global.yoho.helpers;
... ... @@ -33,10 +33,10 @@ let checkCode = (req, res, next) => {
* 检查手机格式
*/
let checkMobileMiddleware = (req, res, next) => {
let mobile = +req.body.mobile;
let area = +req.body.area;
let mobile = req.body.mobile;
let area = req.body.area;
if (!_.isNumber(mobile) || !_.isNumber(area)) {
if (!(_.toNumber(mobile) && _.toNumber(area))) {
return res.json({
code: 400,
message: '手机号码格式不正确'
... ... @@ -66,7 +66,7 @@ let checkPassword = (req, res, next) => {
*/
let index = (req, res, next) => {
// 设置注册有效时间30分钟, 防机器刷
req.session._REG_EXPIRE = Date.now() + 1800000;
req.session.REG_EXPIRE_ = Date.now() + 1800000;
let refer = req.query.refer;
let mobile = req.query.mobile;
... ... @@ -106,11 +106,11 @@ let checkMobile = (req, res, next) => {
let data = {
code: 400
};
let mobile = +req.body.mobile;
let area = +req.body.area;
let mobile = req.body.mobile;
let area = req.body.area || '86';
// 判断手机号是否检查超过指定次数
let regCheckKey = 'regCheckMobileNum_' + passportHelper.makeAreaMobile(area, mobile);
let regCheckKey = `regCheckMobileNum_${area}-${mobile}`;
cache.get(regCheckKey).then((checkNum) => {
checkNum = +(checkNum || 0);
... ... @@ -168,8 +168,8 @@ let sendBindMsg = (req, res, next) => {
data: ''
};
let mobile = +req.body.mobile;
let area = +req.body.area;
let mobile = req.body.mobile;
let area = req.body.area;
// 校验是否发送过多
let sendCodeKey = `send_code_${area}_${mobile}`;
... ... @@ -204,9 +204,9 @@ let msgCaptcha = (req, res, next) => {
message: '',
data: ''
};
let area = +req.body.area;
let mobile = +req.body.mobile;
let code = +req.body.code; // 短信验证码
let area = req.body.area;
let mobile = req.body.mobile;
let code = req.body.code; // 短信验证码
regService.validMobileCode(area, mobile, code).then((result) => {
if (result.code) {
... ... @@ -230,7 +230,7 @@ let mobileRegister = (req, res, next) => {
};
/* 判断是否是有效的注册方式,防注册机刷 */
let regExpireTime = req.session._REG_EXPIRE;
let regExpireTime = req.session.REG_EXPIRE_;
if (!regExpireTime || regExpireTime < Date.now()) {
data.message = '注册超时';
... ... @@ -254,9 +254,9 @@ let mobileRegister = (req, res, next) => {
yield cache.set(ipKey, ipTimes + 1, 3600);
let area = +req.body.area;
let mobile = +req.body.mobile;
let code = +req.body.code; // 短信验证码
let area = req.body.area;
let mobile = req.body.mobile;
let code = req.body.code; // 短信验证码
let password = req.body.password;
let result = yield regService.validMobileCode(area, mobile, code); // 验证注册的标识码是否有效
... ... @@ -273,7 +273,7 @@ let mobileRegister = (req, res, next) => {
return res.json(data);
}
return authHelper.syncUserSession(regResult.data.uid, req, res).then(() => {
return loginService.syncUserSession(regResult.data.uid, req, res).then(() => {
return res.json({
code: 200,
message: '注册成功',
... ...
... ... @@ -5,8 +5,7 @@
*/
'use strict';
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var passport = require('passport');
... ... @@ -20,12 +19,12 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -24,13 +24,13 @@ const validateEmailOrMobileAsync = (userInput, areaCode) => {
return new Promise(function(resolve, rejected) {
let result = {type: 'email', area: '', phone: ''};
if (passportHelper.validator.verifyEmail(userInput)) {
if (passportHelper.validator.isEmail(userInput)) {
result.type = 'email';
result.area = '';
result.phone = userInput;
resolve(result);
} else if (passportHelper.validator.isAreaMobile(passportHelper.makeAreaMobile(areaCode, userInput))) {
} else if (passportHelper.validator.isMobile(userInput)) {
result.type = 'mobile';
result.area = areaCode;
result.phone = userInput;
... ... @@ -57,7 +57,7 @@ const findUserAsync = (type, phone, area) => {
const findBy = {
email: userService.findByEmailAsync,
mobile: (phone1, area1) => userService.findByMobileAsync(area1, phone1) // 交换参数
mobile: _.rearg(userService.findByMobileAsync, [1, 0]) // 交换参数
};
const OK = {code: 200, message: MESSAGE.ok};
... ...
/**
* 注册数据接口
*
* @author JiangFeng<jeff.jiang@yoho.cn>
* @date 2016/06/21
*/
'use strict';
const api = global.yoho.API;
const bindCheck = (mobile, openId, sourceType, area) => {
let params = {
method: 'app.passport.signCheck',
area: area,
mobile: mobile,
open_id: openId,
source_type: sourceType
};
return api.get('', params);
};
const sendBindMsg = (area, mobile) => {
let params = {
method: 'app.passport.smsbind',
mobile: mobile,
area: area
};
return api.get('', params);
};
const checkBindCode = (area, mobile, code) => {
return api.get('', {
method: 'app.register.validRegCode',
mobile: mobile,
area: area,
code: code
});
};
const bindMobile = (openId, sourceType, mobile, area, password, nickname) => {
let params = {
method: 'app.passport.bind',
mobile: mobile,
open_id: openId,
source_type: sourceType,
area: area
};
if (password) {
params.password = password;
}
if (nickname) {
params.nickname = nickname;
}
return api.get('', params);
};
const relateMobile = (openId, sourceType, mobile, area) => {
return api.get('', {
method: 'app.passport.relatedMobile',
mobile: mobile,
openId: openId,
source_type: sourceType,
area: area
});
};
const changeCheck = (mobile, area) => {
return api.get('', {
method: 'app.passport.changeCheck',
mobile: mobile,
area: area
});
};
const changeMobile = (uid, mobile, area, code) => {
return api.get('', {
method: 'app.passport.changeMobile',
mobile: mobile,
uid: uid,
code: code,
area: area
});
};
module.exports = {
bindCheck,
sendBindMsg,
checkBindCode,
bindMobile,
relateMobile,
changeCheck,
changeMobile
};
... ...
... ... @@ -7,81 +7,6 @@
'use strict';
const api = global.yoho.API;
const api = require('./bind-api');
const BindService = {
bindCheck(mobile, openId, sourceType, area) {
let params = {
method: 'app.passport.signCheck',
area: area,
mobile: mobile,
open_id: openId,
source_type: sourceType
};
return api.get('', params);
},
sendBindMsg(area, mobile) {
let params = {
method: 'app.passport.smsbind',
mobile: mobile,
area: area
};
return api.get('', params);
},
checkBindCode(area, mobile, code) {
return api.get('', {
method: 'app.register.validRegCode',
mobile: mobile,
area: area,
code: code
});
},
bindMobile(openId, sourceType, mobile, area, password, nickname) {
let params = {
method: 'app.passport.bind',
mobile: mobile,
open_id: openId,
source_type: sourceType,
area: area
};
if (password) {
params.password = password;
}
if (nickname) {
params.nickname = nickname;
}
return api.get('', params);
},
relateMobile(openId, sourceType, mobile, area) {
return api.get('', {
method: 'app.passport.relatedMobile',
mobile: mobile,
openId: openId,
source_type: sourceType,
area: area
});
},
changeCheck(mobile, area) {
return api.get('', {
method: 'app.passport.changeCheck',
mobile: mobile,
area: area
});
},
changeMobile(uid, mobile, area, code) {
return api.get('', {
method: 'app.passport.changeMobile',
mobile: mobile,
uid: uid,
code: code,
area: area
});
}
};
module.exports = BindService;
module.exports = api;
... ...
... ... @@ -6,13 +6,15 @@
const serviceAPI = global.yoho.ServiceAPI;
const config = global.yoho.config;
/**
* 资源码找资源
*/
const getResourceAsync = resourceCode => {
return serviceAPI.get('/operations/api/v5/resource/get', {
content_code: resourceCode
});
}, config.apiCache);
};
module.exports = {
... ...
'use strict';
/**
* Created by TaoHuang on 2016/10/21.
*/
const md5 = require('md5');
'use strict';
const aes = require('./aes-pwd');
const cache = global.yoho.cache;
const sign = global.yoho.sign;
const api = global.yoho.API;
const cookie = global.yoho.cookie;
const Promise = require('bluebird');
const cartService = require('./cart-service');
const Auth = {
signin(type, area, profile, password, shoppingKey) {
let _that = this;
let loginBy = {
password: _that.signinByPasswordWithAes,
sms: _that.signinBySMS,
qrcode: _that.signinByQrCode
};
return loginBy[type](area, profile, password, shoppingKey);
},
signinByPasswordWithAes(area, profile, password, shoppingKey) {
let param = {
method: 'app.passport.signinAES',
area: area,
profile: profile,
password: aes.aesPwd(password)
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
},
signinBySMS(area, mobile, token, shoppingKey) {
let param = {
method: 'app.passport.autoSignin',
area: area,
profile: mobile,
code: token
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
},
signinByQrCode(__1, __2, code, shoppingKey) { // eslint-disable-line
let param = {
method: 'app.twoDimen.qrCodeLogin',
code: code.substring(code.indexOf('=') + 1)
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
},
fetchByQrCode() {
let param = {
method: 'app.twoDimen.getCode'
};
return api.post('', param);
},
checkByQrCode(code) {
let param = {
method: 'app.twoDimen.loginCheck',
code: code
};
return api.post('', param);
},
sendPasswordBySMS(area, mobile) {
let param = {
method: 'app.message.sendSms',
area: area,
mobile: mobile,
type: 1 // 手机快捷登录短信验证码
};
return api.get('', param);
},
checkUserExitBySMS(area, mobile) {
return api.get('', {
method: 'app.passport.checkUserExist',
area: area,
mobile: mobile
});
},
verifyPasswordBySMS(area, mobile, code) {
return api.get('', {
method: 'app.message.verifySmsCode',
area: area,
mobile: mobile,
code: code,
type: 1 // 手机快捷登录短信验证码
});
},
signinByOpenID(nickname, openId, sourceType, shoppingKey) {
let param = {
nickname: nickname,
openId: openId,
source_type: sourceType,
method: 'app.passport.signinByOpenID'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
},
signinByWechat(nickname, openId, unionId, sourceType, shoppingKey) {
let param = {
nickname: nickname,
openId: openId,
unionId: unionId,
source_type: sourceType,
method: 'app.passport.signinByWechat'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
},
profile(uid) {
let param = {
uid: uid,
method: 'app.passport.profile'
};
return api.get('', param);
},
syncUserSession(uid, req, res) {
return Promise.all([Auth.profile(uid), cartService.goodsCount(uid)]).spread((userInfo, count) => {
let token = sign.makeToken(uid);
let data = userInfo.data;
let encryptionUid = aes.encryptionUid(data.uid);
if (data) {
let uidCookie = `${data.profile_name}::${encryptionUid}::${data.vip_info.title}::${token}`;
let isStudent = data.vip_info.is_student || 0;
req.session._TOKEN = token;
req.session._LOGIN_UID = uid;
res.cookie('_UID', uidCookie, {
domain: 'yohobuy.com'
});
res.cookie('isStudent', isStudent, {
domain: 'yohobuy.com'
});
// 购物车中商品的数量
res.cookie('_g', JSON.stringify({
_k: cookie.getShoppingKey(req),
_nac: count,
_ac: 0,
_c: 1
}), {
domain: 'yohobuy.com'
});
}
req.session._TOKEN = token; // esline-disable-line
req.session._LOGIN_UID = uid; // esline-disable-line
res.cookie('_TOKEN', token, {
domain: 'yohobuy.com'
}); // esline-disable-line
}).catch(console.log);
},
rememberAccount(accountInfo, req, res) {
let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
res.cookie('isRemember', true, aWeek);
res.cookie('remem', rememKey, aWeek);
if (!cache.get(rememKey)) {
cache.set(rememKey, accountInfo, aWeek);
}
const signinByPasswordWithAes = (area, profile, password, shoppingKey) => {
let param = {
method: 'app.passport.signinAES',
area: area,
profile: profile,
password: aes.aesPwd(password)
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
};
const signinBySMS = (area, mobile, token, shoppingKey) => {
let param = {
method: 'app.passport.autoSignin',
area: area,
profile: mobile,
code: token
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
};
const signinByQrCode = (__1, __2, code, shoppingKey) => { // eslint-disable-line
let param = {
method: 'app.twoDimen.qrCodeLogin',
code: code.substring(code.indexOf('=') + 1)
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.post('', param);
};
const fetchByQrCode = () => {
let param = {
method: 'app.twoDimen.getCode'
};
return api.post('', param);
};
const checkByQrCode = (code) => {
let param = {
method: 'app.twoDimen.loginCheck',
code: code
};
return api.post('', param);
};
const sendPasswordBySMS = (area, mobile) => {
let param = {
method: 'app.message.sendSms',
area: area,
mobile: mobile,
type: 1 // 手机快捷登录短信验证码
};
return api.get('', param);
};
const checkUserExitBySMS = (area, mobile) => {
return api.get('', {
method: 'app.passport.checkUserExist',
area: area,
mobile: mobile
});
};
const verifyPasswordBySMS = (area, mobile, code) => {
return api.get('', {
method: 'app.message.verifySmsCode',
area: area,
mobile: mobile,
code: code,
type: 1 // 手机快捷登录短信验证码
});
};
const signinByOpenID = (nickname, openId, sourceType, shoppingKey) => {
let param = {
nickname: nickname,
openId: openId,
source_type: sourceType,
method: 'app.passport.signinByOpenID'
};
if (shoppingKey) {
param.shopping_key = shoppingKey;
}
return api.get('', param);
};
module.exports = Auth;
module.exports = {
signinByPasswordWithAes,
signinBySMS,
signinByQrCode,
fetchByQrCode,
checkByQrCode,
sendPasswordBySMS,
checkUserExitBySMS,
verifyPasswordBySMS,
signinByOpenID
};
... ...
'use strict';
const md5 = require('md5');
const aes = require('./aes-pwd');
const cache = global.yoho.cache;
const sign = global.yoho.sign;
const cookie = global.yoho.cookie;
const config = global.yoho.config;
const Promise = require('bluebird');
const cartService = require('./cart-service');
const userService = require('./user-service');
const api = require('./login-api');
const signin = (type, area, profile, password, shoppingKey) => {
let loginBy = {
password: api.signinByPasswordWithAes,
sms: api.signinBySMS,
qrcode: api.signinByQrCode
};
return loginBy[type](area, profile, password, shoppingKey);
};
const syncUserSession = (uid, req, res, sessionKey) => {
if (sessionKey) {
cache.set(`java_session_key:${uid}`, sessionKey).catch(() => {
global.yoho.logger.error('write session key fail');
});
}
return Promise.all([userService.profile(uid), cartService.goodsCount(uid)]).spread((userInfo, count) => {
let token = sign.makeToken(uid);
let data = userInfo.data;
let encryptionUid = aes.encryptionUid(data.uid);
if (data) {
let uidCookie = `${data.profile_name}::${encryptionUid}::${data.vip_info.title}::${token}`;
let isStudent = data.vip_info.is_student || 0;
res.cookie('_UID', uidCookie, {
domain: config.cookieDomain
});
res.cookie('isStudent', isStudent, {
domain: config.cookieDomain
});
// 购物车中商品的数量
res.cookie('_g', JSON.stringify({
_k: cookie.getShoppingKey(req),
_nac: count,
_ac: 0,
_c: 1
}), {
domain: config.cookieDomain
});
}
req.session.TOKEN_ = token;
req.session.LOGIN_UID_ = uid;
res.cookie('_TOKEN', token, {
domain: config.cookieDomain
});
}).catch(console.log);
};
const rememberAccount = (accountInfo, req, res) => {
let aWeek = (new Date()).getTime() / 1000 + 504000; // 504000-一周
let rememKey = md5(md5(accountInfo.account + accountInfo.password + accountInfo.area));
res.cookie('isRemember', true, {
maxAge: aWeek,
domain: config.cookieDomain
});
res.cookie('remem', rememKey, {
maxAge: aWeek,
domain: config.cookieDomain
});
// if (!cache.get(rememKey)) {
// cache.set(rememKey, accountInfo, aWeek);
// }
};
module.exports = {
signin,
syncUserSession,
rememberAccount,
fetchByQrCode: api.fetchByQrCode,
checkByQrCode: api.checkByQrCode,
sendPasswordBySMS: api.sendPasswordBySMS,
checkUserExitBySMS: api.checkUserExitBySMS,
verifyPasswordBySMS: api.verifyPasswordBySMS,
signinByOpenID: api.signinByOpenID
};
... ...
... ... @@ -9,9 +9,6 @@ const _ = require('lodash');
const helpers = global.yoho.helpers;
const indexService = require('./index-service');
const UserService = require('./user-service');
const DEFAULT_HEAD_IMG_ICO = 'http://img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
/**
* 获得图片
... ... @@ -109,125 +106,14 @@ const getCountry = () => {
};
/**
* 各国手机号规则
*/
const _areaMobileVerify = (phone, area) => {
area = area || '86';
phone = phone.trim();
let verify = {
86: {
name: '中国',
match: /^1[3|4|5|8|7][0-9]{9}$/.test(phone)
},
852: {
name: '中国香港',
match: /^[9|6|5][0-9]{7}$/.test(phone)
},
853: {
name: '中国澳门',
match: /^[0-9]{8}$/.test(phone)
},
886: {
name: '中国台湾',
match: /^[0-9]{10}$/.test(phone)
},
65: {
name: '新加坡',
match: /^[9|8][0-9]{7}$/.test(phone)
},
60: {
name: '马来西亚',
match: /^1[1|2|3|4|6|7|9][0-9]{8}$/.test(phone)
},
1: {
name: '加拿大&美国',
match: /^[0-9]{10}$/.test(phone)
},
82: {
name: '韩国',
match: /^01[0-9]{9}$/.test(phone)
},
44: {
name: '英国',
match: /^7[7|8|9][0-9]{8}$/.test(phone)
},
81: {
name: '日本',
match: /^0[9|8|7][0-9]{9}$/.test(phone)
},
61: {
name: '澳大利亚',
match: /^[0-9]{11}$/.test(phone)
}
};
if (verify[area]) {
return verify[area].match;
} else {
return false;
}
};
/**
* 验证国际手机号是否合法
*/
const isAreaMobile = areaMobile => {
if (!areaMobile) {
return false;
}
let mobile = {
area: '86',
phone: ''
};
let splitMobile = areaMobile.split('-');
if (splitMobile.length === 2) {
mobile.area = splitMobile[0];
mobile.phone = splitMobile[1];
} else {
mobile.phone = splitMobile[0];
}
return _areaMobileVerify(mobile.phone, mobile.area);
};
const isMobile = _.toNumber;
/**
* 验证邮箱是否合法
*/
const verifyEmail = email => {
if (!email) {
return false;
}
const emailRegExp = /^[\.a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;
return emailRegExp.test(email);
};
/**
* 验证手机是否合法
*/
const verifyMobile = phone => {
if (!phone) {
return false;
}
return /^1[3|4|5|8|7][0-9]{9}$/.test(phone);
};
/**
* 生成带区号的手机号码
*/
const makeAreaMobile = (area, mobile) => {
if (!area || area === '86') {
return mobile;
}
return `${area}-${mobile}`;
};
const isEmail = email => _.includes(email, '@');
/**
* 密码是否合法
... ... @@ -242,35 +128,13 @@ const isPassword = pwd => {
return pwdRegexp.test(_.trim(pwd));
};
/**
* 第三方登录 根据手机号获取用户相关信息
*/
const getUserInfo = (area, mobile) => {
return UserService.findByMobileAsync(area, mobile).then(user => {
let profile = (user.profile_name || mobile).toString();
if ((profile.length === 11 && profile.indexOf('*') < 0) || (profile.indexOf('-') >= 0 &&
profile.indexOf('*') < 0)) {
profile = profile.substring(0, 3) + '****' + profile.substring(7, 11);
}
return {
username: profile,
headImg: user.head_ico ? helpers.image(user.head_ico, 100, 100, 2) : DEFAULT_HEAD_IMG_ICO,
bindLogin: helpers.urlFormat('/signin.html', { bindMobile: mobile, bindArea: area })
};
});
};
module.exports = {
validator: {
verifyMobile,
isAreaMobile,
verifyEmail,
isMobile,
isEmail,
isPassword
},
makeAreaMobile,
getCountry,
getLeftBannerAsync,
getUserInfo
getLeftBannerAsync
};
... ...
/**
* Created by TaoHuang on 2016/10/21.
*/
/**
* 注册 model
*/
'use strict';
const aes = require('./aes-pwd');
const api = global.yoho.API;
let sendCodeToMobile = (area, mobile) => {
let params = {
method: 'app.register.sendRegCodeToMobile',
area: area,
mobile: mobile
};
return api.post('', params);
};
let validMobileCode = (area, mobile, code) => {
let params = {
method: 'app.register.validRegCode',
area: area,
mobile: mobile,
code: code
};
return api.post('', params);
};
let regMobile = (area, mobile, password, shoppingKey)=> {
let params = {
method: 'app.passport.register',
area: area,
profile: mobile,
password: password
};
if (shoppingKey) {
params.shopping_key = shoppingKey;
}
return api.post('', params);
};
let regMobileAes = (area, mobile, password, shoppingKey)=> {
let params = {
method: 'app.passport.registerAES',
area: area,
profile: mobile,
password: aes.aesPwd(password)
};
if (shoppingKey) {
params.shopping_key = shoppingKey;
}
return api.post('', params);
};
module.exports = {
sendCodeToMobile,
validMobileCode,
regMobile,
regMobileAes
};
... ...
... ... @@ -3,69 +3,14 @@
*/
'use strict';
const passportHelper = require('./passport-helper');
const aes = require('./aes-pwd');
const api = require('./reg-api');
const REGISTER_LEFT_BANNER_CODE = 'c479ec90120cae7f96e52922b4917064'; // 注册左边的banner
const api = global.yoho.API;
let getRegData = () => {
return passportHelper.getLeftBannerAsync(REGISTER_LEFT_BANNER_CODE);
};
let sendCodeToMobile = (area, mobile) => {
let params = {
method: 'app.register.sendRegCodeToMobile',
area: area,
mobile: mobile
};
return api.post('', params);
};
let validMobileCode = (area, mobile, code) => {
let params = {
method: 'app.register.validRegCode',
area: area,
mobile: mobile,
code: code
};
return api.post('', params);
};
let regMobile = (area, mobile, password, shoppingKey)=> {
let params = {
method: 'app.passport.register',
area: area,
profile: mobile,
password: password
};
if (shoppingKey) {
params.shopping_key = shoppingKey;
}
return api.post('', params);
};
let regMobileAes = (area, mobile, password, shoppingKey)=> {
let params = {
method: 'app.passport.registerAES',
area: area,
profile: mobile,
password: aes.aesPwd(password)
};
if (shoppingKey) {
params.shopping_key = shoppingKey;
}
return api.post('', params);
};
module.exports = {
getRegData,
sendCodeToMobile,
validMobileCode,
regMobile,
regMobileAes
};
module.exports = Object.assign(api, {
getRegData
});
... ...
... ... @@ -34,21 +34,30 @@ const findByEmailAsync = (email) => {
return api.get('', {
email: email,
method: 'app.passport.getProfileByEmail'
})
.then(result => {
if (!result.code || result.code !== 200 || !result.data || _.isEmpty(result.data)) {
return EMPTY;
}
}).then(result => {
if (!result.code || result.code !== 200 || !result.data || _.isEmpty(result.data)) {
return EMPTY;
}
return result.data;
return result.data;
})
.catch(() => {
return EMPTY;
});
}).catch(() => {
return EMPTY;
});
};
const profile = (uid) => {
let param = {
uid: uid,
method: 'app.passport.profile'
};
return api.get('', param);
};
module.exports = {
findByMobileAsync,
findByEmailAsync
findByEmailAsync,
profile
};
... ...
... ... @@ -5,4 +5,30 @@
const api = require('./user-api');
module.exports = api;
const helpers = global.yoho.helpers;
const DEFAULT_HEAD_IMG_ICO = 'http://img10.static.yhbimg.com/headimg/2013/11/28/09/01cae078abe5fe320c88cdf4c220212688.gif?imageView/2/w/100/h/100';
/**
* 第三方登录 根据手机号获取用户相关信息
*/
const getUserInfo = (area, mobile) => {
return api.findByMobileAsync(area, mobile).then(user => {
let profile = (user.profile_name || mobile).toString();
if ((profile.length === 11 && profile.indexOf('*') < 0) || (profile.indexOf('-') >= 0 &&
profile.indexOf('*') < 0)) {
profile = profile.substring(0, 3) + '****' + profile.substring(7, 11);
}
return {
username: profile,
headImg: user.head_ico ? helpers.image(user.head_ico, 100, 100, 2) : DEFAULT_HEAD_IMG_ICO,
bindLogin: helpers.urlFormat('/signin.html', {bindMobile: mobile, bindArea: area})
};
});
};
module.exports = Object.assign(api, {
getUserInfo
});
... ...
... ... @@ -24,9 +24,9 @@ router.get('/logout.html', login.local.logout);
// 本地登录
// 短信验证码
router.post('/passport/login/sms/send', login.local.sms.send); // 发短信验证码
router.post('/passport/login/sms/auth', login.local.sms.auth); // 验证短信验证码
router.post('/passport/login/sms/checkuser', login.local.sms.checkUser); // 短信检查用户是否注册
// router.post('/passport/login/sms/send', login.local.sms.send); // 发短信验证码
// router.post('/passport/login/sms/auth', login.local.sms.auth); // 验证短信验证码
// router.post('/passport/login/sms/checkuser', login.local.sms.checkUser); // 短信检查用户是否注册
router.post('/passport/login/password/checkuser', back.fakeGetUserInfoAPI);// 假的,密码登录检查用户是否注册
// 二维码登录
... ...
... ... @@ -28,10 +28,12 @@
</li>
<li class="relative">
<li class="relative hide">
<div class="switch">
<div class="left selected" data-type="PasswordLogin">普通登录</div>
{{#if smsLogin}}
<div class="right" data-type="SMSLogin">手机验证码登录</div>
{{/if}}
</div>
</li>
... ... @@ -55,7 +57,7 @@
</span>
</li>
{{#if smsLogin}}
<li class="relative clearfix sms-login hide">
<input id="account2" class="account input va" name="account2" value="{{bindMobile}}"
type="text"
... ... @@ -76,6 +78,7 @@
<em></em>
</span>
</li>
{{/if}}
<li class="clearfix captcha-wrap hide">
<input id="captcha" class="input va captcha" type="text" name="captcha" placeholder="图形验证码"
... ... @@ -92,7 +95,7 @@
<span id="login-btn" class="login-btn btn">登录</span>
</li>
<li class="other-opts">
<span class="remember-me">
<span class="remember-me checked">
<i class="iconfont">&#xe613;</i>
记住登录状态
</span>
... ...
... ... @@ -7,6 +7,7 @@
const mRoot = '../models';
const list = require(`${mRoot}/list`);
const helpers = global.yoho.helpers;
const _ = require('lodash');
// 搜索相关接口
const searchApi = require(`${mRoot}/search-api`);
... ... @@ -32,12 +33,22 @@ const shop = (shopId, req, res, next, brandInfo) => {
page: 'shop',
shopId: shopId
});
// 店铺装修为空则不cache
if (!result.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/shop-index', result);
}).catch(next);
} else { // 基础模板
list.getBaseShopData(req.query, Object.assign({uid: req.user.uid}, brandInfo),
req.yoho.channel, shopId).then(result => {
Object.assign(result, {page: 'list'});
// 基础店铺装修为空则不cache
if (!result.brand || !result.brand.shopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/brand', result);
}).catch(next);
}
... ... @@ -55,6 +66,11 @@ exports.index = (req, res, next) => {
list.getListData(req.query, req.yoho.channel).then(result => {
Object.assign(resData, result);
// 查询结果为空则不cache
if (_.isEmpty(_.get(resData, 'list.goods', []))) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/index', resData);
}).catch(next);
... ... @@ -70,7 +86,15 @@ exports.new = (req, res, next) => {
let resData = {};
list.getListNewData(Object.assign({order: 's_t_desc'}, req.query), req.yoho.channel).then(result => {
Object.assign(resData, result);
Object.assign(resData, result, {
hideInfo: {from: 'newProduct'}
});
// 查询结果为空则不cache
if (_.isEmpty(_.get(resData, 'list.goods', []))) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/index', resData);
}).catch(next);
... ... @@ -166,6 +190,11 @@ exports.shopList = (req, res, next) => {
if (req.query.query) {
result.shopKey = req.query.query;
}
// 店铺装修为空则不cache
if (!result.shopTopBanner) {
res.set('Cache-Control', 'no-cache');
}
res.render('list/shop-list', result);
}).catch(next);
};
... ...
... ... @@ -16,6 +16,7 @@ const _ = require('lodash');
* @return {[type]} [description]
*/
exports.index = (req, res, next) => {
let params = req.query;
let resData = {
title: '潮流商品搜索 | YOHO!BUY 有货',
keywords: 'Yoho! 有货,潮流,时尚,流行,购物,B2C,正品,购物网站,网上购物,货到付款,' +
... ... @@ -24,16 +25,23 @@ exports.index = (req, res, next) => {
description: '潮流商品搜索,上衣,衬衫,TEE,卫衣,冲锋衣,风衣,羽绒服,裤子,休闲鞋,板鞋,配饰,复古眼镜'
};
search.getSearchData(req.query, req.yoho.channel).then(result => {
Object.assign(resData, result);
if (!_.get(resData, 'search.goods') || !_.get(resData, 'search.goods').length) {
_.set(resData, 'search.keyWord', req.query.query);
return res.render('search/no-result', resData);
search.getKeyActivity(params.query).then(activityUrl => {
if (activityUrl) {
activityUrl = encodeURI(activityUrl);
res.redirect(activityUrl);
return;
}
res.render('search/index', resData);
}).catch(next);
return search.getSearchData(params, req.yoho.channel).then(result => {
Object.assign(resData, result);
if (!_.get(resData, 'search.goods') || !_.get(resData, 'search.goods').length) {
_.set(resData, 'search.keyWord', req.query.query);
return res.render('search/no-result', resData);
}
res.render('search/index', resData);
});
}).catch(next);
};
/**
... ...
... ... @@ -5,8 +5,7 @@
*/
var express = require('express'),
path = require('path'),
hbs = require('express-handlebars');
path = require('path');
var app = express();
... ... @@ -18,12 +17,12 @@ app.on('mount', function(parent) {
Object.assign(app.locals, parent.locals);
});
app.set('views', path.join(__dirname, 'views/action'));
app.engine('.hbs', hbs({
app.use(global.yoho.hbs({
extname: '.hbs',
defaultLayout: 'layout',
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
}));
... ...
... ... @@ -5,12 +5,13 @@
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
const getBannerInfoAsync = bid => {
return api.get('', {
method: 'web.brand.banner',
brand_id: bid
});
}, config.apiCache);
};
... ... @@ -18,7 +19,7 @@ const getBrandLogoByDomainAsync = domain => {
return api.get('', {
domain: domain,
method: 'web.brand.byDomain'
});
}, config.apiCache);
};
module.exports = {
... ...
... ... @@ -7,18 +7,6 @@
const api = global.yoho.API;
/**
* 获取评论
*/
const indexAsync = (pid, page, size) => {
return api.get('', {
method: 'app.comment.li',
product_id: pid,
page: page,
limit: size
});
};
/**
* 商品详情页的评论列表
*
* @param pid 商品productId
... ... @@ -39,7 +27,6 @@ const getShareOrderListAsync = (pid, page, size) => {
};
module.exports = {
indexAsync,
getShareOrderListAsync
};
... ...
... ... @@ -4,45 +4,7 @@
'use strict';
const Promise = require('bluebird');
const co = Promise.coroutine;
const _ = require('lodash');
const helpers = global.yoho.helpers;
const api = require('./detail-comment-api');
const detailHelper = require('./detail-helper');
const indexAsync = (pid, page, size) => {
return co(function *() {
let commentList = yield api.indexAsync(pid, page, size);
if (!(commentList.code && commentList.code === 200)) {
return [];
}
return commentList.data.map(value => {
let item = {};
let avatar = detailHelper.DEFAULT_AVATAR_ICO;
if (value.head_ico) {
avatar = `${_.last(value.head_ico.split('headimg'))}`;
avatar = helpers.image(avatar, 30, 30);
}
item.avatar = avatar;
item.userName = value.nickname;
item.color = value.color_name;
item.size = value.size_name;
item.comment = value.content || '';
item.date = value.create_time;
item.total = value.total;
return item;
});
})();
};
/**
* 获取订单评论
... ... @@ -51,11 +13,8 @@ const indexAsync = (pid, page, size) => {
* @param page
* @param size
*/
const getShareOrderListAsync = (pid, page, size) => {
return api.getShareOrderListAsync(pid, page, size);
};
const getShareOrderListAsync = api.getShareOrderListAsync;
module.exports = {
indexAsync,
getShareOrderListAsync
};
... ...
... ... @@ -5,6 +5,7 @@
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
/**
* 获取商品的热区
... ... @@ -13,7 +14,7 @@ const indexAsync = pid => {
return api.get('', {
method: 'web.productCollocation.list',
product_id: pid
});
}, config.apiCache);
};
module.exports = {
... ...
... ... @@ -5,12 +5,13 @@
'use strict';
const api = global.yoho.API;
const config = global.yoho.config;
const getProductBannerAsync = (pid) => {
return api.get('', {
method: 'web.productBanner.data',
product_id: pid
});
}, config.apiCache);
};
... ... @@ -18,7 +19,7 @@ const sizeInfoAsync = skn => {
return api.get('', {
method: 'h5.product.intro',
productskn: skn
});
}, config.apiCache);
};
... ... @@ -27,14 +28,14 @@ const isSupportReturnedSale = skn => {
return api.get('', {
method: 'app.product.refundExchange',
product_skn: skn
});
}, config.apiCache);
};
const getProductComfortAsync = pid => {
return api.get('', {
method: 'web.productComfort.data',
product_id: pid
});
}, config.apiCache);
};
... ... @@ -42,14 +43,14 @@ const getProductModelCardAsync = pid => {
return api.get('', {
method: 'web.productModelcard.list',
product_id: pid
});
}, config.apiCache);
};
const getProductModelTryAsync = skn => {
return api.get('', {
method: 'web.productModelTry.data',
product_skn: skn
});
}, config.apiCache);
};
/**
... ... @@ -74,7 +75,7 @@ const getProductAsync = (pid, uid, isStudents, vipLevel) => {
if (vipLevel) {
params.current_vip_level = vipLevel;
}
return api.get('', params);
return api.get('', params, config.apiCache);
};
const getPromotionAsync = (skn) => {
... ... @@ -83,7 +84,7 @@ const getPromotionAsync = (skn) => {
product_skn: skn
};
return api.get('', params);
return api.get('', params, config.apiCache);
};
const getLimitedProductStatusAsync = (code, uid, skn) => {
... ... @@ -100,7 +101,7 @@ const getLimitedProductStatusAsync = (code, uid, skn) => {
params.product_skn = skn;
}
return api.get('', params);
return api.get('', params, config.apiCache);
};
module.exports = {
... ...