Authored by 姜枫

add login assets

... ... @@ -7,6 +7,7 @@
const library = '../../../library';
const passport = require('passport');
const md5 = require('md5');
const cookie = require(`${library}/cookie`);
const helpers = require(`${library}/helpers`);
const log = require(`${library}/logger`);
... ... @@ -51,6 +52,47 @@ function doPassportCallback(openId, nickname, sourceType, req, res) {
}
}
const local = {
loginPage: (req, res) => {
// 设置登录有效时间30分钟, 防机器刷,cache不稳定,改为cookie
res.cookie('LE' + md5('_LOGIN_EXPIRE'), (new Date()).getTime() / 1000 + 1800);
// 清除cookie
res.clearCookie('_UID');
res.clearCookie('_TOKEN');
let refer = req.query.refer;
if (!refer) {
refer = req.get('Referer');
}
refer && res.cookie('refer', encodeURI(refer), {
domain: 'yohobuy.com'
});
res.render('login', {
loginIndex: true, // 模板中使用JS的标识
backUrl: 'javascript:history.go(-1)', // 返回的URL链接
showHeaderImg: true, // 控制显示头部图片
isPassportPage: true, // 模板中模块标识
registerUrl: '/reg.html', // 注册的URL链接
aliLoginUrl: '/passport/login/alipay', // 支付宝快捷登录的URL链接
weiboLoginUrl: '/passport/login/sina', // 微博登录的URL链接
qqLoginUrl: '/passport/login/qq', // 腾讯QQ登录的URL链接
internationalUrl: '/login.html', // 国际号登录的URL链接
phoneRetriveUrl: '/passport/back/mobile', // 通过手机号找回密码的URL链接
emailRetriveUrl: '/passport/back/email', // 通过邮箱找回密码的URL链接
module: 'passport',
page: 'index',
title: '登录'
});
},
login: (req, res, next) => {
}
};
const wechat = {
beforeLogin: (req, res, next) => {
let refer = req.query.refer;
... ... @@ -80,4 +122,5 @@ const wechat = {
}
};
exports.local = local;
exports.wechat = wechat;
... ...
... ... @@ -12,6 +12,7 @@ const login = require(cRoot + '/login');
const router = express.Router(); // eslint-disable-line
router.get('/login', login.local.loginPage);
router.get('/login/wechat', login.wechat.beforeLogin, login.wechat.login); // 登录
router.get('/login/wechat/callback', login.wechat.callback);
... ...
<div class="login-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
<div class="acc-container input-container row has-clear">
<div class="yoho-logo"></div>
<input id="account" class="input account" type="text" placeholder="手机号/邮箱" autocomplete="off" value={{account}}>
</div>
<div class="input-container row has-eye">
<input id="pwd" class="pwd input" type="password" placeholder="密码">
</div>
<span id="btn-login" class="btn btn-login disable">登录</span>
<p class="op-container">
<a class="go-register" href={{registerUrl}}>免费注册</a>
<span id="forget-pwd" class="forget-pwd">忘记密码</span>
</p>
<div class="third-party-login">
<span>其他登录方式</span>
<div class="tp-link">
<a class="alipay" href={{aliLoginUrl}}></a>
<a class="weibo" href={{weiboLoginUrl}}></a>
<a class="qq" href={{qqLoginUrl}}></a>
</div>
</div>
<a class="international" href={{internationalUrl}}>International Customer</a>
<div class="login-tip">
<div class="info-icon"></div>
Yoho!Family账号可登录Yoho!Buy有货
</div>
<div id="retrive-pwd-mask" class="mask"></div>
<ul id="retrive-pwd-ways" class="retrive-pwd-ways">
<li>
<a href={{phoneRetriveUrl}}>通过手机找回密码</a>
</li>
<li>
<a href={{emailRetriveUrl}}>通过邮箱找回密码</a>
</li>
<li id="cancel-retrive">
取消
</li>
</ul>
</div>
</div>
\ No newline at end of file
... ...
<div class="header">
<a class="go-back" href="{{#if backUrl}}{{backUrl}}{{^}}javascript:history.go(-1);{{/if}}"></a>
{{#showHeaderImg}}
<div class="img-header"></div>
{{/showHeaderImg}}
{{#headerText}}
<p class="title">{{.}}</p>
{{/headerText}}
</div>
\ No newline at end of file
... ...
/**
* 登录
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/9/30
*/
var $ = require('jquery');
var $account = $('#account'),
$pwd = $('#pwd'),
$loginBtn = $('#btn-login'),
$mask = $('#retrive-pwd-mask'),
$ways = $('#retrive-pwd-ways'),
accPass = false,
pwdPass = false;
var api = require('../api');
var tip = require('../../plugin/tip');
var trim = $.trim;
var showErrTip = tip.show;
//登录按钮状态切换
function switchLoginBtnStatus() {
if (accPass && pwdPass) {
$loginBtn.removeClass('disable');
} else {
$loginBtn.addClass('disable');
}
}
//显示找回密码面板
function showRetrivePanel() {
$mask.show();
$ways.show();
}
//隐藏找回密码面板
function hideRetrivePanel() {
$mask.hide();
$ways.hide();
}
//密码显示与隐藏
api.bindEyesEvt();
//清空账号输入框
api.bindClearEvt();
$account.bind('input', function() {
if (trim($account.val()) !== '') {
accPass = true;
} else {
accPass = false;
}
switchLoginBtnStatus();
});
$pwd.bind('input', function() {
if (trim($pwd.val()) === '') {
pwdPass = false;
} else {
pwdPass = true;
}
switchLoginBtnStatus();
});
// Login
$loginBtn.on('touchstart', function() {
var acc = trim($account.val()),
pwd = trim($pwd.val());
if ($loginBtn.hasClass('disable')) {
return;
}
$loginBtn.text('正在登录...').addClass('disable');
//验证账号(数字或者邮箱)和密码合理性
if ((/^[0-9]+$/.test(acc) || api.emailRegx.test(acc)) && api.pwdValidate(pwd)) {
$.ajax({
type: 'POST',
url: '/passport/login/auth',
data: {
account: acc,
password: pwd
},
success: function(data) {
var res;
if (data.code === 200) {
res = data.data;
showErrTip('登录成功');
location.href = res.href;
} else {
showErrTip(data.message);
}
},
error: function() {
showErrTip('网络断开连接啦~');
},
complete: function() {
$loginBtn.text('登录').removeClass('disable');
}
});
} else {
showErrTip('账号或密码有错误,请重新输入');
$loginBtn.text('登录').removeClass('disable');
}
});
$('#forget-pwd').on('touchstart', function() {
showRetrivePanel();
});
$mask.on('touchstart', function() {
hideRetrivePanel();
});
$('#cancel-retrive').on('touchstart', function(e) {
e.preventDefault();
hideRetrivePanel();
});
//对初始有默认值的情况去初始化登录按钮状态
$account.trigger('input');
$pwd.trigger('input');
... ...
.back-email-success-page {
.tip {
font-size: 20PX;
color: #fff;
margin-top: 30PX;
}
.sub-tip, .resend {
color: #939393;
font-size: 16PX;
}
.go-email {
margin: 20PX 0 10PX;
}
.resend {
float: right;
}
}
\ No newline at end of file
... ...
.bind-page
.bind-tip {
color: #fff;
font-size: 15PX;
}
#yohood {
background-image: resolve('yohood.png');
background-size: 40%;
background-repeat: no-repeat;
background-color: transparent;
background-position-x: 10%;
background-position-y: 40%;
border: none;
border-bottom: 4PX solid #fff;
}
... ...
.reg-code-page, .back-code-page {
.captcha-tip {
position: absolute;
width: 148PX;
text-align: center;
right: 15PX;
top: 8PX;
color: #36a74c;
padding: 5PX 0;
border: 1px solid #36a74c;
border-radius: 20PX;
font-size: 16PX;
&.disable {
color: #8f8f8f;
border-color: #8f8f8f;
}
}
.input-container {
padding-right: 190PX;
}
.text-container {
color: #fff;
font-size: 16PX;
margin-bottom: 20PX;
}
.phone {
color: #4ecae8;
}
.clear-input {
right: 170PX;
}
.tip {
margin-top: 30PX;
color: #fff;
font-size: 14PX;
line-height: 2;
a {
color: #fff;
}
}
}
... ...
body.passport-body {
background-color: #444;
font-family: "MicroSoft YaHei",SimSun,sans-serif;
* {
box-sizing: border-box;
}
}
.passport-page {
text-align: center;
padding: 0 6%;
.header {
position: relative;
height: 40PX;
margin: 20PX 0 30PX;
.go-back {
display: block;
position: absolute;
height: 30PX;
width: 30PX;
top: 5PX;
left: 0;
background: resolve('passport/go-back.png') no-repeat;
background-size: 100% 100%;
}
.title {
font-size: 20PX;
line-height: 40PX;
color: #fff;
}
.img-header {
width: 68PX;
height: 40PX;
background: resolve('passport/yoho-family.png') no-repeat;
background-size: 100% 100%;
margin: 0 auto;
}
}
.input-container, .select-container {
position: relative;
width: 100%;
height: 52PX;
font-size: 20PX;
background-color: #575757;
border: 1px solid #606060;
border-radius: 5PX;
text-align: left;
color: #fff;
}
.select-container {
.select {
position: absolute;
height: 50PX;
padding-right: 40PX;
right: 0;
color: #fff;
background-color: transparent;
border: 0;
border-radius: 5PX;
appearance: none;
direction: rtl;
&:focus {
outline: 0;
border: none;
}
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 #fff;
}
}
.select-title {
line-height: 2.5;
margin-left: 15PX;
}
.arrow-right {
position: absolute;
width: 13PX;
height: 20PX;
right: 15PX;
top: 16PX;
background: resolve('passport/arrow-right.png') no-repeat;
background-size: 100% 100%;
}
}
.has-eye, .has-clear {
padding-right: 30PX;
}
.area-code {
position: absolute;
left: 15PX;
line-height: 2.5;
}
.phone-container {
padding-left: 55PX;
}
.input {
width: 100%;
line-height: 26PX;
padding: 12PX 0;
padding-left: 15PX;
border-radius: 5PX;
color: #fff;
background-color: transparent;
border: none;
}
.btn {
display: block;
width: 100%;
font-size: 20PX;
line-height: 2.5;
background-color: #36a74c;
border-radius: 5PX;
color: #fff;
&.disable {
background-color: #a2a2a2;
}
}
.country-select.in-android-uc {
width: 90PX;
}
.clear-input {
position: absolute;
display: none;
top: 18PX;
right: 10PX;
width: 16PX;
height: 16PX;
background: resolve('passport/clear-input.png') no-repeat;
background-size: 100% 100%;
}
.eye {
position: absolute;
top: 20PX;
right: 10PX;
width: 19PX;
height: 12PX;
background: resolve('passport/eye.png') no-repeat;
background-size: 100% 100%;
&.close {
background-image: resolve('passport/eye-close.png');
}
}
.row {
margin-bottom: 10PX;
}
}
... ...
@import "common";
@import "register";
@import "login";
@import "back";
@import "code";
@import "bind";
@import "success";
... ...
.login-page {
.yoho-logo {
position: absolute;
height: 31PX;
width: 26PX;
background: resolve('passport/yoho.png');
background-size: 100% 100%;
top: 10PX;
left: 15PX;
}
.acc-container {
padding-left: 45PX;
}
.op-container {
position: relative;
width: 100%;
margin: 20PX 0;
text-align: left;
font-size: 16PX;
.go-register {
text-decoration: underline;
color: #858585;
}
.forget-pwd {
position: absolute;
right: 0;
text-decoration: underline;
color: #858585;
}
}
.third-party-login {
text-align: left;
> span {
font-size: 16PX;
color: #858585;
}
.tp-link {
text-align: center;
padding: 20PX 0;
> a {
display: inline-block;
width: 44PX;
height: 44PX;
margin: 0 7PX;
border-radius: 50%;
background-color: #333;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.alipay {
background-image: resolve('passport/alipay.png');
}
.weibo {
background-image: resolve('passport/weibo.png');
}
.weixin {
background-image: resolve('passport/weixin.png');
}
.qq {
background-image: resolve('passport/qq.png');
}
}
}
.international {
display: block;
width: 200PX;
padding: 5PX 10PX;
background-color: #333;
border: none;
border-radius: 20PX;
margin: 0 auto;
font-size: 16PX;
color: #d8d8d8;
}
.login-tip {
font-size: 16PX;
position: relative;
color: #d8d8d8;
margin: 15PX 0;
.info-icon {
display: inline-block;
height: 12PX;
width: 12PX;
background-image: resolve('passport/info.png');
background-size: 100% 100%;
}
}
.mask {
position: fixed;
display: none;
top: 0;
bottom: 0;
right: 0;
left: 0;
background-color: rgba(0,0,0,.5);
}
.retrive-pwd-ways {
position: fixed;
display: none;
bottom: 5PX;
left: 10PX;
right: 10PX;
font-size: 16PX;
li {
background-color: #fff;
width: 100%;
height: 40PX;
line-height: 40PX;
text-align: center;
&:nth-child(1) {
border-top-left-radius: 5PX;
border-top-right-radius: 5PX;
border-bottom: 1PX solid #9f9f9f;
}
&:nth-child(2) {
border-bottom-left-radius: 5PX;
border-bottom-right-radius: 5PX;
}
&:last-child {
margin-top: 10PX;
border-radius: 5PX;
}
}
}
}
... ...
.reg-page .register-tip {
color: #fff;
font-size: 15PX;
}
... ...
.success-page {
color: #fefefe;
.success-icon {
width: 74PX;
height: 74PX;
margin: 60PX auto 30PX;
background: resolve("passport/success.png");
background-size: 100%;
}
.success-tip {
padding: 10PX 10PX;
font-size: 16PX;
line-height: 1.5;
}
.go {
display: block;
margin: 30PX auto;
width: 270PX;
height: 40PX;
font-size: 14PX;
line-height: 40PX;
color: #fff;
background: rgba(255, 255, 255, .4);
border-radius: 5PX;
}
}
... ...