Authored by xuqi

Merge branch 'feature/passport' into develop

Showing 57 changed files with 1766 additions and 31 deletions
... ... @@ -510,4 +510,95 @@
...
]
}
}
## 登录、注册、找回密码
### TIP:登录注册找回密码页面body有特有样式,因为数据中需要传一个isPassportPage为body添加一个class
### 通用头部(包含在每个页面中)
{
showGoBack: true/false, //是否显示GO-BACK链接
backUrl: '',
showHeaderImg: true/false, //显示头部图片
showHeaderText: true/false, //显示头部文字
headerText: ''
}
### 区域列表
[
{
areaCode: '+86', //区号
selected: true/false,
name: '中国'
},
...
]
### 登录
//登录页
{
account: '', //默认填入的用户名
registerUrl: '', //免费注册地址
aliLoginUrl: '',
weiboLoginUrl: '',
qqLoginUrl: '',
interationalUrl: '',
phoneRetriveUrl: '',
emailRetriveUrl: ''
}
//国际账号登录页
{
countrys: [...], //区域列表
countryCode: '',
phoneNum: ''
}
### 注册
//注册页
{
countrys: [...], //区域列表
countryCode: '' //默认区号
}
//验证码
{
areaCode: '',
phoneNum: ''
}
//密码页
{
... //仅头部
}
### 找回密码
//邮箱找回&重置密码
{
... //仅头部
}
//邮箱找回成功
{
goEmail: '',
resendUrl: ''
}
//手机找回
{
countrys: [...],
countryCode: ''
}
//手机找回验证码
{
areaCode: '',
phoneNum: ''
}
\ No newline at end of file
... ...
var yohobuy;
require('./js/index');
require('./js/passport/index');
module.exports = yohobuy;
... ...
alert('I am test');
\ No newline at end of file
/**
* 登录注册公用API
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var trim = $.trim;
//邮箱验证规则
var emailRegx = /^([a-zA-Z0-9]+[_|\_|\.|-]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.|-]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/;
//手机号码验证规则
var phoneRegx = {
'+86': /^1[35847]{1}[0-9]{9}$/,
'+852': /^[965]{1}[0-9]{7}$/,
'+853': /^[0-9]{8}$/,
'+886': /^[0-9]{10}$/,
'+65': /^[98]{1}[0-9]{7}$/,
'+60': /^1[1234679]{1}[0-9]{8}$/,
'+1': /^[0-9]{10}$/,
'+82': /^01[0-9]{9}$/,
'+44': /^7[789][0-9]{8}$/,
'+81': /^0[9|8|7][0-9]{9}$/,
'+61': /^[0-9]{11}$/
};
//错误验证
var $errTip,
tipTime;
/**
* 初始化错误提示
*/
function initErrTip() {
var errTipHtml = '<div id="err-tip" class="err-tip"></div>';
//插入错误提示HTML
$('.passport-page').append(errTipHtml);
$errTip = $('#err-tip');
$errTip.on('touchstart', function() {
$errTip.fadeOut();
//清除Timeout
clearTimeout(tipTime);
});
}
/**
* 显示错误提示
*/
function showErrTip(content) {
if (typeof $errTip === 'undefined') {
return;
}
$errTip.text(content).show();
//若2秒内未点击则自动消失
tipTime = setTimeout(function() {
if ($errTip.css('display') === 'block') {
$errTip.fadeOut();
}
}, 2000);
}
//密码显示隐藏
function bindEyesEvt() {
var $hasEye = $('.has-eye'),
$eye;
$hasEye.append('<div class="eye close"></div>');
$eye = $hasEye.children('.eye');
$eye.on('touchstart', function(e) {
var $this = $(this),
$pwd = $this.siblings('.pwd');
e.preventDefault();
$this.toggleClass('close');
//切换密码显示和文本显示
if ($this.hasClass('close')) {
$pwd.attr('type', 'password');
} else {
$pwd.attr('type', 'text');
}
$pwd.focus();
});
}
// 清空账号显示
function bindClearEvt() {
var $hasClear = $('.has-clear'),
$clear;
$hasClear.append('<div class="clear-input"></div>');
$clear = $hasClear.children('.clear-input');
$clear.on('touchstart', function(e) {
var $input = $clear.siblings('.input');
$input.val('').trigger('input').focus();
e.preventDefault();
});
//反向逻辑
$hasClear.children('.input').bind('input', function() {
var $this = $(this),
$thisClear = $this.siblings('.clear-input'),
val = trim($this.val());
if (val === '') {
$thisClear.hide();
} else {
$thisClear.show();
}
});
}
// 密码长度验证
function pwdValidate(pwd) {
if (pwd.length >= 6 && pwd.length <= 20) {
return true;
}
return false;
}
// hack for resolving direction:rtl didn't work in android uc
function selectCssHack($countrySelect) {
var u = navigator.userAgent;
function autoSelectWidth() {
var wordCount = $countrySelect.find('option:selected').text().length;
switch (wordCount) {
//分别有2,3,4个汉字的情况
case 2:
$countrySelect.outerWidth(90);
break;
case 3:
$countrySelect.outerWidth(110);
break;
default:
$countrySelect.outerWidth(130);
}
}
if (u.match(/uc/i) && u.match(/android/i)) {
$countrySelect.change(function() {
autoSelectWidth();
});
} else {
$countrySelect.removeClass('in-android-uc');
}
}
//Exports APIs
module.exports = {
emailRegx: emailRegx,
phoneRegx: phoneRegx,
initErrTip: initErrTip,
showErrTip: showErrTip,
bindEyesEvt: bindEyesEvt,
bindClearEvt: bindClearEvt,
pwdValidate: pwdValidate,
selectCssHack: selectCssHack
};
\ No newline at end of file
... ...
/**
* 找回密码-验证码
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
require('../code')(false);
\ No newline at end of file
... ...
/**
* 找回密码-邮箱找回成功
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $resend = $('#resend');
var api = require('../api'),
showErrTip = api.showErrTip;
api.initErrTip();
$resend.on('touchstart', function(e) {
e.preventDefault();
$.ajax({
url: $resend.data('url'),
type: 'GET'
}).then(function(data) {
if (data.code === 200) {
showErrTip(data.message);
} else {
showErrTip(data.message);
}
});
});
\ No newline at end of file
... ...
/**
* 找回密码-邮箱找回
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $email = $('#email'),
$btnSure = $('#btn-sure');
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
api.initErrTip();
api.bindClearEvt();
$email.bind('input', function() {
if (trim($email.val()) === '') {
$btnSure.addClass('disable');
} else {
$btnSure.removeClass('disable');
}
});
$btnSure.on('touchstart', function() {
var email = trim($email.val());
if ($btnSure.hasClass('disable')) {
return;
}
if (api.emailRegx.test(email)) {
$.ajax({
url: '/passport/back/sendemail',
type: 'POST',
data: {
email: email
}
}).then(function(data) {
if (data.code === 200) {
location.href = data.data;
} else {
showErrTip(data.message);
}
});
} else {
showErrTip('邮箱格式不正确,请重新输入');
}
});
\ No newline at end of file
... ...
/**
* 找回密码-手机
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $phoneNum = $('#phone-num'),
$countrySelector = $('#country-selector'),
$countryCode = $('#country-code'),
$btnNext = $('#btn-next');
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
api.initErrTip();
api.bindClearEvt();
$phoneNum.bind('input', function() {
if (trim($phoneNum.val()) === '') {
$btnNext.addClass('disable');
} else {
$btnNext.removeClass('disable');
}
});
$countrySelector.change(function() {
$countryCode.text($countrySelector.val());
});
$btnNext.on('touchstart', function() {
var pn = trim($phoneNum.val()),
country = $countrySelector.val();
if ($btnNext.hasClass('disable')) {
return;
}
if (api.phoneRegx.test(pn)) {
$.ajax({
url: '/passport/back/sendcode',
type: 'POST',
data: {
area: country.split('+')[1],
mobile: pn
}
}).then(function(data) {
if (data.code === 200) {
location.href = '/passport/back/code';
} else {
showErrTip(data.message);
}
});
} else {
showErrTip('手机号格式不正确,请重新输入');
}
});
\ No newline at end of file
... ...
/**
* 密码找回-新密码
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $pwd = $('#pwd'),
$btnOk = $('#btn-ok');
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
api.initErrTip();
api.bindEyesEvt();
$pwd.bind('input', function() {
if (trim($pwd.val()) === '') {
$btnOk.addClass('disable');
} else {
$btnOk.removeClass('disable');
}
});
$btnOk.on('touchstart', function() {
var pwd = trim($pwd.val());
if ($btnOk.hasClass('disable')) {
return;
}
if (api.pwdValidate(pwd)) {
$.ajax({
type: 'POST',
url: '/passport/back/update',
data: {
password: pwd
}
}).then(function(data) {
if (data.code === 200) {
showErrTip('密码修改成功');
//1000ms后跳转页面
setTimeout(function() {
location.href = '/';
}, 1000);
} else {
showErrTip(data.message);
}
});
} else {
showErrTip('密码6-20位,请重新输入');
}
});
\ No newline at end of file
... ...
/**
* 注册/找回密码-验证码
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
module.exports = function(useInRegister) {
var $captcha = $('#captcha'),
$btnNext = $('#btn-next'),
$captchaTip = $('#captcha-tip');
var api = require('./api');
var trim = $.trim;
var showErrTip = api.showErrTip;
var urlMid = useInRegister ? 'register' : 'back';
function countDown() {
var count = 59,
itime;
itime = setInterval(function() {
if (count === 0) {
$captchaTip.text('重发验证码').removeClass('disable');
clearInterval(itime);
} else {
$captchaTip.text('重发验证码 (' + count-- + '秒)');
}
}, 1000);
}
api.initErrTip();
api.bindClearEvt();
$captcha.bind('input', function() {
if (trim($captcha.val()) !== '') {
$btnNext.removeClass('disable');
} else {
$btnNext.addClass('disable');
}
});
//重新发送验证码
$captchaTip.on('touchstart', function() {
if ($captchaTip.hasClass('disable')) {
return;
}
$.ajax({
type: 'POST',
url: '/passport/' + urlMid + '/sendPhone'
}).then(function (data) {
if (data.code === 200) {
$captchaTip.text('重发验证码 (60秒)').addClass('disable');
countDown();
} else {
//验证码不正确,显示提示
showErrTip(data.message);
}
});
});
$btnNext.on('touchstart', function() {
if ($btnNext.hasClass('disable')) {
return;
}
$.ajax({
type: 'POST',
url: '/passport/' + urlMid + '/verifycode',
data: {
verifyCode: trim($captcha.val())
}
}).then(function (data) {
if (data.code === 200) {
location.href = data.data;
} else {
//验证码不正确,显示提示
showErrTip(data.message);
}
});
});
countDown();
};
\ No newline at end of file
... ...
/**
* 注册、登录、密码找回打包入口
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
//注册
require('./register/register');
require('./register/code');
require('./register/password');
//登录
require('./login/login');
require('./login/interational');
//密码找回
require('./back/mobile');
require('./back/code');
require('./back/email');
require('./back/email-success');
require('./back/new-password');
\ No newline at end of file
... ...
/**
* 国际账号登录
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $phoneNum = $('#phone-num'),
$countrySelect = $('#country-select'),
$countryCode = $('#country-code'),
$pwd = $('#pwd'),
$loginBtn = $('#btn-login'),
pnPass = false,
pwdPass = false;
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
//登录按钮状态切换
function switchLoginBtnStatus() {
if (pnPass && pwdPass) {
$loginBtn.removeClass('disable');
} else {
$loginBtn.addClass('disable');
}
}
//Android-UC下显示select的direction:rtl无效的临时解决办法
api.selectCssHack($countrySelect);
//初始化ErrTip
api.initErrTip();
//显示隐藏密码
api.bindEyesEvt();
//清空手机号码
api.bindClearEvt();
$phoneNum.bind('input', function() {
if (trim($phoneNum.val()) === '') {
pnPass = false;
} else {
pnPass = true;
}
switchLoginBtnStatus();
});
$pwd.bind('input', function() {
var pwd = trim($pwd.val());
if (pwd === '') {
pwdPass = false;
} else {
pwdPass = true;
}
switchLoginBtnStatus();
});
$countrySelect.change(function() {
$countryCode.text($countrySelect.val());
});
$loginBtn.on('touchstart', function() {
var pn = trim($phoneNum.val()),
country = $countrySelect.val(),
pwd = trim($pwd.val());
if ($loginBtn.hasClass('disable')) {
return;
}
if (api.phoneRegx[country].test(pn) && api.pwdValidate(pwd)) {
$.ajax({
type: 'POST',
url: '/passport/signin/auth',
data: {
area: country.split('+')[1],
account: pn,
pwd: pwd
}
}).then(function(data) {
if (data.code === 200) {
showErrTip('登录成功');
//1000ms后跳转页面
setTimeout(function() {
location.href = data.data;
}, 1000);
} else {
showErrTip(data.message);
}
}, function() {
showErrTip('网络断开连接啦~');
});
} else {
showErrTip('账号或密码有错误,请重新输入');
}
});
//对初始有默认值的情况去初始化登录按钮状态
$phoneNum.trigger('input');
$pwd.trigger('input');
\ No newline at end of file
... ...
/**
* 登录
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/9/30
*/
var $ = require('yoho.zepto');
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 trim = $.trim;
var showErrTip = api.showErrTip;
//登录按钮状态切换
function switchLoginBtnStatus() {
if (accPass && pwdPass) {
$loginBtn.removeClass('disable');
} else {
$loginBtn.addClass('disable');
}
}
//显示找回密码面板
function showRetrivePanel() {
$mask.show();
$ways.slideDown();
}
//隐藏找回密码面板
function hideRetrivePanel() {
$mask.hide();
$ways.slideUp();
}
//初始化ErrTip
api.initErrTip();
//密码显示与隐藏
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;
}
//验证账号(数字或者邮箱)和密码合理性
if ((/^[0-9]+$/.test(acc) || api.emailRegx.test(acc)) && api.pwdValidate(pwd)) {
$.ajax({
type: 'POST',
url: '/passport/signin/auth',
data: {
account: acc,
pwd: pwd
}
}).then(function(data) {
if (data.code === 200) {
showErrTip('登录成功');
//1s后跳转页面
setTimeout(function() {
location.href = data.data;
}, 1000);
} else {
showErrTip(data.message);
}
}, function() {
showErrTip('网络断开连接啦~');
});
} else {
showErrTip('账号或密码有错误,请重新输入');
}
});
$('#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');
\ No newline at end of file
... ...
/**
* 注册-验证码
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
require('../code')(true);
\ No newline at end of file
... ...
/**
* 注册-密码
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $pwd = $('#pwd'),
$btnSure = $('#btn-sure');
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
api.initErrTip();
api.bindEyesEvt();
$pwd.bind('input', function() {
if (trim($pwd.val()) === '') {
$btnSure.addClass('disable');
} else {
$btnSure.removeClass('disable');
}
});
$btnSure.on('touchstart', function() {
var pwd = trim($pwd.val());
if ($btnSure.hasClass('disable')) {
return;
}
if (api.pwdValidate(pwd) === false) {
showErrTip('密码6-20位,请重新输入');
} else {
$.ajax({
type: 'POST',
url: '/passport/register/regmobile',
data: {
password: pwd
}
}).then(function(data) {
if (data.code === 200) {
showErrTip('注册成功');
//1000ms后跳转页面
setTimeout(function() {
location.href = data.data;
}, 1000);
} else {
if (data.code === 401 || data.code === 404 || data.code === 505) {
showErrTip(data.message);
} else {
showErrTip(data.message);
setTimeout(function() {
location.href = data.data;
}, 1000);
}
}
});
}
});
\ No newline at end of file
... ...
/**
* 注册
* @author: xuqi<qi.xu@yoho.cn>
* @date: 2015/10/8
*/
var $ = require('yoho.zepto');
var $phoneNum = $('#phone-num'),
$countrySelect = $('#country-select'),
$countryCode = $('#country-code'),
$btnNext = $('#btn-next');
var api = require('../api');
var trim = $.trim;
var showErrTip = api.showErrTip;
api.initErrTip();
api.bindClearEvt();
$phoneNum.bind('input', function() {
if (trim($phoneNum.val()) === '') {
$btnNext.addClass('disable');
} else {
$btnNext.removeClass('disable');
}
});
$countrySelect.change(function() {
$countryCode.text($countrySelect.val());
});
$btnNext.on('touchstart', function() {
var pn = trim($phoneNum.val()),
country = $countrySelect.val();
if ($btnNext.hasClass('disable')) {
return;
}
if (api.phoneRegx[country].test(pn)) {
$.ajax({
url: '/passport/register/sendphone',
type: 'POST',
data: {
area: country.split('+')[1],
profile: pn
}
}).then(function(data) {
if (data.code === 200) {
location.href = '/passport/register/code';
} else {
showErrTip(data.message);
}
});
} else {
showErrTip('手机号格式不正确,请重新输入');
}
});
\ No newline at end of file
... ...
... ... @@ -16,6 +16,8 @@
"spm": {
"main": "index.js",
"dependencies": {
"yoho.zepto": "1.1.60",
"yoho.jquery": "1.8.3"
},
"devDependencies": {
"expect.js": "0.3.1"
... ... @@ -30,4 +32,4 @@
"test": "spm test",
"build": "spm build"
}
}
}
\ No newline at end of file
... ...
body {
background-color: #ff0;
}
\ No newline at end of file
@import "compass", "compass/reset";
$pxConvertRem: 40;
* {
-webkit-tap-highlight-color: rgba(0,0,0,0);
}
html, body {
font-family: helvetica,Arial,"黑体";
width: 100%;
font-size: 12px;
line-height: 1.4;
}
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}
button, input, select, textarea {
font-family: inherit;
font-size: 100%;
margin: 0;
}
img {
max-width: 100%;
display: block;
border: 0;
margin: 0 auto;
}
a {
text-decoration: none;
outline: none;
color: #000;
}
@import "passport/index";
\ No newline at end of file
... ...
.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
... ...
.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 {
right: 170px;
}
}
\ No newline at end of file
... ...
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 {
position: absolute;
height: 30px;
width: 30px;
top: 5px;
left: 0;
}
.title {
font-size: 20px;
line-height: 40px;
color: #fff;
}
.img-header {
width: 68px;
height: 40px;
}
}
.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;
@include border-radius(5px);
@include 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-image: url('http://static.dev.yohobuy.com/img/passport/arrow-right.png');
background-size: 100% 100%;
}
}
.has-eye, .has-clear {
padding-right: 30px;
}
.country-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;
@include 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-image: url('http://static.dev.yohobuy.com/img/passport/clear-input.png');
background-size: 100% 100%;
}
.eye {
position: absolute;
top: 20px;
right: 10px;
width: 19px;
height: 12px;
background-image: url('http://static.dev.yohobuy.com/img/passport/eye.png');
background-size: 100% 100%;
&.close {
background-image: url('http://static.dev.yohobuy.com/img/passport/eye-close.png');
}
}
.row {
margin-bottom: 10px;
}
.err-tip {
position: absolute;
display: none;
text-align: center;
width: 70%;
padding: 34px 0;
top: 50%;
left: 50%;
margin-left: -35%;
margin-top: -45px;
background-color: #000;
opacity: 0.7;
color: #fff;
font-size: 18px;
border: none;
@include border-radius(10px);
}
}
\ No newline at end of file
... ...
@import "common", "register", "login", "back", "code";
\ No newline at end of file
... ...
.login-page {
.yoho-logo {
position: absolute;
height: 31px;
width: 26px;
background: image-url('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;
@include border-radius(50%);
background-color: #333;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.alipay {
background-image: image-url('passport/alipay.png');
}
.weibo {
background-image: image-url('passport/weibo.png');
}
.weixin {
background-image: image-url('passport/weixin.png');
}
.qq {
background-image: image-url('passport/qq.png');
}
}
}
.interational {
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: image-url('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) {
@include border-top-left-radius(5px);
@include border-top-right-radius(5px);
border-bottom: 1px solid #9f9f9f;
}
&:nth-child(2) {
@include border-bottom-left-radius(5px);
@include border-bottom-right-radius(5px);
}
&:last-child {
margin-top: 10px;
@include border-radius(5px);
}
}
}
}
\ No newline at end of file
... ...
.reg-page .register-tip {
color: #fff;
font-size: 15px;
}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="back-email-success-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
<p class="tip">验证邮件已发送至你的邮箱</p>
<p class="sub-tip">请在24小时内通过邮件内的链接设置新密码</p>
<a class="go-email btn" href={{goEmail}}>去邮箱看看</a>
<a id="resend" class="resend" data-url={{resendUrl}}>重新发送邮件</a>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="back-email-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
<div class="input-container row has-clear">
<input id="email" class="input email" type="text" placeholder="请输入邮箱" autocomplete="off">
</div>
<span id="btn-sure" class="btn btn-sure disable row">确定</span>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
{{> layout/header}}
<div class="back-code-page passport-page yoho-page">
{{> passport/code}}
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="back-mobile-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
{{> passport/country_list}}
<div class="input-container phone-container row has-clear">
<span id="country-code" class="country-code">{{countryCode}}</span>
<input id="phone-num" class="input phone-num" type="text" placeholder="手机号">
</div>
<span id="btn-next" class="btn btn-next disable row">下一步</span>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="back-new-password-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
<div class="input-container row has-eye">
<input id="pwd" class="input pwd" type="password" placeholder="请输入新密码" autocomplete="off" maxlength="20">
</div>
<span id="btn-ok" class="btn btn-ok disable">完成</span>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<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="interational" href={{interationalUrl}}>Interational Customer</a>
<div class="login-tip">
<div class="info-icon"></div>
Yoho!Family账号可登录YOHO!有货
</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>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="login-interational-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
{{> passport/country_list}}
<div class="input-container phone-container row has-clear">
<span id="country-code" class="country-code">{{countryCode}}</span>
<input id="phone-num" class="input phone-num" type="text" placeholder="手机号" value={{phoneNum}}>
</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 disble row">登录</span>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="reg-code-page passport-page yoho-page">
{{> passport/code}}
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="reg-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
{{> passport/country_list}}
<div class="input-container phone-container row has-clear">
<span id="country-code" class="country-code">{{countryCode}}</span>
<input id="phone-num" class="input phone-num" type="text" placeholder="手机号">
</div>
<span id="btn-next" class="btn btn-next disable row">下一步</span>
<p class="register-tip">YOHO!Family账号可登录YOHO!有货、YOHO!Boys、YOHO!Girls及SHOW</p>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
{{> layout/header}}
<div class="reg-password-page passport-page yoho-page">
{{> passport/header}}
<div class="content">
<div class="input-container row has-eye">
<input id="pwd" class="input pwd" type="text" placeholder="请输入密码" autocomplete="off" maxlength="20">
</div>
<span id="btn-sure" class="btn btn-sure disable row">确定</span>
</div>
</div>
{{> layout/footer}}
\ No newline at end of file
... ...
... ... @@ -3,7 +3,7 @@
seajs.config({
base: 'http://172.16.6.248:8000'
});
seajs.use('js/index');
seajs.use('js/{{modulePath}}');
</script>
</body>
</html>
\ No newline at end of file
... ...
... ... @@ -25,4 +25,4 @@
</script>
<link rel="stylesheet" href="http://static.dev.yohobuy.com/css/index.css">
</head>
<body>
\ No newline at end of file
<body {{#if isPassportPage}}class=passport-body{{/if}}>
\ No newline at end of file
... ...
{{> passport/header}}
<div class="content">
<div class="text-container">
验证码已发送至
<span class="phone">
{{areaCode}} {{phoneNum}}
</span>
</div>
<div class="input-container row has-clear">
<input id="captcha" class="input captcha" type="text" placeholder="验证码" maxlength="6" autocomplete="off">
<div id="captcha-tip" class="captcha-tip disable">重发验证码 (60秒)</div>
</div>
<span id="btn-next" class="btn btn-next disable row">下一步</span>
</div>
\ No newline at end of file
... ...
<div class="select-container row">
<span class="select-title">国家和地区</span>
<select id="country-select" class="country-select select in-android-uc">
{{# countrys}}
<option value={{areaCode}} {{#if selected}}selected{{/if}}>{{name}}</option>
{{/ countrys}}
</select>
<div class="arrow-right"></div>
</div>
\ No newline at end of file
... ...
<div class="header">
{{#if showGoBack}}
<a class="go-back" href={{../backUrl}}>
<img src="http://static.dev.yohobuy.com/img/passport/go-back.png">
</a>
{{/if}}
{{#if showHeaderImg}}
<img class="img-header" src="http://static.dev.yohobuy.com/img/passport/yoho-family.png">
{{/if}}
{{#if showHeaderText}}
<p class="title">{{../headerText}}</p>
{{/if}}
</div>
\ No newline at end of file
... ...
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
use Action\AbstractAction;
/**
* 频道选择
*/
class BackController extends AbstractAction
{
public function indexAction()
{
echo '密码找回';
}
public function emailAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '找回密码',
'isPassportPage' => true,
'modulePath' => 'passport/back/email'
);
$this->_view->assign('title', 'YOHO!有货');
$this->_view->display('email', $data);
}
public function successAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '找回密码',
'isPassportPage' => true,
'modulePath' => 'passport/back/email-success',
'goEmail' => '',
'resendUrl' => ''
);
$this->_view->assign('title', 'YOHO!有货');
$this->_view->display('email-success', $data);
}
public function mobileAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '找回密码',
'isPassportPage' => true,
'modulePath' => 'passport/back/mobile',
'countrys' => array(
array(
'areaCode' => '+86',
'selected' => true,
'name' => '中国'
),
array(
'areaCode' => '+864',
'name' => '中国香港'
)
),
'countryCode' => '+86'
);
$this->_view->assign('title', 'YOHO!有货');
$this->_view->display('mobile', $data);
}
public function codeAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '找回密码',
'isPassportPage' => true,
'modulePath' => 'passport/back/code',
'areaCode' => '+86',
'phoneNum' => '15895869035'
);
$this->_view->assign('title', 'YOHO!有货');
$this->_view->display('mobile-code', $data);
}
public function passwordAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '找回密码',
'isPassportPage' => true,
'modulePath' => 'passport/back/new-password'
);
$this->_view->assign('title', 'YOHO!有货');
$this->_view->display('new-password', $data);
}
}
\ No newline at end of file
... ...
<?php
use Action\AbstractAction;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
class LoginController extends AbstractAction
{
public function indexAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderImg' => true,
'isPassportPage' => true,
'modulePath' => 'passport/login/login'
);
$this->_view->assign('title', '登录');
$this->_view->display('index', $data);
}
public function interationalAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '登录',
'isPassportPage' => true,
'modulePath' => 'passport/login/interational',
'countrys' => array(
array(
'areaCode' => '+86',
'selected' => true,
'name' => '中国'
),
array(
'areaCode' => '+864',
'name' => '中国香港'
)
),
'countryCode' => '+86'
);
$this->_view->assign('title', '国际账号登录');
$this->_view->display('interational', $data);
}
}
\ No newline at end of file
... ...
<?php
use Action\AbstractAction;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
class RegController extends AbstractAction
{
public function indexAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '注册',
'isPassportPage' => true,
'modulePath' => 'passport/register/register',
'countrys' => array(
array(
'areaCode' => '+86',
'selected' => true,
'name' => '中国'
),
array(
'areaCode' => '+864',
'name' => '中国香港'
)
),
'countryCode' => '+86'
);
$this->_view->assign('title', '注册');
$this->_view->display('index', $data);
}
public function codeAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '注册',
'isPassportPage' => true,
'modulePath' => 'passport/register/code',
'areaCode' => '+86',
'phoneNum' => '15895869035'
);
$this->_view->assign('title', '注册-验证码');
$this->_view->display('code', $data);
}
public function passwordAction()
{
$data = array(
'showGoBack' => true,
'backUrl' => '',
'showHeaderText' => true,
'headerText' => '注册',
'isPassportPage' => true,
'modulePath' => 'passport/register/password'
);
$this->_view->assign('title', '注册-密码');
$this->_view->display('password', $data);
}
}
\ No newline at end of file
... ...