Showing 100 changed files with 1950 additions and 377 deletions

Too many changes to show.

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

... ... @@ -143,6 +143,7 @@ typings/
### YOHO ###
dist
public/build/bundle/*
public/build/dll/*
public/build/dist/*
public/css/*
public/bundle/*
... ...
... ... @@ -20,14 +20,10 @@ const path = require('path');
const compression = require('compression');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const uuid = require('uuid');
const moment = require('moment');
const pkg = require('./package.json');
const cookieSession = require('client-sessions');
const memcachedSession = require('yoho-express-session');
const memcached = require('connect-memcached');
const MemcachedStore = memcached(memcachedSession);
const hbsEvent = require('./config/hbsevent');
const _ = require('lodash');
const app = express();
... ... @@ -43,9 +39,6 @@ yohoLib.global(config);
const logger = global.yoho.logger;
// tdk
global.yoho.redis = require('./doraemon/middleware/redis');
// zookeeper
if (config.zookeeperServer) {
require('yoho-zookeeper')(config.zookeeperServer, 'wap', app.locals.wap = {}, global.yoho.cache);
... ... @@ -97,7 +90,8 @@ app.use(global.yoho.hbs({
layoutsDir: path.join(__dirname, 'doraemon/views'),
partialsDir: path.join(__dirname, 'doraemon/views/partial'),
views: path.join(__dirname, 'doraemon/views'),
helpers: _.assign(global.yoho.helpers, require('./utils/helpers'))
helpers: _.assign(global.yoho.helpers, require('./utils/helpers')),
cb: hbsEvent.cb
}));
... ... @@ -108,67 +102,7 @@ app.use(bodyParser.urlencoded({
app.use(cookieParser());
app.use(compression());
const sessionStore = new MemcachedStore({
hosts: config.memcache.session,
prefix: 'yohobuy_session:',
reconnect: 5000,
timeout: 1000,
retries: 0
});
app.use(memcachedSession({
proxy: true,
resave: false,
saveUninitialized: true,
unset: 'destroy',
secret: '82dd7e724f2c6870472c89dfa43cf48d',
name: 'yohobuy_session',
cookie: {
domain: 'yohobuy.com',
httpOnly: false
},
store: sessionStore
}));
app.use(cookieSession({
requestKey: 'session2',
cookieName: 'yohobuy_session_cookie',
secret: '82dd7e724f2c6870472c89dfa43cf48d',
cookie: {
domain: 'yohobuy.com',
ephemeral: true
}
}));
app.use((req, res, next) => {
if (req.session) {
let sessionKeys = Object.keys(req.session || {});
let backSessionKeys = Object.keys(req.session2.sessionBack || {});
if (backSessionKeys.length > sessionKeys.length) {
let differences = _.difference(backSessionKeys, sessionKeys);
_.forEach(differences, d => {
req.session[d] = req.session2.sessionBack[d];
});
}
req.session2.sessionBack = req.session;
} else {
req.session = new memcachedSession.Session(req);
req.session.cookie = new memcachedSession.Cookie({
domain: 'yohobuy.com',
httpOnly: false
});
req.session = _.assign(req.session, req.session2.sessionBack);
}
if (!req.sessionID) {
req.sessionID = uuid.v4();
}
next();
});
require('./doraemon/middleware/yoho-session')(app);
app.use((req, res, next) => {
req.user = {}; // 全局的用户数据
... ... @@ -231,4 +165,15 @@ try {
// listener
app.listen(config.port, function() {
logger.info('yohobuy start');
hbsEvent.event.on('hbs-complete', () => {
logger.info('hbs-all-complete');
if (!process.env.NODE_ENV || process.env.NODE_ENV === 'dev') {
let {devHost, port} = require('./config/devtools');
require('request-promise')({
url: `http://${devHost}:${port}/event?action=reload`
}).then(() => {}, () =>{});
}
});
});
... ...
... ... @@ -7,6 +7,7 @@ const sm = require('sitemap');
const staticUrls = require('../../../config/staticUrls');
const api = global.yoho.API;
const Service = global.yoho.ServiceAPI;
const redis = require('../../../utils/redis');
const getStaticUrls = (currentStatics) => {
let urls = [];
... ... @@ -50,13 +51,37 @@ const itemXmlData = () => {// eslint-disable-line
});
};
// m 地图数据
const mXmlData = () => {// eslint-disable-line
return Promise.all([getStaticUrls(_.get(staticUrls, 'm')), itemXmlData()]).then(result => {
return _.union(result[0], result[1]);
// 关键词页面
const keywordsPage = (page) => {
return redis.getAsync(`global:yoho:seo:keywords:allIds:page:${page}`).then(function(res) {
let pages = [];
_.forEach(JSON.parse(res), val => {
pages.push({
url: `https://m.yohobuy.com/chanpin/${val}.html`,
changefreq: 'daily',
priority: 0.5
});
});
return pages;
}).timeout(200).catch(()=>{
return {};
});
};
// m 地图数据
const mXmlData = (page) => {// eslint-disable-line
if (page > 1) {
return keywordsPage(page);
} else {
return Promise.all([keywordsPage(page),
getStaticUrls(_.get(staticUrls, 'm')),
itemXmlData()]).then(result => {
return _.concat(result[1], result[0], result[2]);
});
}
};
// list 地图数据
const listXmlData = () => {// eslint-disable-line
return getStaticUrls(_.get(staticUrls, 'list'));
... ... @@ -95,7 +120,10 @@ const siteMap = (req, res, next) => {
res.end('end');
return;
}
eval(subdomain + 'XmlData')().then(urls => {// eslint-disable-line
let page = req.params[0] || 1;
eval(subdomain + 'XmlData')(page).then(urls => {// eslint-disable-line
sm.createSitemap({
hostname: `https://${subdomain}.yohobuy.com`,
xmlNs: ' ',
... ...
... ... @@ -6,7 +6,8 @@
var express = require('express'),
path = require('path'),
helpers = require(path.join(global.utils, 'helpers'));
helpers = require(path.join(global.utils, 'helpers')),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -26,7 +27,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, 'views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: Object.assign({}, global.yoho.helpers, helpers)
helpers: Object.assign({}, global.yoho.helpers, helpers),
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -120,7 +120,7 @@ exports.inviteReg = (req, res, next) => {
let isApp = req.yoho.isApp,
uid = req.user.uid;
req.ctx(expandModel).promotionData(uid, isApp).then(result => {
req.ctx(expandModel)._getPromotionData(uid, isApp).then(result => {
res.render('expand-new/invite-reg', {
isApp: isApp,
width750: true,
... ...
... ... @@ -6,7 +6,8 @@
var express = require('express'),
path = require('path'),
helpers = require(path.join(global.utils, 'helpers'));
helpers = require(path.join(global.utils, 'helpers')),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -26,7 +27,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, 'views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: Object.assign({}, global.yoho.helpers, helpers)
helpers: Object.assign({}, global.yoho.helpers, helpers),
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -25,6 +25,7 @@ module.exports = class extends global.yoho.BaseModel {
result.data.isApp = isApp;
result.data.copyCode = result.data.trendWord ? result.data.trendWord : result.data.inviteCode;
result.data.copyUrl = result.data.shareUrl ?
result.data.shareUrl.replace(/"/g, '"').replace(/=/g, ':') : '';
... ... @@ -41,6 +42,9 @@ module.exports = class extends global.yoho.BaseModel {
_getTrendPop(contentCode) {
return service.get('operations/api/v5/resource/get', {
content_code: contentCode,
}, {
code: 200,
cache: true
}).then(result => {
if (result && result.code === 200 && result.data) {
return result.data[0];
... ...
... ... @@ -53,7 +53,7 @@ module.exports = {
yh_channel: params.yh_channel,
limit: params.limit,
need_filter: 'null',
rec_pos: '100008',
rec_pos: '100004',
gender: params.gender || gender[params.yh_channel]
}, {
cache: true
... ...
... ... @@ -211,7 +211,11 @@ module.exports = class extends global.yoho.BaseModel {
}, {
code: 200
}).then((result) => {
let currencyUrl = 'http://m.yohobuy.com/home/helpDetail?code=20151230-102233&caption=有货币介绍&name=有货币介绍';
let currencyUrl = helpers.urlFormat('/service/qaDetail', {
keyword: '%E6%9C%89%E8%B4%A7%E5%B8%81',
sonId: '233'
});
let shareUrl = 'http://m.yohobuy.com/activity/share-buy';
if (result && result.code === 200 && result.data) {
... ...
... ... @@ -13,7 +13,7 @@
{{# hotGoods}}
<a class="goods-info" href="{{url}}" data-good-id="{{product_id}}">
<div class="goods-image">
<img src="{{image2 default_images w=340 h=370 q=60}}">
<img src="{{image default_images 318 425}}">
</div>
<div class="good-detail-text">
<div class="price">
... ...
... ... @@ -16,7 +16,7 @@
<span class="code trend-code">{{#if trendWord}}{{trendWord}}{{else}}{{inviteCode}}{{/if}}</span>
<span class="modify button">修改</span>
{{#if isApp}}
<a class="copy button" href='//m.yohobuy.com/?openby:yohobuy={"action":"go.copy","params":{"text":"{{inviteCode}}","message":"复制成功"}}'>复制</a>
<a class="copy button" href='//m.yohobuy.com/?openby:yohobuy={"action":"go.copy","params":{"text":"{{copyCode}}","message":"复制成功"}}'>复制</a>
{{/if}}
</div>
<p class="info">1.复制您的潮流口令 2.粘贴给您的朋友(微信/短信等方式)</p>
... ...
... ... @@ -5,7 +5,8 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -25,7 +26,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, 'views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -49,8 +49,8 @@
</h3>
<ul class="dispatch-mode">
{{#each dispatchMode}}
<li {{#if isSelected}}class="chosed"{{/if}} data-id="{{id}}">
<span>{{name}}:运费¥{{cost}}</span>
<li class="{{#if isSelected}}chosed{{/if}}{{#if is_support_message}} no-support{{/if}}" data-id="{{id}}">
<span>{{name}}:运费¥{{cost}} {{#if is_support_message}}({{is_support_message}}){{/if}}</span>
<i class="right iconfont {{#if isSelected}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{id}}"></i>
</li>
{{/each}}
... ...
... ... @@ -49,9 +49,9 @@
</h3>
<ul class="dispatch-mode">
{{#each dispatchMode}}
<li {{#if isSelected}}class="chosed"{{/if}} data-id="{{id}}">
<span>{{name}}:运费¥{{cost}}</span>
<i class="right iconfont {{#if isSelected}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{id}}"></i>
<li class="{{#if isSelected}}chosed{{/if}}{{#if is_support_message}} no-support{{/if}}" data-id="{{id}}">
<span>{{name}}:运费¥{{cost}} {{#if is_support_message}}({{is_support_message}}){{/if}}</span>
<i class="right iconfont {{#if isSelected}}icon-cb-radio{{else}}icon-radio{{/if}}" data-id="{{id}}"></i>
</li>
{{/each}}
</ul>
... ...
... ... @@ -54,13 +54,3 @@ _fxcmd.push(['trackOrder', {
unid : "{{uid}}"
}]);
</script>
{{!--<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{ event: "setAccount", account: [21397] },
{ event: "setHashedEmail", email: "" },
{ event: "setSiteType", type: "m" },
{ event: "trackTransaction" , id: "{{orderCode}}", currency: "CNY", item: ""}
);
</script>--}}
... ...
... ... @@ -39,6 +39,10 @@ let _channelPage = (req, res, data) => {
res.set('Cache-Control', 'no-cache');
}
if (result && result.content && result.content.length) {
result.content.length = 6;
}
// result.content = [{
// seckill: true,
// data: {
... ...
... ... @@ -5,7 +5,9 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -26,7 +28,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, 'views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -168,7 +168,17 @@ const index = (req, res, next) => {
isShare = isWeixin || isqq || isWeibo ? true : false;
co(function* () {
let ret = yield tdk('article', id, req);
let [ret, detail, commentsTotal, praise, wxFooter] = yield Promise.all([
tdk('article', id, req),
req.ctx(DetailModel).packageData(id, isApp, isWeixin, channel, isShare),
req.ctx(DetailModel).commentsTotal({ article_id: id, udid: udid }),
req.ctx(DetailModel).getArticlePraiseAndFavor({
uid: uid,
id: id,
udid: udid
}),
req.ctx(aboutModel).about(req.yoho.isApp)
]);
if (ret[0]) {
req.tdk = {
... ... @@ -177,13 +187,7 @@ const index = (req, res, next) => {
description: ret[3]
};
}
let detail = yield req.ctx(DetailModel).packageData(id, isApp, isWeixin, channel, isShare);
let commentsTotal = yield req.ctx(DetailModel).commentsTotal({article_id: id, udid: udid});
let praise = yield req.ctx(DetailModel).getArticlePraiseAndFavor({
uid: uid,
id: id,
udid: udid
});
let data = {
guangDetail: true,
guang: {}
... ... @@ -275,9 +279,7 @@ const index = (req, res, next) => {
// 标识有微信分享
data.hasWxShare = true;
let resu = yield req.ctx(aboutModel).about(req.yoho.isApp);
data.guang.wxFooter = resu;
data.guang.wxFooter = wxFooter;
res.render('info/index', Object.assign({
page: 'info-index',
gender: gender,
... ...
... ... @@ -5,7 +5,8 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -25,7 +26,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, './views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -5,7 +5,8 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -25,7 +26,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, './views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -151,20 +151,15 @@ class favoriteIndexModel extends global.yoho.BaseModel {
let obj = {
productList: []
};
let shopOrBrandLink;
// if (empty(val.productSkn)) {
// continue;
// }
if (val.brandOrShopType === 'brandOrShopType') {
obj = _.assign(obj, {
link: helpers.urlFormat('/product/index/brand', {
shop_id: val.shopId
})
if (val.brandOrShopType === 'brand') {
shopOrBrandLink = helpers.urlFormat('/product/shop', {
brand_id: val.brandId
});
} else {
obj = _.assign(obj, {
link: helpers.urlFormat('', {}, val.brandDomain)
shopOrBrandLink = helpers.urlFormat('/product/shop', {
shop_id: val.shopId
});
}
... ... @@ -175,9 +170,7 @@ class favoriteIndexModel extends global.yoho.BaseModel {
discount: val.productDiscountNum,
brandImg: val.brandIco,
update: val.newProductNum,
link: helpers.urlFormat('/product/shop', {
shop_id: val.shopId
})
link: shopOrBrandLink
});
_.forEach(val.newProduct, function(data, key) {
... ...
... ... @@ -23,13 +23,3 @@
unid: "{{uid}}"
}]);
</script>
<script type="text/javascript" src="//static.criteo.net/js/ld/ld.js" async="true"></script>
<script type="text/javascript">
window.criteo_q = window.criteo_q || [];
window.criteo_q.push(
{event: "setAccount", account: [21397]},
{event: "setHashedEmail", email: ""},
{event: "setSiteType", type: "m"},
{event: "trackTransaction", id: "{{orderCode}}", currency: "CNY", item: ""}
);
</script>
... ...
... ... @@ -5,7 +5,8 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -25,7 +26,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
app.locals.layout = 'mip';
... ...
class BackNew {
/**
* 通过手机找回密码
*/
backByMobile(req, res) {
res.render('back/mobile-new', {
width750: true,
localCss: true,
module: 'passport',
page: 'back-mobile-new'
});
}
/**
* 通过邮箱找回密码
*/
backByEmail(req, res) {
res.render('back/email-new', {
width750: true,
localCss: true,
module: 'passport',
page: 'back-email-new'
});
}
/**
* 通过邮箱找回密码成功页
*/
backByEmailSuccess(req, res) {
res.render('back/email-success-new', {
width750: true,
localCss: true,
module: 'passport',
page: 'back-email-success-new'
});
}
}
module.exports = BackNew;
... ...
... ... @@ -41,7 +41,7 @@ exports.imgCheck = (req, res, next) => {
req.session.captchaTimeout = new Date().getTime() + 1000 * 60;
req.session.captchaSrc = result.data.verifiedGraphicCode;
return request(`${result.data.verifiedGraphicCode}?imageView2/0/format/jpg/q/70|watermark/2/text/${uuid.v4()}/fontsize/120/dissolve/10`).pipe(res); // eslint-disable-line
return request(`${result.data.verifiedGraphicCode}?imageView2/0/format/jpg/q/99|watermark/2/text/${uuid.v4()}/fontsize/120/dissolve/10`).pipe(res); // eslint-disable-line
}
next();
}).catch(next);
... ... @@ -70,7 +70,7 @@ exports.validate = (req, res, next) => {
let jsonData = {
code: 400,
message: '请将图片旋转到正确方向',
message: '请将所有图片点击翻转至正向朝上',
captchaShow: true
};
... ...
const _ = require('lodash');
const co = Promise.coroutine;
const RegService = require('../models/reg-service');
const LoginNewModel = require('../models/login-new');
class Login {
/**
* 登录页面
*/
loginPage(req, res, next) {
// 是否关闭账号登录
let closePassword = _.get(req.app.locals.wap, 'close.passwordLogin', false);
if (closePassword) {
return res.redirect(`/signin.html?refer=${req.query.refer || ''}`);
}
if (req.session.captchaValidCount == null) { // eslint-disable-line
req.session.captchaValidCount = 5;
}
co(function* () {
let bannerData = yield req.ctx(LoginNewModel).getTopBanner();
let banner = _.get(bannerData, 'data[0].data[0].src', '');
res.render('login/login-new', {
module: 'passport',
page: 'login-new',
localCss: true,
width750: true,
banner: banner,
captchaShow: req.yoho.captchaShow,
backUrl: 'javascript:history.go(-1)', // eslint-disable-line
smsLoginUrl: '/passport/sms_login',
registerUrl: '/passport/reg/index', // 注册的URL链接
aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接
weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接
qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接
wechatLoginUrl: '/passport/login/wechat', // 微信登录的URL链接
internationalUrl: '/passport/international', // 国际号登录的URL链接
phoneRetriveUrl: '/passport/back/mobile', // 通过手机号找回密码的URL链接
emailRetriveUrl: '/passport/back/email', // 通过邮箱找回密码的URL链接
isWechat: req.yoho.isWechat
});
})().catch(next);
}
/**
* 国际账号登录
*/
international(req, res) {
// 是否关闭账号登录
let closePassword = _.get(req.app.locals.wap, 'close.passwordLogin', false);
if (closePassword) {
return res.redirect(`/signin.html?refer=${req.query.refer || ''}`);
}
if (req.session.captchaValidCount == null) { // eslint-disable-line
req.session.captchaValidCount = 5;
}
res.render('login/international-new', {
module: 'passport',
page: 'international-new',
localCss: true,
width750: true,
captchaShow: req.yoho.captchaShow,
countrys: RegService.getAreaData()
});
}
}
module.exports = Login;
... ...
const _ = require('lodash');
const url = require('url');
const RegService = require('../models/reg-service');
const utils = require(global.utils);
const sign = global.yoho.sign;
const co = require('bluebird').coroutine;
const cookie = global.yoho.cookie;
const AuthHelper = require('../models/auth-helper');
class Reg {
/**
* 注册页面
*/
regPage(req, res, next) {
if (req.user.uid) {
return res.redirect(req.get('refer') || '/');
}
// 判断是否 来自 个人中心
if (!_.get(req.session, 'phoneReg.isFromMy')) {
let referer = req.get('Referer') || '';
let urlObj = url.parse(referer, true, true);
referer = _.get(urlObj, 'query.refer', '');
urlObj = url.parse(referer, true, true);
urlObj.path === '/home' && _.set(req.session, 'phoneReg.isFromMy', '1');
}
// 设置注册有效时间30分钟, 防机器刷
// req.session.REG_EXPIRE = Date.now() + 1800000;
let refer = req.query.refer;
refer = utils.refererLimit(refer);
refer && res.cookie('refer', encodeURI(refer), {
domain: 'yohobuy.com'
});
// session init
_.set(req.session, 'phoneReg.step', 1);
if (req.session.captchaValidCount == null) { // eslint-disable-line
req.session.captchaValidCount = 5;
}
if (req.session.phoneReg.count == null) { // eslint-disable-line
req.session.phoneReg.count = 5;
}
co(function* () {
let inviteValue = '';
let inviteCode = req.query.inviteCode;
if (inviteCode) {
let inviteUserInfo = yield RegService.inviteUserInfo(inviteCode);
inviteValue = _.get(inviteUserInfo, 'data.trendWord', inviteCode);
}
res.render('reg/reg-new', {
module: 'passport',
page: 'reg-new',
localCss: true,
width750: true,
inviteValue: inviteValue,
countrys: RegService.getAreaData() // 地区信息列表
});
})().catch(next);
}
/**
* 注册请求处理
*/
register(req, res, next) {
let postResult = {
code: 400
};
let mobile = +req.body.phoneNum;
let area = +(req.body.areaCode || 86);
let password = req.body.password;
let smsCode = +req.body.smsCode;
let inviteCode = req.body.inviteCode || '';
let isFromMy = _.get(req.session, 'phoneReg.isFromMy', '0');
let token = req.body.token;
// 购物车key
let shoppingKey = cookie.getShoppingKey(req);
// 判断参数是否合法
if (!smsCode || !_.isString(token) || !_.isNumber(mobile) || !_.isNumber(area) || !password) {
postResult.message = '请求参数不合法';
return res.json(postResult);
}
// 判断是否允许访问
if (!sign.verifyToken(mobile, token)) {
postResult.message = '非法 token';
return res.json(postResult);
}
// 判断密码是否符合规则
if (!/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$/.test(password)) {
postResult.message = '密码格式不正确';
return res.json(postResult);
}
co(function* () {
let validMobileCodeResult = yield RegService.validMobileCode(area, mobile, smsCode);
if (!validMobileCodeResult.code) {
return res.json(validMobileCodeResult);
}
let resultCode = _.get(validMobileCodeResult, 'code');
if (resultCode !== 200) {
return res.json(validMobileCodeResult);
}
let regMobileAesResult = yield RegService.regMobileAes(area, mobile, password,
shoppingKey, smsCode, inviteCode, isFromMy);
if (regMobileAesResult.code !== 200 || !regMobileAesResult.data ||
!regMobileAesResult.data.uid) {
return res.json(regMobileAesResult);
}
yield AuthHelper.syncUserSession(regMobileAesResult.data.uid,
req, res, regMobileAesResult.data.session_key);
// 返回跳转到来源页面
let refer = req.cookies.refer;
if (regMobileAesResult.data.newUserPage) {
refer = regMobileAesResult.data.msgDelivery; // 来自个人中心,跳新人会场
} else {
if (refer) {
refer = decodeURI(req.cookies.refer);
} else {
refer = '/home';
}
if (/sign|login/.test(refer)) {
refer = '/home';
}
refer = utils.refererLimit(refer);
}
delete req.session.phoneNum;
return res.json({
code: 200,
message: '注册成功',
data: {
session: refer,
href: '//m.yohobuy.com/activity/invite-reg',
msgDelivery: _.get(regMobileAesResult, 'data.msgDelivery', '')
}
});
})().catch(next);
}
}
module.exports = Reg;
... ...
... ... @@ -151,12 +151,15 @@ let verifyMobile = (req, res, next) => {
_.set(req.session, 'phoneReg.expire', Date.now() + 5 * 60 * 1000);
}
result.data = helpers.urlFormat('/passport/reg/code', {
token: token,
phoneNum: mobile,
areaCode: area,
inviteCode: inviteCode
});
result.data = {
href: helpers.urlFormat('/passport/reg/code', {
token: token,
phoneNum: mobile,
areaCode: area,
inviteCode: inviteCode
}),
token: token
};
}
return res.json(result);
}).catch(next);
... ...
const _ = require('lodash');
const RegService = require('../models/reg-service');
const co = Promise.coroutine;
const LoginNewModel = require('../models/login-new');
class SmsNew {
smsLoginPage(req, res, next) {
_.set(req.session, 'smsLogin.step', 1);
if (req.session.captchaValidCount == null) { // eslint-disable-line
req.session.captchaValidCount = 5;
}
co(function* () {
let bannerData = yield req.ctx(LoginNewModel).getTopBanner();
let banner = _.get(bannerData, 'data[0].data[0].src', '');
res.render('sms/sms-login-new', {
module: 'passport',
page: 'sms-login-new',
width750: true,
localCss: true,
banner: banner,
countrys: RegService.getAreaData(), // 地区信息列表
backUrl: 'javascript:history.go(-1)', // eslint-disable-line
loginUrl: '/passport/login',
registerUrl: '/passport/reg/index', // 注册的URL链接
aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接
weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接
qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接
wechatLoginUrl: '/passport/login/wechat', // 微信登录的URL链接
internationalUrl: '/passport/international', // 国际号登录的URL链接
phoneRetriveUrl: '/passport/back/mobile', // 通过手机号找回密码的URL链接
emailRetriveUrl: '/passport/back/email', // 通过邮箱找回密码的URL链接
isWechat: req.yoho.isWechat
});
})().catch(next);
}
}
module.exports = SmsNew;
... ...
... ... @@ -5,7 +5,8 @@
*/
'use strict';
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var passport = require('passport');
... ... @@ -27,7 +28,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: path.join(__dirname, 'views/partial'),
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
require('./auth');
... ...
const serviceApi = global.yoho.ServiceAPI;
const resources = {
yohobuy: 'b7a510c2ece17d205a8f17b06ee8d2af',
yohomars: '',
yohocoffee: ''
};
class LoginNewModel extends global.yoho.BaseModel {
constructor(ctx) {
super(ctx);
}
/**
* 调用接口获取登录页顶部的 Banner
*/
getTopBanner(which) {
let resource = resources.yohobuy;
if (which) {
resource = resources[which];
}
return serviceApi.get('operations/api/v5/resource/get', {
content_code: resource
}, {cache: true});
}
}
module.exports = LoginNewModel;
... ...
... ... @@ -114,6 +114,16 @@ const RegService = {
}
return api.post('', params);
},
/**
* 好友邀请信息
*/
inviteUserInfo(inviteCode) {
return api.get('', {
method: 'app.invitecode.userinfo',
inviteCode: inviteCode
});
}
};
... ...
... ... @@ -28,11 +28,11 @@ const router = express.Router(); // eslint-disable-line
router.get('/passport/geetest/register', geetest.register);
// 兼容老的路由
router.get('/signin.html', login.common.weixinCheck, validateCode.load,
login.common.beforeLogin, login.common.clearCookie, smsLogin.loginPage);
router.get('/reg.html', validateCode.load, disableBFCahce, reg.index);
router.get('/login.html', validateCode.load,
login.common.beforeLogin, login.common.clearCookie, login.local.international);
// router.get('/signin.html', login.common.weixinCheck, validateCode.load,
// login.common.beforeLogin, login.common.clearCookie, smsLogin.loginPage);
// router.get('/reg.html', validateCode.load, disableBFCahce, reg.index);
// router.get('/login.html', validateCode.load,
// login.common.beforeLogin, login.common.clearCookie, login.local.international);
router.get('/phoneback.html', back.indexMobilePage);
router.get('/emailback.html', back.indexEmailPage);
... ... @@ -40,21 +40,21 @@ router.get('/emailback.html', back.indexEmailPage);
router.get('/passport/signout/index', login.common.clearCookie, login.local.logout);
// 登录页面
router.get('/passport/login',
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
login.loginShowCaptchaByIp,
login.local.loginPage
);
router.get('/passport/international',
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
login.loginShowCaptchaByIp,
login.local.international
);
// router.get('/passport/login',
// validateCode.load,
// login.common.beforeLogin,
// login.common.clearCookie,
// login.loginShowCaptchaByIp,
// login.local.loginPage
// );
// router.get('/passport/international',
// validateCode.load,
// login.common.beforeLogin,
// login.common.clearCookie,
// login.loginShowCaptchaByIp,
// login.local.international
// );
// 本地登录
router.post('/passport/login/auth', validateCode.check, login.local.login);
... ... @@ -63,8 +63,9 @@ router.post('/passport/login/auth', validateCode.check, login.local.login);
router.get('/passport/login/check', login.common.check);
// SMS 短信
router.use('/passport/sms_login', login.common.beforeLogin, smsLogin.beforeIn);
router.get('/passport/sms_login', validateCode.load, smsLogin.loginPage);
// router.use('/passport/sms_login', login.common.beforeLogin, smsLogin.beforeIn);
// router.get('/passport/sms_login', validateCode.load, smsLogin.loginPage);
router.post('/passport/sms_login/step1_check', validateCode.check, smsLogin.indexCheck);
router.get('/passport/sms_login/token.json',
smsLogin.tokenBefore,
... ... @@ -113,7 +114,8 @@ router.post('/passport/bind/changeMobile', bind.changeMobile);
* 注册
*/
router.use('/passport/reg/*', disableBFCahce);
router.get('/passport/reg/index', validateCode.load, reg.index);
// router.get('/passport/reg/index', validateCode.load, reg.index);
router.post('/passport/reg/verifymobile', validateCode.check, reg.sendCodeBusyBoy, reg.verifyMobile);
router.get('/passport/reg/code', reg.guardStep(2), reg.code);
router.post('/passport/reg/sendcode', reg.guardStep(2), reg.sendCodeBusyBoy, reg.sendCode);
... ... @@ -163,4 +165,57 @@ let captcha = require('./controllers/captcha');
router.get('/passport/captcha/get', captcha.get);
router.get('/passport/img-check.jpg', captcha.imgCheck);
// 新的登录注册
const LoginNew = require('./controllers/login-new');
const loginNew = new LoginNew();
const RegNew = require('./controllers/reg-new');
const regNew = new RegNew();
const SmsNew = require('./controllers/sms-new');
const smsNew = new SmsNew();
const BackNew = require('./controllers/back-new');
const backNew = new BackNew();
router.get('/passport/login',
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
login.loginShowCaptchaByIp,
loginNew.loginPage); // 普通登录
router.get('/passport/international',
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
login.loginShowCaptchaByIp,
loginNew.international); // 国际账号登录
router.get('/passport/reg/index',
validateCode.load,
regNew.regPage); // 注册页面
router.post('/passport/register-new',
reg.sendCodeBusyBoy,
regNew.register); // 注册请求
router.get('/passport/sms_login',
validateCode.load,
smsNew.smsLoginPage); // 短信验证码登录
// 兼容老的路由
router.get('/signin.html',
login.common.weixinCheck,
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
smsNew.smsLoginPage); // 短信验证码登录
router.get('/reg.html',
validateCode.load,
regNew.regPage); // 注册页面
router.get('/login.html',
validateCode.load,
login.common.beforeLogin,
login.common.clearCookie,
login.loginShowCaptchaByIp,
loginNew.international); // 国际账号登录
router.get('/passport/back/mobile-new', backNew.backByMobile); // 通过手机找回密码
router.get('/passport/back/email-new', backNew.backByEmail); // 通过邮箱找回密码
router.get('/passport/back/email-success-new', backNew.backByEmailSuccess); // 通过邮箱找回密码成功页
module.exports = router;
... ...
<div class="back-email-new-page">
<div class="top-operation-bar">
<button class="back iconfont">&#xe72e;</button>
<span class="page-title">邮箱找回密码</span>
<button class="close iconfont">&#xe72d;</button>
</div>
<div class="back-email-form">
<div class="form-group email">
<label for="email" class="iconfont">&#xe724;</label><input type="text" name="email" placeholder="请输入邮箱"><i class="iconfont clear">&#xe72a;</i>
</div>
<button id="backEmailResetBtn" class="back-email-reset-btn">确 认</button>
</div>
</div>
... ...
<div class="back-email-success-new-page">
<div class="top-operation-bar">
<button class="back iconfont">&#xe72e;</button>
<span class="page-title">邮箱找回密码</span>
<button class="close iconfont">&#xe72d;</button>
</div>
<div class="success-info">
<div class="iconfont">&#xe72b;</div>
<p class="info">验证邮件已发送至您的邮箱</p>
<p class="info">请在24小时内通过邮件内的链接设置新密码</p>
</div>
<div class="form-group back-email-success-btn">
<button id="backEmailSuccessBtn">完 成</button>
</div>
<div class="form-group resend-email-btn">
<button id="resendEmailBtn">重新发送邮件</button>
</div>
</div>
\ No newline at end of file
... ...
<div class="back-mobile-new-page">
<div class="top-operation-bar">
<button class="back iconfont">&#xe72e;</button>
<span class="page-title">手机找回密码</span>
<button class="close iconfont">&#xe72d;</button>
</div>
<div class="back-mobile-form">
<div class="form-group mobile">
<label for="mobile" class="iconfont">&#xe727;</label><button class="country-code">+86<i class="iconfont">&#xe72f;</i></button><i class="line">|</i><input type="number" name="mobile" placeholder="请输入手机号" class="mobile-input"><i class="iconfont clear">&#xe72a;</i>
</div>
<div class="form-group verify-code">
<label for="verifyCode" class="iconfont">&#xe71c;</label><input type="text" name="verifyCode" placeholder="请输入验证码" class="verify-code-input"><button class="get-verify-code">获取验证码</button>
</div>
<div class="form-group password">
<label for="password" class="iconfont">&#xe723;</label><input type="password" name="password" placeholder="请重置新密码"><span id="passwordEyeIcon" class="eye"><i class="iconfont eye-close">&#xe716;</i><i class="iconfont eye-open hide">&#xe714;</i></span>
</div>
<button id="backMobileResetBtn" class="back-mobile-reset-btn">重置登录密码</button>
</div>
</div>
\ No newline at end of file
... ...
<div class="international-new-page">
<div class="top-operation-bar">
<button class="back iconfont" onclick="javascript:history.go(-1);">&#xe72e;</button>
<span class="page-title">海外账号登录</span>
</div>
<div class="international-form">
<div class="form-group mobile">
<label for="mobile" class="iconfont">&#xe727;</label>
<select name="" id="countryCodeSelector" class="country-select">
{{# countrys}}
<option value={{areaCode}} {{#if selected}}selected{{/if}}>{{name}}</option>
{{/ countrys}}
</select>
<i class="iconfont arrow-icon">&#xe72f;</i>
<i class="line">|</i><input type="number" name="mobile" placeholder="请输入手机号" class="mobile-input"><i id="clearMobile"
class="iconfont clear hide">&#xe72a;</i>
</div>
<div class="form-group password">
<label for="password" class="iconfont">&#xe723;</label><input type="password" name="password" placeholder="请输入密码">
<span
id="passwordEyeIcon" class="eye"><i class="iconfont eye-close">&#xe716;</i><i class="iconfont eye-open hide">&#xe714;</i></span>
</div>
<div data-userverify="{{captchaShow}}" data-geetest="{{useGeetest}}" id="js-img-check" {{#unless useGeetest}} class="full-img-verify" {{/unless}}></div>
<button id="internationalLoginBtn" class="international-login-btn">登录</button>
</div>
</div>
\ No newline at end of file
... ...
<div class="login-new-page">
<div class="banner-box">
<img src="{{image2 banner w=750 h=290}}">
<div class="banner-info">
<div class="top-operation-bar">
<button class="close iconfont" onclick="location.href='{{backUrl}}'">&#xe72e;</button>
<a href="{{registerUrl}}" class="register">注册</a>
</div>
<div class="tip">Yoho!Family账号可登录Yoho!Buy有货 <i id="showYohoFamilyTip" class="iconfont">&#xe639;</i></div>
</div>
</div>
<div class="login-form">
<div class="form-group username">
<label for="username" class="iconfont">&#xe727;</label><input type="text" name="username" placeholder="请输入手机号/邮箱">
<i id="clearUsrname" class="iconfont clear hide">&#xe72a;</i>
</div>
<div class="form-group password">
<label for="password" class="iconfont">&#xe723;</label><input type="password" name="password" placeholder="请输入密码">
<span id="passwordEyeIcon" class="eye"><i class="iconfont eye-close">&#xe716;</i><i class="iconfont eye-open hide">&#xe714;</i></span>
</div>
<div data-userverify="{{captchaShow}}" data-geetest="{{useGeetest}}" id="js-img-check" {{#unless useGeetest}} class="full-img-verify" {{/unless}}></div>
<button id="loginBtn" class="login-btn disable">登录</button>
<div class="other-info">
<a href="{{internationalUrl}}">海外账号登录</a>
<a href="{{smsLoginUrl}}">手机验证码登录</a>
<a id="getPswrdBtn" href="javascript:void(0);">忘记密码?</a>
</div>
</div>
<div class="third-party-login">
<div class="tip-box">
<span class="left-line"></span>
<span class="tip">使用第三方登录</span>
<span class="right-line"></span>
</div>
<div class="third-logo-box">
{{#if isWechat}}
<a href="{{wechatLoginUrl}}" class="iconfont">&#xe728;</a>
{{^}}
<a href="{{aliLoginUrl}}" class="iconfont">&#xe72c;</a>
{{/if}}
<a href="{{weiboLoginUrl}}" class="iconfont">&#xe729;</a>
<a href="{{qqLoginUrl}}" class="iconfont">&#xe726;</a>
</div>
</div>
<div class="get-password-box hide">
<div class="bottom-button-box">
<a class="by-email" onclick="location.href='{{emailRetriveUrl}}'">邮箱找回</a>
<a class="by-mobile" onclick="location.href='{{phoneRetriveUrl}}'">手机找回</a>
</div>
</div>
</div>
\ No newline at end of file
... ...
<div class="reg-new-page">
<div class="top-operation-bar">
<button class="back iconfont" onclick="javascript:history.go(-1);">&#xe72e;</button>
<span class="page-title">注册</span>
</div>
<div class="reg-form">
<div class="form-group mobile">
<label for="mobile" class="iconfont">&#xe727;</label>
<select name="" id="countryCodeSelector" class="country-select">
{{# countrys}}
<option value={{areaCode}} {{#if selected}}selected{{/if}}>{{name}}</option>
{{/ countrys}}
</select>
<i class="iconfont arrow-icon">&#xe72f;</i>
<i class="line">|</i><input type="number" name="mobile" placeholder="请输入手机号" class="mobile-input" autocomplete="off"><i id="clearMobile"
class="iconfont clear hide">&#xe72a;</i>
</div>
<div class="form-group verify-code">
<label for="verifyCode" class="iconfont">&#xe71c;</label><input type="text" name="verifyCode" placeholder="请输入验证码"
class="verify-code-input" autocomplete="off"><button id="getVerifyCodeBtn" class="get-verify-code">获取验证码</button>
</div>
<div class="form-group password">
<label for="password" class="iconfont">&#xe723;</label><input type="password" name="password" placeholder="请输入密码" autocomplete="off">
<span
id="passwordEyeIcon" class="eye"><i class="iconfont eye-close">&#xe716;</i><i class="iconfont eye-open hide">&#xe714;</i></span>
</div>
<div class="form-group invite-code">
<label for="inviteCode" class="iconfont">&#xe71e;</label><input type="text" name="inviteCode" placeholder="好友潮流口令(非必填)" autocomplete="off" value="{{inviteValue}}">
</div>
<input name="token" type="hidden" value="{{token}}">
<div data-geetest="{{useGeetest}}" id="js-img-check"{{#unless useGeetest}} class="full-img-verify"{{/unless}}></div>
<button id="regBtn" class="reg-btn">注册</button>
</div>
</div>
\ No newline at end of file
... ...
<div class="sms-login-new-page">
<div class="banner-box">
<img src="{{image2 banner w=750 h=290}}">
<div class="banner-info">
<div class="top-operation-bar">
<button class="close iconfont" onclick="location.href='{{backUrl}}'">&#xe72e;</button>
<a href="{{registerUrl}}" class="register">注册</a>
</div>
<div class="tip">Yoho!Family账号可登录Yoho!Buy有货 <i id="showYohoFamilyTip" class="iconfont">&#xe639;</i></div>
</div>
</div>
<div class="sms-login-form">
<div class="form-group mobile">
<label for="mobile" class="iconfont">&#xe727;</label>
<select name="" id="countryCodeSelector" class="country-select">
{{# countrys}}
<option value={{areaCode}} {{#if selected}}selected{{/if}}>{{name}}</option>
{{/ countrys}}
</select>
<i class="iconfont arrow-icon">&#xe72f;</i>
<i class="line">|</i><input type="number" name="mobile" placeholder="请输入手机号" class="mobile-input"><i id="clearMobile"
class="iconfont clear hide">&#xe72a;</i>
</div>
<div class="form-group verify-code">
<label for="verifyCode" class="iconfont">&#xe71c;</label><input type="text" name="verifyCode" placeholder="请输入验证码"
class="verify-code-input"><button id="getVerifyCodeBtn" class="get-verify-code">获取验证码</button>
</div>
<div data-geetest="{{useGeetest}}" id="js-img-check" {{#unless useGeetest}} class="full-img-verify" {{/unless}}></div>
<button id="smsLoginBtn" class="sms-login-btn">登录</button>
<div class="other-info">
<a href="{{internationalUrl}}">海外账号登录</a>
<a href="{{loginUrl}}">账号密码登录</a>
<a id="getPswrdBtn" href="javascript:void(0);">忘记密码?</a>
</div>
</div>
<div class="third-party-login">
<div class="tip-box">
<span class="left-line"></span>
<span class="tip">使用第三方登录</span>
<span class="right-line"></span>
</div>
<div class="third-logo-box">
{{#if isWechat}}
<a href="{{wechatLoginUrl}}" class="iconfont">&#xe728;</a> {{^}}
<a href="{{aliLoginUrl}}" class="iconfont">&#xe72c;</a>
{{/if}}
<a href="{{weiboLoginUrl}}" class="iconfont">&#xe729;</a>
<a href="{{qqLoginUrl}}" class="iconfont">&#xe726;</a>
</div>
</div>
<div class="get-password-box hide">
<div class="bottom-button-box">
<a class="by-email" onclick="location.href='{{emailRetriveUrl}}'">邮箱找回</a>
<a class="by-mobile" onclick="location.href='{{phoneRetriveUrl}}'">手机找回</a>
</div>
</div>
</div>
\ No newline at end of file
... ...
... ... @@ -204,7 +204,7 @@ const shop = {
shopInfo.shop_intro_link = helpers.urlFormat('/product/index/intro', { shop_id: shopId });
res.render('newshop/shop-reds', {
let finalResult = {
title: shopInfo.shop_name + '|' + shopInfo.shop_name + '潮流服装服饰-Yoho!Buy有货',
keywords: shopInfo.shop_name + ',' + shopInfo.shop_name + '服装服饰,' + shopInfo.shop_name + '潮流服装服饰',
description: shopInfo.shop_name + '|Yoho!Buy有货' + shopInfo.shop_name +
... ... @@ -234,7 +234,19 @@ const shop = {
couponData,
shopId,
banner, shopInfo, favCount, decorators, category
});
};
let domain = req.shopInfo.shop_domain || req.shopInfo.brandDomain || null;
if (domain) {
_.assign(finalResult, {
cononical: {
currentHref: `https://${domain}.m.yohobuy.com`
}
});
}
res.render('newshop/shop-reds', finalResult);
})().catch(next);
},
... ...
... ... @@ -319,6 +319,10 @@ const keyId = (req, res, next) => {
return searchModel.getSearchKeywordDataById(req.params.id, params, req.user.uid).then(result => {
let queryKey = result.queryKey;
if (!result) {
return next();
}
// 唤起 APP 的路径
res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.list","params":${JSON.stringify(params)}}`;
... ... @@ -336,7 +340,10 @@ const keyId = (req, res, next) => {
keywords: `${queryKey},${queryKey}价格,${queryKey}图片,${queryKey}怎么样,${queryKey}品牌,YOHO!BUY有货`,
description: `YOHO!BUY有货网yohobuy.com是国内专业的${queryKey}网上潮流购物商城,为您找到${_.get(result,
'total', 0)}${queryKey}、产品的详细参数,实时报价,价格行情,图片、评价、品牌等信息。买${queryKey},就上YOHO!BUY有货`,
pageFooter: true
pageFooter: true,
cononical: {
currentHref: `//www.yohobuy.com${req.originalUrl}`
}
});
}).catch(next);
};
... ...
... ... @@ -6,7 +6,8 @@
'use strict';
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -26,7 +27,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
// router
... ...
... ... @@ -458,6 +458,9 @@ const _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
}
dest.goodsName = origin.product_name;
// 线下店商品展示限制
dest.storeGood = origin.store_show_status === 3 || origin.store_show_status === 4;
// 活动促销短语
origin.market_phrase && (dest.marketPhrase = origin.market_phrase);
... ... @@ -560,7 +563,7 @@ const _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
dest.cartInfo.soldOut = true;
} else if (notForSale) { // 非卖品
dest.cartInfo.notForSale = true;
} else if (origin.is_deposit_advance === 'Y') { // 定金预售
} else if (origin.is_deposit_advance === 'Y' || origin.is_limit_time_advance === 'Y') { // 定金预售,定金促销
dest.cartInfo.isDepositAdvance = true;
} else if (origin.isLimitBuy) { // 限购
Object.assign(dest.cartInfo, cartInfo, {
... ... @@ -650,7 +653,9 @@ const _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
if (result.isSecKill === 'Y' && result.cartInfo.totalNum > 0) {
result.totalNum = 1;
}
if (result.storeGood) {
result.cartInfo.storeGood = true;
}
return result;
});
};
... ...
... ... @@ -7,7 +7,9 @@ const commentModel = require('./consult-comment');
const bundle = require('./bundle');
const utils = '../../../utils';
const detailProcess = require(`${utils}/detail-process`);
const redis = require(`${utils}/redis`);
const api = global.yoho.API;
const helpers = global.yoho.helpers;
const newDetail = {
/**
... ... @@ -42,7 +44,35 @@ const newDetail = {
result.data.goods_id = data.goodsId;
result.data.shopId = _.get(result, 'data.shop_id', null);
return detailProcess.prodessDetailData(result.data);
let finalResult = detailProcess.prodessDetailData(result.data);
let smallSort = _.get(result, 'data.smallSortId');
if (!smallSort) {
return finalResult;
}
return this.getRecomdKeywords(smallSort).then(res => {
let recomdKeywords = [];
res = res ? JSON.parse(res) : [];
_.forEach(_.slice(_.shuffle(res), 0, 12), val => {
recomdKeywords.push({
url: helpers.urlFormat(`/chanpin/${val.id}.html`),
keyword: val.keyword
});
});
finalResult.recommendKeywords = recomdKeywords;
return finalResult;
});
});
},
getRecomdKeywords(smallSort) {
return redis.all([['get', `global:yoho:seo:keywords:sortId:${smallSort}:page:1`]]).then(res => {
return res[0];
});
},
... ...
... ... @@ -2,7 +2,6 @@
* @Author: Targaryen
* @Date: 2016-05-18 11:42:11
* @Last Modified by: Targaryen
* @Last Modified time: 2017-02-24 15:18:50
*/
'use strict';
... ... @@ -24,7 +23,7 @@ module.exports = (data) => {
limit: data.limit || '20',
shopId: data.shopId,
yh_channel: yhchannelMap[data.yhChannel]
}).then(result => {
}, {cache: true}).then(result => {
let goodsContainer = $.load(result)('#goods-container');
let goodThumb = goodsContainer.find('.good-thumb');
... ...
... ... @@ -13,7 +13,7 @@ const logger = global.yoho.logger;
const api = global.yoho.API;
const cache = require('memory-cache');
const helpers = global.yoho.helpers;
const redis = global.yoho.redis;
const redis = require(`${utils}/redis`);
const co = require('bluebird').coroutine;
/**
... ... @@ -586,11 +586,10 @@ const getSearchKeywordData = (params, uid) => {
const getSearchKeywordDataById = (id, params, uid) => {
return redis.all([
['get', `golobal:yoho:seo:keywords:id:${id}`]
['get', `global:yoho:seo:keywords:id:${id}`]
]).then(redisData => {
if (!redisData[0]) {
return Promise.reject('get redis canpin keywords by id error!' +
`key: golobal:yoho:seo:keywords:id:${id} value: ${redisData[0]}`);
return false;
}
redisData = JSON.parse(redisData[0]);
... ...
... ... @@ -24,7 +24,7 @@ const newDetail = {
.then(result => {
let data = {};
if (result.data) {
if (_.get(result, 'data') && !_.isArray(result.data)) {
data = result.data;
if (data.storageSum > 0) {
data.storageSum = 1;
... ...
... ... @@ -16,6 +16,7 @@ class SimilarModel extends global.yoho.BaseModel {
product_skn: params.skn
},
param: {
cache: true,
code: 200
}
};
... ...
... ... @@ -124,6 +124,14 @@
<input id="product-coupon-switch" type="hidden" value="{{showCoupon}}">
<input id="bundleType" type="hidden" value="{{bundleType}}">
{{#if recommendKeywords}}
<div class="rec-word clearfix">
{{# recommendKeywords}}
<a href="{{url}}">{{keyword}}</a>
{{/ recommendKeywords}}
</div>
{{/if}}
{{> common/suspend-home}}
</div>
{{/ result}}
... ...
... ... @@ -5,7 +5,8 @@
*/
var express = require('express'),
path = require('path');
path = require('path'),
hbsEvent = require('../../config/hbsevent');
var app = express();
... ... @@ -25,7 +26,8 @@ app.use(global.yoho.hbs({
layoutsDir: doraemon,
partialsDir: [path.join(__dirname, 'views/partial')],
views: path.join(__dirname, 'views/action'),
helpers: global.yoho.helpers
helpers: global.yoho.helpers,
cb: hbsEvent.cb
}));
... ...
... ... @@ -46,6 +46,6 @@ router.get('/limitcodeColSize', help.limitcodeColSize);// 选择限购码颜色
router.get('/limitcodeIntro', help.limitcodeIntro);// 什么是限购码 (APP使用)
// 站点地图
router.get('/sitemap.xml', sitemap.siteMap);
router.get(/^\/sitemap(\d*)\.xml/, sitemap.siteMap);
module.exports = router;
... ...
... ... @@ -11,8 +11,8 @@ const isProduction = process.env.NODE_ENV === 'production';
const isTest = process.env.NODE_ENV === 'test';
const domains = {
api: 'http://api-test3.yohops.com:9999/',
service: 'http://service-test3.yohops.com:9999/',
api: 'http://api.yoho.cn/',
service: 'http://service.yoho.cn/',
singleApi: 'http://api-test3.yohops.com:9999/',
global: 'http://global-test-soa.yohops.com:9999',
liveApi: 'http://testapi.live.yohops.com:9999/',
... ... @@ -24,7 +24,7 @@ const domains = {
module.exports = {
app: 'h5',
appVersion: '6.0.0', // 调用api的版本
appVersion: '6.0.1', // 调用api的版本
port: 6001,
siteUrl: '//m.yohobuy.com',
assetUrl: '//127.0.0.1:5001',
... ...
const fs = require('fs');
let devHost = '127.0.0.1';
try {
let buf = fs.readFileSync('.devhost');
devHost = JSON.parse(buf.toString()).host;
} catch (e) {} //eslint-disable-line
module.exports = {
devHost,
port: 5001
};
... ...
/**
* hbs预编译回调事件
* @author: chenfeng<feng.chen@yoho.cn>
* @date: 2017/08/14
*/
const EventEmitter = require('events');
const event = new EventEmitter();
let hbsEvent = {
cbTick: 0,
cbComTick: 0,
event
};
Object.defineProperty(hbsEvent, 'cb', {
get() {
hbsEvent.cbTick++;
return this._cb;
},
set(val) {
this._cb = val;
}
});
hbsEvent.cb = () => {
hbsEvent.cbComTick++;
if (hbsEvent.cbTick <= hbsEvent.cbComTick) {
event.emit('hbs-complete');
}
};
module.exports = hbsEvent;
... ...
... ... @@ -13,7 +13,7 @@ module.exports = (req, res, next) => {
return res.json({
code: 400,
message: '抱歉,您暂未登录!',
redirect: '/passport/login'
redirect: '/signin.html'
});
} else if (req.yoho.isApp) {
return next({
... ...
'use strict';
const fs = require('fs');
let devHost = '127.0.0.1';
fs.readFile('.devhost', (err, buf)=> {
if (!err) {
devHost = JSON.parse(buf.toString()).host;
}
});
const devHost = require('../../config/devtools');
module.exports = () => {
return (req, res, next) => {
Object.assign(res.locals, {
devHost: devHost
});
Object.assign(res.locals, devHost);
next();
};
... ...
... ... @@ -51,9 +51,9 @@ module.exports = () => {
req.url = '/service/systemUpdate';
}
if (/^\/sitemap\.xml/.test(req.url)) {
if (/^\/sitemap(\d*)\.xml/.test(req.url)) {
// sitemap/sitemap.xml
req.url = '/service/sitemap.xml';
req.url = `/service${req.url}`;
}
if (/^\/coupon\/couponSend/.test(req.url)) {
... ...
const config = global.yoho.config;
const memcachedSession = require('yoho-express-session');
const _ = require('lodash');
const uuid = require('uuid');
const cookieSession = require('client-sessions');
const memcached = require('connect-memcached');
const MemcachedStore = memcached(memcachedSession);
/**
* 该中间件主要把 express-session 和 client-session 集中起来处理,如果 memcached 出错了,使用 cookie session
* @param opts.backSession cookieSession 的键名
* @returns {function(*=, *=, *)}
*/
function yohoSession(opts) {
return (req, res, next) => {
let notUseMemcached = _.get(req.app.locals.wap, 'session.removeMemcached', false);
opts.backSession = opts.backSession || 'session2';
if (req.session && !notUseMemcached) {
req.sessionError = false;
} else {
// 重建 session
res.emit('sessionError');
req.sessionError = true;
req.sessionID = uuid.v4();
req.session = new memcachedSession.Session(req, req[opts.backSession].sessionBack);
req.session.cookie = new memcachedSession.Cookie({
domain: 'yohobuy.com',
httpOnly: false
});
}
Object.defineProperty(req.session, 'reset', {
configurable: true,
enumerable: false,
value: function() {
req.session.destroy();
req[opts.backSession].reset();
},
writable: false
});
// 备份数据
req[opts.backSession].sessionBack = req.session;
next();
};
}
module.exports = (app) => {
app.use(memcachedSession({ // eslint-disable-line
proxy: true,
resave: false,
saveUninitialized: true,
unset: 'destroy',
secret: '82dd7e724f2c6870472c89dfa43cf48d',
name: 'yohobuy_session',
cookie: {
domain: 'yohobuy.com',
httpOnly: false
},
store: new MemcachedStore({
hosts: config.memcache.session,
prefix: 'yohobuy_session:',
reconnect: 5000,
timeout: 1000,
retries: 0
})
}));
app.use(cookieSession({ // eslint-disable-line
requestKey: 'session2',
cookieName: 'yohobuy_session_cookie',
secret: '82dd7e724f2c6870472c89dfa43cf48d',
cookie: {
domain: 'yohobuy.com',
ephemeral: true
}
}));
app.use(yohoSession({
backSession: 'session2'
}));
};
... ...
... ... @@ -12,6 +12,7 @@
<meta content="email=no" name="format-detection" />
<meta name="referrer" content="always">
{{# cononical}}
<meta name="applicable-device" content="mobile">
<link rel="cononical" href="{{currentHref}}">
{{/ cononical}}
{{#if miphtml}}
... ... @@ -40,7 +41,21 @@
</script>
{{/if}}
{{#unless devEnv}}
{{#if devEnv}}
{{#if localCss }}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/common.css?t={{startTime}}">
{{/if}}
{{#if isFeature}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/feature.css?t={{startTime}}">
{{else}}
{{#ifor localCss vue}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/{{module}}.{{page}}.css?t={{startTime}}">
{{^}}
<link rel="stylesheet" media="all" href="//{{devHost}}:5001/index.css?t={{startTime}}">
{{/ifor}}
{{/if}}
{{else}}
{{#if localCss }}
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/common.css?t={{startTime}}">
{{/if}}
... ... @@ -54,7 +69,7 @@
<link rel="stylesheet" media="all" href="//cdn.yoho.cn/m-yohobuy-node/{{version}}/index.css?t={{startTime}}">
{{/ifor}}
{{/if}}
{{/unless}}
{{/if}}
<link rel="apple-touch-icon-precomposed" href="http://static.yohobuy.com/m/v1/img/touch/apple-touch-icon-144x144-precomposed-new.png">
<link rel="apple-touch-startup-image" sizes="640x920" href="http://static.yohobuy.com/m/v1/img/startup/startup-retina.png" media="screen and (max-device-width: 480px) and (-webkit-min-device-pixel-ratio: 2)">
<link rel="apple-touch-startup-image" sizes="320x460" href="http://static.yohobuy.com/m/v1/img/startup/startup.png" media="screen and (max-device-width: 320)">
... ... @@ -103,14 +118,6 @@
<script>var STATIC_RESOURCE_PATH = '//{{devHost}}:5001';</script>
<script src="//{{devHost}}:5001/libs.js"></script>
{{!--开发环境的CSS需要hot reload, 所以使用 JS 方式加载--}}
{{#if localCss}}
<script src="//{{devHost}}:5001/common.js"></script>
{{else}}
<script src="//{{devHost}}:5001/index.js"></script>
{{/if}} {{#if isFeature}}
<script src="//{{devHost}}:5001/feature.js"></script>
{{/if}}
<script src="//{{devHost}}:5001/{{module}}.{{page}}.js"></script>
{{^}}
<script>var STATIC_RESOURCE_PATH = '//cdn.yoho.cn/m-yohobuy-node/assets';</script>
... ...
... ... @@ -16,13 +16,13 @@
<a href="{{url}}" class="nav-sub-right">{{text}}</a>
{{/shopPage}}
{{#currencyPage}}
<a href="/home/helpDetail?code=20151230-102233&caption=有货币介绍&name=有货币介绍" class="iconfont nav-home">&#xe639;</a>
<a href="/service/qaDetail?keyword=%E6%9C%89%E8%B4%A7%E5%B8%81&sonId=233" class="iconfont nav-home">&#xe639;</a>
{{/currencyPage}}
{{#currencyDetailPage}}
<a href="/home/helpDetail?code=20111130-152530&caption=如何使用有货币支付&name=如何使用有货币支付" class="iconfont nav-home">&#xe639;</a>
<a href="/service/qaDetail?keyword=%E6%9C%89%E8%B4%A7%E5%B8%81&sonId=227" class="iconfont nav-home">&#xe639;</a>
{{/currencyDetailPage}}
{{#installmentPage}}
<a href="/home/helpDetail?code=20151230-102233&caption=有货分期&name=有货分期" class="iconfont nav-home">&#xe639;</a>
<a href="/service/qaDetail?keyword=%E6%9C%89%E8%B4%A7%E5%88%86%E6%9C%9F&sonId=179" class="iconfont nav-home">&#xe639;</a>
{{/installmentPage}}
{{#navPhone}}
<a href="{{.}}" class="iconfont nav-home">&#xe641;</a>
... ...
{
"name": "m-yohobuy-node",
"version": "6.0.0",
"version": "6.0.12",
"private": true,
"description": "A New Yohobuy Project With Express",
"repository": {
... ... @@ -10,8 +10,9 @@
"scripts": {
"start": "NODE_ENV=\"production\" node app.js",
"dev": "nodemon -e js,hbs -i public/ app.js",
"static": "webpack-dev-server --config ./public/build/webpack.dev.config.js",
"build": "webpack --config ./public/build/webpack.prod.config.js",
"static": "node ./public/build/dev-server.js",
"build:dll": "webpack --config ./public/build/webpack.dll.indexcss.config.js",
"build": "webpack --config ./public/build/webpack.dll.indexcss.config.js --config ./public/build/webpack.prod.config.js",
"debug": "DEBUG=\"express:*\" nodemon -e js,hbs -i public/ app.js",
"lint-js": "lint-js",
"lint-css": "lint-css",
... ... @@ -49,7 +50,7 @@
"connect-multiparty": "^2.0.0",
"cookie-parser": "^1.4.3",
"cssnano": "^3.10.0",
"express": "^4.15.3",
"express": "^4.15.4",
"fast-safe-stringify": "^1.2.0",
"feed": "^1.1.0",
"geetest": "^4.1.2",
... ... @@ -63,7 +64,7 @@
"passport-sina": "^0.1.0",
"passport-strategy": "^1.0.0",
"passport-weixin": "^0.1.0",
"redis": "^2.7.1",
"redis": "^2.8.0",
"request": "^2.81.0",
"request-promise": "^4.2.1",
"semver": "^5.4.1",
... ... @@ -72,7 +73,7 @@
"xml2js": "^0.4.17",
"yoho-express-session": "^2.0.0",
"yoho-md5": "^2.0.0",
"yoho-node-lib": "=0.2.28",
"yoho-node-lib": "=0.2.29",
"yoho-zookeeper": "^1.0.8"
},
"devDependencies": {
... ... @@ -82,15 +83,18 @@
"babel-polyfill": "^6.23.0",
"babel-preset-env": "^1.6.0",
"css-loader": "^0.28.4",
"eslint": "^4.3.0",
"eslint": "^4.4.1",
"eslint-config-yoho": "^1.0.9",
"eslint-loader": "^1.9.0",
"eslint-plugin-html": "^3.1.1",
"extract-text-webpack-plugin": "^3.0.0",
"friendly-errors-webpack-plugin": "^1.6.1",
"handlebars-loader": "^1.5.0",
"happypack": "^3.1.0",
"husky": "^0.14.3",
"ignore-file-loader": "^1.0.0",
"nodemon": "^1.11.0",
"opn": "^5.1.0",
"postcss-assets": "^4.2.0",
"postcss-calc": "^6.0.0",
"postcss-center": "^1.0.0",
... ... @@ -115,10 +119,14 @@
"vue": "^2.4.2",
"vue-infinite-scroll": "^2.0.1",
"vue-lazyload": "^1.0.6",
"vue-loader": "^13.0.2",
"vue-loader": "^13.0.4",
"vue-template-compiler": "^2.4.2",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"webpack": "^3.5.2",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-middleware": "^1.12.0",
"webpack-dev-server": "^2.7.1",
"webpack-hot-middleware": "^2.18.2",
"webpack-merge": "^4.1.0",
"webpack-uglify-parallel": "^0.1.3",
"yoho-cookie": "^1.2.0",
"yoho-fastclick": "^1.0.6",
... ...
const hotClient = require('webpack-hot-middleware/client?dynamicPublicPath=true&path=__webpack_hmr&noInfo=true&reload=true'); // eslint-disable-line
hotClient.subscribeAll(event => {
if (event.action === 'built') {
document.querySelectorAll('link[href][rel=stylesheet]').forEach((link) => {
fetch(link.href).then((res) => {
res.text().then(text => {
let head = document.getElementsByTagName('head')[0];
let style;
style = document.getElementById(link.href);
if (!style) {
style = document.createElement('style');
style.type = 'text/css';
style.id = link.href;
style.appendChild(document.createTextNode(text));
} else {
style.textContent = text;
}
head.appendChild(style);
});
});
});
}
});
... ...
const express = require('express');
const webpack = require('webpack');
const compression = require('compression');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const webpackConfig = require('./webpack.dev.config.js');
const path = require('path');
const compiler = webpack(webpackConfig);
const devMiddleware = webpackDevMiddleware(compiler, {
publicPath: webpackConfig.output.publicPath,
quiet: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
});
const hotMiddleware = webpackHotMiddleware(compiler, {
log: () => {}
});
const app = express();
app.use(devMiddleware);
app.use(hotMiddleware);
app.use((req, res, next) => {
res.set('Access-Control-Allow-Origin', '*');
next();
});
app.use('/',
express.static(path.join(__dirname, '../')),
express.static(path.join(__dirname, './bundle/')),
express.static(path.join(__dirname, './dll/')));
app.use('/event', (req, res) => {
if (req.query.action === 'reload') {
hotMiddleware.publish({
action: 'reload'
});
}
res.json({
action: req.query.action,
message: 'ok'
});
});
app.use(compression());
app.listen(5001, () => {
console.log('dev start 5001');
});
... ...
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const postcssConfig = require('./postcss.config.js');
const cssLoader = (env, type) => {
let loaders = [{
loader: 'css-loader',
options: {
url: false,
sourceMap: env === 'dev'
}
}];
if (type === 'css') {
loaders.push({
loader: 'postcss-loader',
options: {
plugins: postcssConfig.postcssPlugin(env),
parser: 'postcss-scss'
}
});
}
// if (env === 'dev') {
// loaders.unshift({
// loader: 'style-loader'
// });
// return loaders;
// }
return ExtractTextPlugin.extract({
fallback: type === 'css' ? 'style-loader' : 'vue-style-loader',
use: loaders
});
};
const hbsLoader = {
loader: 'handlebars-loader',
options: {
helperDirs: [
path.join(__dirname, '../js/common/helpers')
],
partialDirs: [
path.join(__dirname, '../../doraemon/views/partial')
]
}
};
module.exports = {
cssLoader,
hbsLoader
};
... ...
... ... @@ -12,61 +12,17 @@ const shelljs = require('shelljs');
const _ = require('lodash');
const webpack = require('webpack');
const HappyPack = require('happypack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { cssLoader, hbsLoader } = require('./utils.js');
const postcssConfig = require('./postcss.config.js');
const happyThreadPool = HappyPack.ThreadPool({ // eslint-disable-line
size: os.cpus().length
});
const hbsLoader = {
loader: 'handlebars-loader',
options: {
helperDirs: [
path.join(__dirname, '../js/common/helpers')
],
partialDirs: [
path.join(__dirname, '../../doraemon/views/partial')
]
}
};
const cssLoader = (env, type) => {
let loaders = [{
loader: 'css-loader',
options: {
url: false,
sourceMap: env === 'dev'
}
}];
if (type === 'css') {
loaders.push({
loader: 'postcss-loader',
options: {
plugins: postcssConfig.postcssPlugin(env),
parser: 'postcss-scss'
}
});
}
if (env === 'dev') {
loaders.unshift({
loader: 'style-loader'
});
return loaders;
}
return ExtractTextPlugin.extract({
fallback: type === 'css' ? 'style-loader' : 'vue-style-loader',
use: loaders
});
};
const getEntries = () => {
const entries = {
libs: ['babel-polyfill', 'yoho-jquery', path.join(__dirname, '../js/global.js')],
index: path.join(__dirname, '../scss/index.css'),
common: path.join(__dirname, '../scss/common.css'),
feature: path.join(__dirname, '../scss/feature.css')
};
... ...
'use strict';
const path = require('path');
const _ = require('lodash');
const webpack = require('webpack');
const StyleLintPlugin = require('stylelint-webpack-plugin');
const path = require('path');
const merge = require('webpack-merge');
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const devInfo = require('./dev-info.js');
let baseConfig = require('./webpack.base.config.js');
baseConfig = baseConfig('dev');
_.mergeWith(baseConfig, {
devtool: '#inline-source-map',
Object.keys(baseConfig.entry).forEach(function(name) {
baseConfig.entry[name] = [path.join(__dirname, './dev-client.js')].concat(baseConfig.entry[name]);
});
module.exports = merge(baseConfig, {
devtool: '#cheap-module-source-map',
output: {
publicPath: devInfo.publicPath
},
module: {
rules: [{
enforce: 'pre',
test: /(\.js|\.vue)$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
cache: true,
configFile: './.eslintrc',
formatter: require('eslint/lib/formatters/codeframe')
}
}]
},
devServer: {
host: devInfo.host,
port: devInfo.port,
publicPath: devInfo.publicPath,
contentBase: [path.join(__dirname, './bundle/'), path.join(__dirname, '../')],
hot: true,
inline: true,
compress: true,
stats: {
colors: true,
children: false,
chunks: false,
assetsSort: 'size',
},
headers: {
'Access-Control-Allow-Origin': '*'
}
},
plugins: [
new StyleLintPlugin({
files: ['public/scss/**/*.css', 'public/vue/**/*.vue'],
syntax: 'scss'
}),
new webpack.HotModuleReplacementPlugin()
new ExtractTextPlugin('[name].css'),
new webpack.HotModuleReplacementPlugin(),
new FriendlyErrorsPlugin(),
]
}, function customizer(objValue, srcValue) {
if (_.isArray(objValue)) {
return objValue.concat(srcValue);
}
});
delete baseConfig.extends;
module.exports = baseConfig;
... ...
const webpack = require('webpack');
const path = require('path');
const shelljs = require('shelljs');
const {cssLoader} = require('./utils.js');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const config = require('../../package.json');
const distDir = path.join(__dirname, `../dist/${config.name}/${config.version}`);
// cope img font
shelljs.mkdir('-p', distDir);
shelljs.cp('-R', path.join(__dirname, '../img/'), distDir);
shelljs.cp('-R', path.join(__dirname, '../font/'), distDir);
let webpackConfig = {
entry: {
index: [path.join(__dirname, '../scss/index.css')]
},
output: {
path: path.join(__dirname, './dll'), // absolute path
filename: '[name].js'
},
module: {
rules: [{
test: /\.css$/,
use: cssLoader('pro', 'css')
}]
},
plugins: [
new ExtractTextPlugin('[name].css'),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
})
]
};
module.exports = webpackConfig;
... ...
... ... @@ -3,8 +3,8 @@
const os = require('os');
const path = require('path');
const shelljs = require('shelljs');
const _ = require('lodash');
const webpack = require('webpack');
const merge = require('webpack-merge');
const UglifyJsParallelPlugin = require('webpack-uglify-parallel');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const config = require('../../package.json');
... ... @@ -15,10 +15,11 @@ let baseConfig = require('./webpack.base.config.js');
shelljs.mkdir('-p', distDir);
shelljs.cp('-R', path.join(__dirname, '../img/'), distDir);
shelljs.cp('-R', path.join(__dirname, '../font/'), distDir);
shelljs.cp('-R', path.join(__dirname, './dll/*'), distDir);
baseConfig = baseConfig('pro');
_.mergeWith(baseConfig, {
module.exports = merge(baseConfig, {
output: {
path: distDir
},
... ... @@ -37,10 +38,4 @@ _.mergeWith(baseConfig, {
comments: false
})
]
}, function customizer(objValue, srcValue) {
if (_.isArray(objValue)) {
return objValue.concat(srcValue);
}
});
module.exports = baseConfig;
... ...
No preview for this file type
... ... @@ -336,6 +336,9 @@ t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-
<glyph glyph-name="back1" unicode="&#59182;" d="M525.301861 836.425505C269.200475 836.425505 60.831683 628.07699 60.831683 371.955327S269.200475-92.514851 525.301861-92.514851s464.470178 208.368792 464.470179 464.470178S781.423525 836.425505 525.301861 836.425505z m0-910.731406c-246.064158 0-446.261228 200.176792-446.261227 446.261228 0 246.064158 200.197069 446.261228 446.261227 446.261227 246.084436 0 446.261228-200.197069 446.261228-446.261227s-200.176792-446.261228-446.261228-446.261228zM663.146455 593.301545a27.313426 27.313426 0 0 1-38.648396 38.648396L392.668515 400.100119l-0.669149-0.669149a27.313426 27.313426 0 0 1 0.669149-38.628119c0.547485-0.527208 1.277465-0.709703 1.865505-1.196356l229.964039-229.903208a27.313426 27.313426 0 0 1 38.628119 38.54701l-212.505346 212.525624 212.525623 212.525624z" horiz-adv-x="1024" />
<glyph glyph-name="sanjiao2-center-view-copy" unicode="&#59183;" d="M511.999488 140.58653800000013L72.8374 755.413462 951.1626 755.413462Z" horiz-adv-x="1024" />
</font>
... ...
No preview for this file type
No preview for this file type
{{!--图片验证--}}
<div class="img-check">
<div class="img-check-header">
<span>请将下列图片点击翻转至正确方向</span>
<span>请将下列图片点击翻转至正向朝上</span>
<a class="img-check-refresh">换一批</a>
</div>
<div class="img-check-main">
... ...
{{# cartInfo}}
<div class="cart-bar">
<div class="cart-bar{{#if storeGood}} store-good{{/if}}">
{{#unless @root.wap.common.removeCartCount}}
<input type="hidden" id="remove-cart-count" value="1">
{{/unless}}
... ... @@ -14,10 +14,11 @@
<div class="iconfont">&#xe705;</div>
<div class="tip">品牌店铺</div>
</a>
<a href="javascript:;" class="new-foot-ico fav">
<a href="javascript:;" class="new-foot-ico fav like-btn-c">
<div id="likeBtn" class="favorite iconfont {{#if @root.isCollect}}liked{{/if}}">&#xe605;</div>
<div class="tip{{#unless @root.isCollect}} opa{{/unless}}">{{#if @root.isCollect}}已收藏{{else}}收藏{{/if}}</div>
</a>
<span class="btn-c">
{{#if addToCartUrl}}
<a id="addtoCart" href="javascript:;" class="addto-cart add-to-cart-url">加入购物车</a>
{{/if}}
... ... @@ -48,7 +49,7 @@
{{#if noLimitCode}}
<a id="noLimitCode" href="javascript:;" class="sold-out limit">立即购买</a>
{{/if}}
</span>
<input type="hidden" id="limitCodeUrl" name="limitCodeUrl" value="{{limitCodeUrl}}">
<input type="hidden" id="limitProductPay" name="limitProductPay" value="{{limitProductPay}}">
{{#if limitProductCode}}
... ...
'use strict';
const yoho = require('yoho-app');
let tip = require('plugin/tip');
import {
Controller
} from 'yoho-mvc';
... ... @@ -25,13 +27,7 @@ class FreeMailIndexController extends Controller {
this.freeMailModel.receiveVerify().then(result => {
if (result.code === 200) {
if (yoho.isApp) {
yoho.goH5('http://m.yohobuy.com/activity/free-mail/list', JSON.stringify({
action: 'go.h5',
params: {
islogin: 'N',
url: 'http://m.yohobuy.com/activity/free-mail/list'
}
}));
yoho.goH5(location.protocol + '//m.yohobuy.com/activity/free-mail/list');
} else {
location.href = '//m.yohobuy.com/activity/free-mail/list';
}
... ... @@ -47,6 +43,8 @@ class FreeMailIndexController extends Controller {
}
this.receiveView.popHide();
}).catch(() => {
tip.show('服务异常,请稍后重试');
});
}
}
... ...
... ... @@ -11,7 +11,7 @@ class FreeMail {
receiveVerify() {
return http({
type: 'GET',
url: '/activity/free-mail/verify'
url: location.protocol + '//m.yohobuy.com/activity/free-mail/verify'
});
}
}
... ...
... ... @@ -9,8 +9,8 @@ class IndexView extends View {
this.receiveBtn = $('.receive-btn');
this.tipClose = $('.close');
this.on('touchend touchcancel', '.receive-btn', this.btnClick.bind(this));
this.on('touchend touchcancel', '.close', this.tipClickHide.bind(this));
this.on('click', '.receive-btn', this.btnClick.bind(this));
this.on('click', '.close', this.tipClickHide.bind(this));
}
/**
... ...
... ... @@ -30,13 +30,7 @@ class FreeMailIndexController extends Controller {
setTimeout(function() {
if (yoho.isApp) {
yoho.goH5('http://m.yohobuy.com/home/coupons', JSON.stringify({
action: 'go.coupon',
params: {
islogin: 'N',
url: 'http://m.yohobuy.com/home/coupons'
}
}));
yoho.goH5(location.protocol + '//m.yohobuy.com/home/coupons');
} else {
location.href = '//m.yohobuy.com/home/coupons';
}
... ... @@ -44,6 +38,8 @@ class FreeMailIndexController extends Controller {
} else {
tip.show(result.message);
}
}).catch(() => {
tip.show('服务异常,请稍后重试');
});
}
}
... ...
... ... @@ -11,7 +11,7 @@ class FreeMailList {
receiveCoupon() {
return http({
type: 'GET',
url: '/activity/free-mail/verifyCoupon'
url: location.protocol + '//m.yohobuy.com/activity/free-mail/verifyCoupon'
});
}
}
... ...
... ... @@ -8,7 +8,7 @@ class ListView extends View {
this.receiveBtn = $('.receive-btn');
this.on('touchend touchcancel', '.receive-btn', this.receiveClick.bind(this));
this.on('click', '.receive-btn', this.receiveClick.bind(this));
}
/**
... ...
... ... @@ -343,6 +343,10 @@ if (!orderInfo('address_id')) {
}
$('.delivery-id').on('touchend', 'li', function(event) {
if ($(this).hasClass('no-support')) {
return false;
}
orderInfo('delivery_way', $(this).data('id'));
// 实付金额发生变化,使用有货币为0
... ... @@ -448,6 +452,10 @@ $subBlock.on('touchstart', 'li', function() {
return true;
}
if ($(this).hasClass('no-support')) {
return false;
}
$.each($(this).parents('ul').find('i'), function() {
$(this).parents('ul').find('i').removeClass('icon-cb-radio').addClass('icon-radio');
});
... ...
... ... @@ -324,6 +324,10 @@ if (!orderInfo('addressId')) {
}
$('.delivery-id').on('touchend', 'li', function(event) {
if ($(this).hasClass('no-support')) {
return false;
}
orderInfo('deliveryId', $(this).data('id'));
// 实付金额发生变化,使用有货币为0
... ... @@ -425,11 +429,16 @@ $('.dispatch').on('touchend', 'h3', function() {
});
$subBlock.on('touchstart', 'li', function() {
// 送货时间提示语li,不响应事件
if ($(this).hasClass('dispatch-time-info')) {
return true;
}
if ($(this).hasClass('no-support')) {
return false;
}
$.each($(this).parents('ul').find('i'), function() {
$(this).parents('ul').find('i').removeClass('icon-cb-radio').addClass('icon-radio');
});
... ...
... ... @@ -485,10 +485,11 @@ class ChosePanel {
}
$chosePanel.find('.left-num').text(numText);
$chosePanel.find('.size-info').text(selectSku.sizeInfo).removeClass('hide');
$chosePanel.find('.size-rec').text(selectSku.sizeRec).removeClass('hide');
$chosePanel.find('.size-rec').text(selectSku.sizeRec || '').removeClass('hide');
} else {
$chosePanel.find('.left-num').text('');
$chosePanel.find('.size-info').text('').addClass('hide');
$chosePanel.find('.size-rec').text('').addClass('hide');
}
}
... ...
... ... @@ -42,21 +42,24 @@ function point(type, trend) {
}
$('.set-world').click(function() {
let trendWord = $('.trend-world-area').val();
$.ajax({
type: 'GET',
url: '/activity/set-trend-world',
data: {
trendWord: $('.trend-world-area').val()
trendWord: trendWord
},
success: function(result) {
tip.show(result.message);
if (result.code === 200) {
let copyUrl = `//m.yohobuy.com/?openby:yohobuy={"action":"go.copy","params":{"text":"${trendWord}","message":"复制成功"}}`; // eslint-disable-line
point(1, $('.trend-world-area').val());
$('.trend-code').html($('.trend-world-area').val());
$('.copy.button').eq(0).attr('href', copyUrl);
setTimeout(function() {
$('.set-trend-world').hide();
... ...
... ... @@ -34,7 +34,9 @@ if ($loadMoreInfo.length > 0) {
$noMore = $loadMoreInfo.children('.no-more');
}
info.initSwiper(curType);
if ($('.swiper-container').length > 0) {
info.initSwiper(curType);
}
info.initInfosEvt($infoList);
... ...
require('passport/back-email-new.page.css');
... ...
require('passport/back-email-success-new.page.css');
... ...
require('passport/back-mobile-new.page.css');
... ...
... ... @@ -89,10 +89,10 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
itime = setInterval(function() {
if (count === 0) {
$captchaTip.text('重新发送').removeClass('disable');
$captchaTip.text('重新获取').removeClass('disable');
clearInterval(itime);
} else {
$captchaTip.text('重新发送 (' + count-- + '秒)');
$captchaTip.text('重新获取 (' + count-- + '秒)');
window.setCookie('count', count);
if (during && parseInt(during, 10) !== 0) {
... ... @@ -112,7 +112,7 @@ module.exports = function(useInRegister, useForBind, useForRelate) {
}
});
// 重新发送验证码
// 重新获取验证码
$captchaTip.on('touchstart', function() {
if ($captchaTip.hasClass('disable')) {
return;
... ...
require('passport/international-new.page.css');
const $ = require('yoho-jquery');
const InternationalNew = require('./login/international-new.js');
$(() => {
new InternationalNew();
});
... ...
require('passport/login-new.page.css');
const $ = require('yoho-jquery');
const Login = require('./login/login-new');
$(() => {
new Login();
});
... ...
import $ from 'yoho-jquery';
import tip from 'plugin/tip';
import Page from 'yoho-page';
import api from '../api';
import Validate from 'plugin/validata';
const showErrTip = tip.show;
const trim = $.trim;
const $captcha = $('#js-img-check');
const useVerify = $captcha.data('userverify'); // 170406 是否使用验证
const validate = new Validate($captcha, {
useREM: {
rootFontSize: 40,
picWidth: 150
}
});
class InternationalNew extends Page {
constructor() {
super();
this.selector = {
countryCodeSelector: $('#countryCodeSelector'),
clearMobile: $('#clearMobile'),
mobileInput: $('input[name=mobile]'),
passwordInput: $('input[name=password]'),
passwordEyeIcon: $('#passwordEyeIcon'),
eyeClose: $('.eye-close'),
eyeOpen: $('.eye-open'),
internationalLoginBtn: $('#internationalLoginBtn')
};
this.init();
}
init() {
if ($captcha.data('userverify')) {
validate.init();
}
this.bindEvents();
}
bindEvents() {
this.selector.clearMobile.on('click', this.clearMobile.bind(this));
this.selector.passwordEyeIcon.on('click', this.passwordShowStatus.bind(this));
this.selector.internationalLoginBtn.on('click', this.internationalLogin.bind(this));
this.selector.mobileInput.bind('input', this.changeLoginBtnStatus.bind(this));
this.selector.passwordInput.bind('input', this.changeLoginBtnStatus.bind(this));
}
/**
* 改变登录按钮的状态
*/
changeLoginBtnStatus() {
// 清除手机号按钮
if (this.selector.mobileInput.val()) {
this.selector.clearMobile.removeClass('hide');
} else {
this.selector.clearMobile.addClass('hide');
}
// 登录按钮
if (this.selector.mobileInput.val() && this.selector.passwordInput.val()) {
this.selector.internationalLoginBtn.addClass('active');
} else {
this.selector.internationalLoginBtn.removeClass('active');
}
}
/**
* 登录操作处理
*/
internationalLogin() {
let pn = trim(this.selector.mobileInput.val()),
areaCode = this.selector.countryCodeSelector.val(),
pwd = trim(this.selector.passwordInput.val());
if (!this.selector.internationalLoginBtn.hasClass('active')) {
return;
}
if ((api.phoneRegx[areaCode].test(pn) || areaCode !== '+86') && api.pwdValidate(pwd)) {
let params = {
areaCode: areaCode.replace('+', ''),
account: pn,
password: pwd
};
if (useVerify) {
validate.getResults().then((result) => {
this.selector.internationalLoginBtn.text('正在登录...').addClass('disable');
$.extend(params, result);
this.postInternationalLogin(params);
});
} else {
this.postInternationalLogin(params);
}
} else {
showErrTip('账号或密码有错误,请重新输入');
this.selector.internationalLoginBtn.text('登录').addClass('disable');
}
}
/**
* 发送国际账号登录请求
*/
postInternationalLogin(params) {
this.ajax({
type: 'POST',
url: '/passport/login/auth',
data: params
}).then(data => {
let res;
validate && validate.type === 2 && validate.refresh();
if (data.code === 200) {
res = data.data;
showErrTip('登录成功');
// 3秒后强制跳转
setTimeout(() => {
location.href = res.href;
}, 1500);
this.selector.internationalLoginBtn.text('登录成功');
showErrTip('登录成功');
} else {
$captcha.data('userverify', data.captchaShow);
if (data.captchaShow) {
if (validate.atWorking) {
((data.changeCaptcha && validate.type !== 2) && validate.refresh());
} else {
validate.init();
}
}
showErrTip(data.message);
this.resetForm();
}
});
}
/**
* 重置表单
*/
resetForm() {
this.selector.passwordInput.val('').focus();
this.selector.internationalLoginBtn.text('登录').removeClass('active');
}
/**
* 隐藏显示密码
*/
passwordShowStatus() {
if (this.selector.eyeOpen.hasClass('hide')) {
this.selector.passwordInput.attr('type', 'text');
this.selector.eyeClose.addClass('hide');
this.selector.eyeOpen.removeClass('hide');
} else {
this.selector.passwordInput.attr('type', 'password');
this.selector.eyeOpen.addClass('hide');
this.selector.eyeClose.removeClass('hide');
}
}
/**
* 清除输入的手机号
*/
clearMobile() {
this.selector.mobileInput.val('');
this.selector.clearMobile.addClass('hide');
}
}
module.exports = InternationalNew;
... ...
const $ = require('yoho-jquery');
const $captcha = $('#js-img-check');
const tip = require('plugin/tip');
const Modal2 = require('plugin/modal2');
const showErrTip = tip.show;
const api = require('../api');
const trim = $.trim;
const Validate = require('plugin/validata');
const validate = new Validate($captcha, {
useREM: {
rootFontSize: 40,
picWidth: 150
}
});
class Login {
constructor() {
this.view = {
loginBtn: $('#loginBtn'),
clearUsrname: $('#clearUsrname'),
usernameInput: $('input[name=username]'),
passwordInput: $('input[name=password]'),
passwordEyeIcon: $('#passwordEyeIcon'),
eyeClose: $('.eye-close'),
eyeOpen: $('.eye-open'),
getPswrdBtn: $('#getPswrdBtn'),
getPasswordBox: $('.get-password-box'),
showYohoFamilyTip: $('#showYohoFamilyTip')
};
this.view.loginBtn.on('click', this.login.bind(this));
this.view.clearUsrname.on('click', this.clearUsrname.bind(this));
this.view.passwordEyeIcon.on('click', this.passwordShowStatus.bind(this));
this.view.getPswrdBtn.on('click', this.showGetPasswordBox.bind(this));
this.view.getPasswordBox.on('click', this.hiddenGetPasswordBox.bind(this));
this.view.showYohoFamilyTip.on('click', this.showYohoFamilyTip.bind(this));
this.view.usernameInput.bind('input', this.changeBtnStatus.bind(this));
this.view.passwordInput.bind('input', this.changeBtnStatus.bind(this));
if ($captcha.data('userverify')) {
validate.init();
}
}
/**
* 输入监听,改变按钮状态
*/
changeBtnStatus() {
// 清除按钮
if (this.view.usernameInput.val()) {
this.view.clearUsrname.removeClass('hide');
} else {
this.view.clearUsrname.addClass('hide');
}
// 登录按钮
if (this.view.usernameInput.val() && this.view.passwordInput.val()) {
this.view.loginBtn.removeClass('disable');
} else {
this.view.loginBtn.addClass('disable');
}
}
/**
* 展示弹窗
*/
showYohoFamilyTip() {
Modal2.alert('Yoho!Family账号可登录Yoho!Buy有货、Yoho!Now、Mars及SHOW', 'Yoho!Family');
}
/**
* 登录
*/
login() {
if (this.view.loginBtn.hasClass('disable')) {
return;
}
let acc = trim(this.view.usernameInput.val()),
pwd = trim(this.view.passwordInput.val());
// 验证账号(数字或者邮箱)和密码合理性
if ((/^[0-9]+$/.test(acc) || api.emailRegx.test(acc)) && api.pwdValidate(pwd)) {
let params = {
account: acc,
password: pwd,
isskip: window.queryString.isskip
};
if ($captcha.data('userverify')) {
validate.getResults().then((result) => {
this.view.loginBtn.text('正在登录...').addClass('disable');
$.extend(params, result);
// auth
this.loginAuth(params, acc);
}, () => {});
} else {
this.loginAuth(params, acc);
}
} else {
showErrTip('账号或密码有错误,请重新输入');
this.view.loginBtn.text('登录').removeClass('disable');
}
}
loginAuth(params, acc) {
$.ajax({
type: 'POST',
url: '/passport/login/auth',
data: params,
success: (data) => {
let res,
LOGI_TYPE;
if (acc.indexOf('@') > 0) {
LOGI_TYPE = 8;
} else {
LOGI_TYPE = 5;
}
if (window._yas && window._yas.sendCustomInfo) {
window._yas.sendCustomInfo({
op: 'YB_MY_LOGIN_C',
param: JSON.stringify({
C_ID: window._ChannelVary[window.cookie('_Channel')],
LOGI_TYPE: LOGI_TYPE
})
}, true);
}
validate && validate.type === 2 && validate.refresh();
if (data.code === 200) {
res = data.data;
showErrTip('登录成功');
location.href = res.href;
this.view.loginBtn.text('登录成功');
} else if (data.code === 4189) {
localStorage.loginJumpUrl = $('#account').val();
localStorage.loginJump = 'true';
location.href = data.url;
} else if (data.code === 510) {
location.href = data.url;
} else {
$captcha.data('userverify', data.captchaShow);
if (data.captchaShow) {
if (validate.atWorking) {
((data.changeCaptcha && validate.type !== 2) && validate.refresh());
} else {
validate.init();
}
}
showErrTip(data.message);
this.resetForm();
}
return data;
},
error: () => {
showErrTip('网络断开连接啦~');
validate && validate.refresh();
},
complete: () => {
this.view.loginBtn.text('登录').removeClass('disable');
}
});
}
resetForm() {
this.view.loginBtn.text('登录').addClass('disable');
}
/**
* 清除输入的用户名
*/
clearUsrname() {
this.view.usernameInput.val('');
this.view.clearUsrname.addClass('hide');
}
/**
* 隐藏显示密码
*/
passwordShowStatus() {
if (this.view.eyeOpen.hasClass('hide')) {
this.view.passwordInput.attr('type', 'text');
this.view.eyeClose.addClass('hide');
this.view.eyeOpen.removeClass('hide');
} else {
this.view.passwordInput.attr('type', 'password');
this.view.eyeOpen.addClass('hide');
this.view.eyeClose.removeClass('hide');
}
}
/**
* 显示找回密码遮罩
*/
showGetPasswordBox() {
this.view.getPasswordBox.removeClass('hide');
}
/**
* 隐藏找回密码遮罩
*/
hiddenGetPasswordBox() {
this.view.getPasswordBox.addClass('hide');
return false;
}
}
module.exports = Login;
... ...
require('passport/reg-new.page.css');
const $ = require('yoho-jquery');
const RegisterNew = require('./register/register-new');
$(() => {
new RegisterNew();
});
... ...
const $ = require('yoho-jquery');
const $captcha = $('#js-img-check');
const tip = require('plugin/tip');
const showErrTip = tip.show;
const api = require('../api');
const validatePWD = require('../password-check');
const Validate = require('plugin/validata');
const validate = new Validate($captcha, {
useREM: {
rootFontSize: 40,
picWidth: 150
}
});
class RegisterNew {
constructor() {
this.view = {
clearMobile: $('#clearMobile'),
countryCodeBtn: $('#countryCodeBtn'),
countryCodeSelector: $('#countryCodeSelector'),
getVerifyCodeBtn: $('#getVerifyCodeBtn'),
regBtn: $('#regBtn'),
mobileInput: $('input[name=mobile]'),
verifyCodeInput: $('input[name=verifyCode]'),
inviteCodeInput: $('input[name=inviteCode]'),
passwordInput: $('input[name=password]'),
passwordEyeIcon: $('#passwordEyeIcon'),
eyeClose: $('.eye-close'),
eyeOpen: $('.eye-open'),
tokenInput: $('input[name=token]')
};
validate.init();
this.view.clearMobile.on('click', this.clearMobile.bind(this));
this.view.regBtn.on('click', this.register.bind(this));
this.view.mobileInput.bind('input', this.changeBtnStatus.bind(this));
this.view.verifyCodeInput.bind('input', this.changeBtnStatus.bind(this));
this.view.passwordInput.bind('input', this.changeBtnStatus.bind(this));
this.view.passwordEyeIcon.on('click', this.passwordShowStatus.bind(this));
this.view.getVerifyCodeBtn.on('click', this.getVerifyCode.bind(this));
}
/**
* 清除输入的手机号
*/
clearMobile() {
this.view.mobileInput.val('');
this.view.clearMobile.addClass('hide');
}
/**
* 隐藏显示密码
*/
passwordShowStatus() {
if (this.view.eyeOpen.hasClass('hide')) {
this.view.passwordInput.attr('type', 'text');
this.view.eyeClose.addClass('hide');
this.view.eyeOpen.removeClass('hide');
} else {
this.view.passwordInput.attr('type', 'password');
this.view.eyeOpen.addClass('hide');
this.view.eyeClose.removeClass('hide');
}
}
/**
* 获取验证码倒计时
*/
countDown(during) {
let count = during || 59;
let itime;
this.view.getVerifyCodeBtn.removeClass('active');
itime = setInterval(() => {
if (count === 0) {
this.view.getVerifyCodeBtn.text('重新获取').addClass('active');
clearInterval(itime);
} else {
this.view.getVerifyCodeBtn.text('重新获取 (' + count-- + '秒)');
window.setCookie('count', count);
if (during && parseInt(during, 10) !== 0) {
this.view.getVerifyCodeBtn.removeClass('active');
}
}
}, 1000);
}
/**
* 输入监听,改变按钮状态
*/
changeBtnStatus() {
// 获取验证码按钮
if (this.view.mobileInput.val()) {
this.view.getVerifyCodeBtn.addClass('active');
this.view.clearMobile.removeClass('hide');
} else {
this.view.getVerifyCodeBtn.removeClass('active');
this.view.clearMobile.addClass('hide');
}
// 登录按钮
if (this.view.mobileInput.val() &&
this.view.passwordInput.val() &&
this.view.verifyCodeInput.val()) {
this.view.regBtn.addClass('active');
} else {
this.view.regBtn.removeClass('active');
}
}
/**
* 注册动作处理
*/
register() {
let password = this.view.passwordInput.val();
if (!this.view.regBtn.hasClass('active')) {
return;
}
let validateResult = validatePWD(password, result => {
if (!result.valid) {
showErrTip(result.msg);
}
return result.valid;
});
if (!validateResult) {
return;
}
this.postRegister();
}
/**
* 提交注册请求
*/
postRegister() {
if (this.view.regBtn.hasClass('active')) {
this.view.regBtn.removeClass('active');
let postData = {
password: $.trim(this.view.passwordInput.val()),
phoneNum: this.view.mobileInput.val(),
areaCode: this.view.countryCodeSelector.val(),
smsCode: this.view.verifyCodeInput.val(),
token: this.view.tokenInput.val(),
inviteCode: this.view.inviteCodeInput.val()
};
return $.ajax({
type: 'POST',
url: '/passport/register-new',
data: postData,
success: (data) => {
let res = data.data;
if (data.code === 200) {
showErrTip('注册成功');
window.setCookie('refer', res.session);
window.setCookie('msgDelivery', res.msgDelivery, {expires: 1, path: '/' });
// 统计代码:用于统计从哪个渠道注册成功的
if (window._yas && window._yas.sendCustomInfo) {
window._yas.sendCustomInfo({
op: 'YB_REGISTER_SUCCESS_L',
ud: window.getUid(),
param: JSON.stringify({
C_ID: window._ChannelVary[window.cookie('_Channel')] || 1,
UNION_TYPE: window.queryString.union_type || window.cookie('unionTypeYas') || false
})
}, true);
}
let _fxcmd = window._fxcmd || [];
_fxcmd.push(['trackEvent', 'event', 'reg', '注册', '1']);
setTimeout(function() {
location.href = res.href;
}, 1500);
} else {
this.view.regBtn.addClass('active');
showErrTip(data.message);
}
},
error: (data) => {
this.view.regBtn.addClass('active');
if (data && data.responseJSON && data.responseJSON.message) {
showErrTip(data.message);
}
}
});
}
}
/**
* 获取验证码
*/
getVerifyCode() {
if (!this.view.getVerifyCodeBtn.hasClass('active')) {
return;
}
let areaCode = this.view.countryCodeSelector.val();
let phoneNum = this.view.mobileInput.val();
let params = {
areaCode: areaCode.replace('+', ''),
phoneNum: this.view.mobileInput.val(),
inviteCode: this.view.inviteCodeInput.val()
};
if (api.phoneRegx[areaCode].test(phoneNum) || areaCode !== '+86') {
validate.getResults().then(result => {
$.extend(params, result);
$.ajax({
url: '/passport/reg/verifymobile',
type: 'POST',
data: params,
success: postResult => {
validate.type === 2 && validate.refresh();
if (postResult.code === 200) {
this.view.tokenInput.val(postResult.data.token);
this.countDown();
} else {
(postResult.changeCaptcha && validate.type !== 2) && validate.refresh();
showErrTip(postResult.message);
}
},
error: () => {
showErrTip('出错了,请重试');
validate.refresh();
}
});
});
}
}
}
module.exports = RegisterNew;
... ...
... ... @@ -96,7 +96,7 @@ $btnNext.on('touchstart', function() {
success: function(data) {
validate.type === 2 && validate.refresh();
if (data.code === 200) {
location.href = data.data;
location.href = data.data.href;
} else {
(data.changeCaptcha && validate.type !== 2) && validate.refresh();
... ...
... ... @@ -3,11 +3,11 @@ const $ = require('yoho-jquery');
let reLoginBtn = $('#reLogin');
reLoginBtn.on('click', function() {
window.location.href = '/passport/login';
window.location.href = '/signin.html';
});
$(function() {
setTimeout(function() {
window.location.href = '/passport/login';
window.location.href = '/signin.html';
}, 3000);
});
... ...
... ... @@ -2,7 +2,6 @@
* @Author: Targaryen
* @Date: 2017-04-13 14:43:19
* @Last Modified by: Targaryen
* @Last Modified time: 2017-04-19 14:51:03
*/
/* ***************
... ... @@ -115,7 +114,7 @@ $sureResetBtn.on('click', function() {
}
if (result.code === 402) {
window.location.href = '/passport/login';
window.location.href = '/signin.html';
}
},
error: function() {
... ...
... ... @@ -84,7 +84,7 @@ page = {
}
$resendBtn.prop('disabled', true);
$resendBtn.text('重新发送(' + second + ')');
$resendBtn.text('重新获取(' + second + ')');
this.timerId = setInterval(function() {
let txt = self.resendText;
... ... @@ -95,7 +95,7 @@ page = {
self.timerId = null;
$resendBtn.prop('disabled', false);
} else {
txt = '重新发送(' + second + '秒)';
txt = '重新获取(' + second + '秒)';
}
$resendBtn.text(txt);
... ...