Browse Source

手机验证码

Signed-off-by: chenshihai <chenshh@pcl.ac.cn>
tags/v1.22.7.1
chenshihai 3 years ago
parent
commit
1f9becdf0b
2 changed files with 401 additions and 0 deletions
  1. +397
    -0
      templates/user/auth/phone_verify.tmpl
  2. +4
    -0
      templates/user/auth/signup_inner.tmpl

+ 397
- 0
templates/user/auth/phone_verify.tmpl View File

@@ -0,0 +1,397 @@
<style>
.phone-verify-code {
}

.phone-c {
display: flex;
margin: 0 0 1em;
}

.phone-c .phone-area-c {
height: 38px;
width: 80px;
margin-right: 10px;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}

.phone-c .phone-area-c select {
outline: none;
}

.phone-c .phone-num-c {
height: 38px;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}

.phone-c .phone-num-c input {
height: 100%;
width: 100%;
padding: 9.5px 14px;
box-sizing: border-box;
border: none;
outline: none;
}

.slide-bar-c {
display: flex;
height: 38px;
margin: 0 0 1em;
justify-content: center;
align-items: center;
position: relative;
}

.slide-bar-c .slide-bar-bg {
height: 34px;
flex: 1;
background-color: rgb(245, 245, 246);
border: 1px solid rgb(225, 227, 230);
border-radius: 2px;
position: relative;
}

.slide-bar-c .slide-bar-bg .slide-txt {
position: absolute;
width: 100%;
height: 100%;
display: flex;
user-select: none;
justify-content: center;
align-items: center;
color: #cdcacb;
font-size: 14px;
}

.slide-bar-c .slide-bar-bg .slide-bar {
position: absolute;
width: 38px;
height: 34px;
background-color: #d1e9fe;
border: 1px solid #1991fa;
border-radius: 2px;
box-sizing: border-box;
top: -1px;
}

.slide-bar-c .slide-bar-bg .slide-bar.sucess {
background-color: #d2f4ef;
border: 1px solid #52ccba;
}

.slide-bar-c .slide-bar-bg .slide-bar.error {
border-color: #f57a7a;
background-color: #fce1e1;
}

.slide-bar-c .slide-bar-bg .slide-trigger {
position: absolute;
width: 38px;
height: 34px;
background-color: #1991fa;
border-radius: 2px;
cursor: pointer;
top: -1px;
}

.slide-bar-c .slide-bar-bg .slide-trigger.sucess {
background-color: #52ccba;
}

.slide-bar-c .slide-bar-bg .slide-trigger.error {
background-color: #f57a7a;
}

.slide-bar-c .slide-image-big {
position: absolute;
width: 391px;
height: 196px;
top: 36px;
left: 0;
border-radius: 2px;
display: none;
}

.slide-bar-c .slide-image-small {
position: absolute;
left: 0;
width: 51px;
height: 51px;
background-color: blue;
}

.slide-bar-c .verify-code-c {
display: flex;
height: 38px;
}

.verify-code-c {
display: flex;
height: 38px;
margin: 0 0 1em;
justify-content: center;
align-items: center;
}

.verify-code-c .verify-code-num-c {
flex: 1;
height: 38px;
box-sizing: border-box;
justify-content: center;
align-items: center;
display: flex;
}

.verify-code-c .verify-code-num-c input {
height: 100%;
width: 100%;
padding: 9.5px 14px;
box-sizing: border-box;
border: none;
outline: none;
}

.verify-code-c .verify-code-send {
display: flex;
width: 120px;
height: 38px;
justify-content: center;
align-items: center;
}

.verify-code-c .verify-code-send .verify-code-send-btn {
height: 100%;
width: 100%;
margin-left: 10px;
border: 1px solid #398dee;
background-color: #398dee;
color: white;
border-radius: 2px;
box-sizing: border-box;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
}

.verify-code-c .verify-code-send .verify-code-send-btn.__disabled {
border: 1px solid #ddd;
background-color: #ddd;
cursor: not-allowed;
}
</style>
<div class="phone-verify-code">
<div class="phone-c">
<div class="phone-area-c">
<select value="+86">
<option value="+86">+86</option>
</select>
</div>
<div class="field phone-num-c">
<input class="phoneNumber" name="phoneNumber" placeholder="手机号码" required />
</div>
</div>
<div class="slide-bar-c">
<div class="slide-bar-bg">
<div class="slide-txt">向右拖动滑块填充拼图</div>
<div class="slide-bar"></div>
<div class="slide-trigger"></div>
</div>
<div class="slide-image-big">
<div class="slide-image-small" style="top:{{.SlideImageInfo.ImageY}}px"></div>
</div>
</div>
<div class="verify-code-c">
<div class="verify-code-num-c">
<input class="verifyCode" name="verifyCode" placeholder="请输入短信验证码" required />
</div>
<div class="verify-code-send">
<div class="verify-code-send-btn __disabled">获取验证码</div>
</div>
</div>
</div>
<script>
window.addEventListener('load', function () {
function PhoneVerifyCode(dom) {
if (!dom) return;
this.countDownNumber = 20;
this.init(dom);
}
PhoneVerifyCode.prototype.init = function (dom) {
if (!dom) return;
this.dom = $(dom);
this.isMoving = false;
this.verifySucess = false;
this.canSendCode = false;
this.countDownEnd = false;
this.imgID = '';
this.eventInit();
this.refreshImages();
};

PhoneVerifyCode.prototype.eventInit = function () {
if (!this.dom) return;
var self = this;
var clientX = 0, oLeft = 0, imgHideTimer = null;
this.dom.find('.slide-bar-bg').on('mouseenter', function (e) {
if (self.verifySucess) return;
imgHideTimer && clearTimeout(imgHideTimer);
self.dom.find('.slide-image-big').slideDown();
});
this.dom.find('.slide-bar-bg').on('mouseleave', function (e) {
imgHideTimer && clearTimeout(imgHideTimer);
imgHideTimer = setTimeout(function () {
self.dom.find('.slide-image-big').slideUp();
}, 200);
});
this.dom.find('.slide-image-big').on('mouseenter', function (e) {
imgHideTimer && clearTimeout(imgHideTimer);
});
this.dom.find('.slide-image-big').on('mouseleave', function (e) {
imgHideTimer && clearTimeout(imgHideTimer);
imgHideTimer = setTimeout(function () {
self.dom.find('.slide-image-big').slideUp();
}, 200);
});
function mouseMove(e) {
var _clientX = e.clientX;
var offset = _clientX - clientX;
var triggerEl = self.dom.find('.slide-trigger');
var triggerWidth = triggerEl.width();
var parentWidth = triggerEl.parent().width();
var maxLeft = parentWidth - triggerWidth;
var left = oLeft + offset;
if (oLeft + offset < 0) left = 0;
if (oLeft + offset > maxLeft) left = maxLeft;
triggerEl.css('left', left + 'px');
self.dom.find('.slide-bar').css('width', left + triggerWidth);
var imageBigWidth = self.dom.find('.slide-image-big').width();
var imageSmallWidth = self.dom.find('.slide-image-small').width();
self.dom.find('.slide-image-small').css('left', left / maxLeft * (imageBigWidth - imageSmallWidth) + 'px');
self.isMoving = true;
self.dom.find('.slide-txt').hide();
imgHideTimer && clearTimeout(imgHideTimer);
}
function mouseUp(e) {
$(document).off('mousemove', mouseMove);
$(document).off('mouseup', mouseUp);
self.isMoving = false;
$.ajax({
url: '/verifySlideImage',
type: 'post',
dataType: 'json',
data: {
slideID: self.imgID,
x: self.dom.find('.slide-image-small').position().left
},
success: function(res) {
if (res && res.code === 0) {
self.verifySucess = true;
self.canSendCode = true;
self.dom.find('.slide-bar').addClass('sucess');
self.dom.find('.slide-trigger').addClass('sucess');
self.dom.find('.slide-image-big').slideUp();
self.dom.find('.verify-code-send-btn').removeClass('__disabled');
} else {
self.dom.find('.slide-bar').addClass('error');
self.dom.find('.slide-trigger').addClass('error');
setTimeout(function () {
self.refreshImages();
}, 300);
}
},
error: function(err) {
self.dom.find('.slide-bar').addClass('error');
self.dom.find('.slide-trigger').addClass('error');
setTimeout(function () {
self.refreshImages();
}, 300);
}
});
}
this.dom.find('.slide-trigger').on('mousedown', function (e) {
if (self.verifySucess) return;
clientX = e.clientX;
oLeft = $(this).position().left;
$(document).on('mousemove', mouseMove);
$(document).on('mouseup', mouseUp);
});
this.dom.find('.verify-code-send-btn').on('click', function () {
if (!self.canSendCode) return;
if (self.countDownEnd) {
self.refreshImages();
return;
}
var phoneArea = self.dom.find('.phone-area-c select').val();
var phoneNumber = self.dom.find('.phone-num-c input').val();
if (!/^1[3578]\d{9}$/.test(phoneNumber)) {
self.dom.find('.phone-num-c').addClass('error');
} else {
self.dom.find('.phone-num-c').removeClass('error');
self.countDown();
}
});
};
PhoneVerifyCode.prototype.refreshImages = function () {
this.isMoving = false;
this.verifySucess = false;
this.canSendCode = false;
this.countDownEnd = false;
this.imgID = '';
this.dom.find('.slide-bar').removeClass('sucess error').css('width', '30px');
this.dom.find('.slide-trigger').removeClass('sucess error').css('left', '0px');
this.dom.find('.slide-txt').show();
this.dom.find('.slide-image-small').css('left', '0');
this.dom.find('.verify-code-send-btn').addClass('__disabled');
var self = this;
$.ajax({
url: '/slideImage',
type: 'get',
success: function(res) {
if (res && res.Code === 0) {
self.imgID = res.Message;
self.dom.find('.slide-image-big').css('background', `url("/slideimage/${res.Message}.png")`);
self.dom.find('.slide-image-small').css('background', `url("/slideimage/${res.Message}screenshot.png")`);
}
},
error: function(err) {
console.log(err);
}
});
};
PhoneVerifyCode.prototype.countDown = function () {
var self = this;
var sendBtnEl = this.dom.find('.verify-code-send-btn');
var count = this.countDownNumber;
sendBtnEl.addClass('__disabled').text(`${count}S后重发`);
this.canSendCode = false;
this.countDownEnd = false;
var timer = setInterval(function () {
count--;
sendBtnEl.addClass('__disabled').text(`${count}S后重发`);
if (count <= 0) {
sendBtnEl.removeClass('__disabled').text(`获取验证码`);
clearInterval(timer);
self.canSendCode = true;
self.countDownEnd = true;
}
}, 1000);
};
const phoneVerifyCode = new PhoneVerifyCode($('.phone-verify-code'));
});
</script>

+ 4
- 0
templates/user/auth/signup_inner.tmpl View File

@@ -64,6 +64,10 @@
</div> </div>
{{end}} {{end}}
{{if .EnablePhone }}
{{template "user/auth/phone_verify" .}}
{{end}}

<div class="ui hidden divider"></div> <div class="ui hidden divider"></div>


<div class="center aligned field"> <div class="center aligned field">


Loading…
Cancel
Save