| @@ -1 +1,79 @@ | |||
| {{template "base/head" .}} | |||
| <div class="user bindphone forgot password" style="margin-top: 20px;"> | |||
| <div class="ui middle very relaxed page grid"> | |||
| <div class="column"> | |||
| <form class="ui form ignore-dirty" action="" method=""> | |||
| {{.CsrfTokenHtml}} | |||
| <h2 class="ui top attached header"> | |||
| {{/*.i18n.Tr "auth.forgot_password_title"*/}} | |||
| 请绑定手机号 | |||
| </h2> | |||
| <div class="ui attached segment"> | |||
| {{template "base/alert" .}} | |||
| <div style="display:none;" class="ui negative message"> | |||
| <p></p> | |||
| </div> | |||
| {{if .EnablePhone }} | |||
| <div style="display:flex;justify-content:center;"> | |||
| <div class="use-type" usetype="2" autofocus="true" style="width:491px;" showlabel="true" > | |||
| {{template "user/auth/phone_verify" .}} | |||
| </div> | |||
| </div> | |||
| <style> | |||
| .use-type ._label-c { | |||
| display: flex; | |||
| } | |||
| </style> | |||
| {{end}} | |||
| <div class="ui divider"></div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui blue button">{{/*.i18n.Tr "auth.send_reset_mail"*/}}提交</button> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| <script> | |||
| (function() { | |||
| window.addEventListener('load', function () { | |||
| var bindPhoneEl = $('.bindphone'); | |||
| bindPhoneEl.find('button.button').off('click').on('click', function(e) { | |||
| var phoneNumber = bindPhoneEl.find('input.phoneNumber').val(); | |||
| var verifyCode = bindPhoneEl.find('input.verifyCode').val(); | |||
| if (phoneNumber && verifyCode) { | |||
| e.preventDefault(); | |||
| if (!/^1[3578]\d{9}$/.test(phoneNumber)) { | |||
| bindPhoneEl.find('.ui.negative.message').show().find('p').text('请输入正确的手机号'); | |||
| return; | |||
| } | |||
| if (!/^\d{6}$/.test(verifyCode)) { | |||
| bindPhoneEl.find('.ui.negative.message').show().find('p').text('请输入正确格式的手机验证码'); | |||
| return; | |||
| } | |||
| $.ajax({ | |||
| url: '/bindPhone', | |||
| type: 'post', | |||
| dataType: 'json', | |||
| data: { | |||
| phone_number: phoneNumber, | |||
| verify_code: phoneNumber | |||
| }, | |||
| success: function(res) { | |||
| if (res && res.Code === 0) { | |||
| window.location.href = '/dashboard'; | |||
| } else { | |||
| bindPhoneEl.find('.ui.negative.message').show().find('p').text(res.Message); | |||
| } | |||
| }, | |||
| error: function(err) { | |||
| console.log(err); | |||
| } | |||
| }); | |||
| } | |||
| }); | |||
| }); | |||
| })(); | |||
| </script> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -1,4 +1,14 @@ | |||
| {{template "base/head" .}} | |||
| <div class="ui secondary pointing tabular top attached borderless menu new-menu navbar"> | |||
| <a class="active item" rel="nofollow" href="{{AppSubUrl}}/user/forgot_password"> | |||
| {{/* 手机验证码登陆 .i18n.Tr "auth.login_userpass" */}} | |||
| 邮箱找回密码 | |||
| </a> | |||
| <a class="item" rel="nofollow" href="{{AppSubUrl}}/user/forgot_password?type=phone"> | |||
| {{/* .i18n.Tr "auth.login_userpass" */}} | |||
| 手机号找回密码 | |||
| </a> | |||
| </div> | |||
| <div class="user forgot password"> | |||
| <div class="ui middle very relaxed page grid"> | |||
| <div class="column"> | |||
| @@ -0,0 +1,47 @@ | |||
| {{template "base/head" .}} | |||
| <div class="ui secondary pointing tabular top attached borderless menu new-menu navbar"> | |||
| <a class="item" rel="nofollow" href="{{AppSubUrl}}/user/forgot_password"> | |||
| {{/* 手机验证码登陆 .i18n.Tr "auth.login_userpass" */}} | |||
| 邮箱找回密码 | |||
| </a> | |||
| <a class="active item" rel="nofollow" href="{{AppSubUrl}}/user/forgot_password?type=phone"> | |||
| {{/* .i18n.Tr "auth.login_userpass" */}} | |||
| 手机号找回密码 | |||
| </a> | |||
| </div> | |||
| <div class="user forgot password"> | |||
| <div class="ui middle very relaxed page grid"> | |||
| <div class="column"> | |||
| <form class="ui form ignore-dirty" action="{{AppSubUrl}}/user/recover_account_by_phone" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <h2 class="ui top attached header"> | |||
| {{.i18n.Tr "auth.forgot_password_title"}} | |||
| </h2> | |||
| <div class="ui attached segment"> | |||
| {{template "base/alert" .}} | |||
| {{if .EnablePhone }} | |||
| <div style="display:flex;justify-content:center;"> | |||
| <div class="use-type" usetype="3" style="width:491px;" showlabel="true" shownewpwd="true" autofocus="true"> | |||
| {{template "user/auth/phone_verify" .}} | |||
| </div> | |||
| </div> | |||
| <style> | |||
| .use-type ._label-c, .use-type .new-pass-word-wrap { | |||
| display: flex; | |||
| } | |||
| </style> | |||
| {{end}} | |||
| <div class="ui divider"></div> | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui blue button">{{/*.i18n.Tr "auth.send_reset_mail"*/}}提交</button> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| @@ -1,7 +1,30 @@ | |||
| <style> | |||
| .phone-verify-code { | |||
| max-width: 519px; | |||
| } | |||
| .phone-verify-code ._label-c { | |||
| display: flex; | |||
| justify-content: fixed-start; | |||
| align-items: center; | |||
| width: 100px; | |||
| display: none; | |||
| } | |||
| .phone-verify-code ._label-c ._label { | |||
| font-size: 13px; | |||
| font-weight: 700; | |||
| color: rgba(0,0,0,.87); | |||
| } | |||
| .phone-verify-code ._label-c.required ._label:after { | |||
| margin: -0.2em 0 0 0.2em; | |||
| content: '*'; | |||
| color: #db2828; | |||
| display: inline-block; | |||
| vertical-align: top; | |||
| } | |||
| .phone-c { | |||
| display: flex; | |||
| margin: 0 0 1em; | |||
| @@ -40,7 +63,7 @@ | |||
| outline: none; | |||
| } | |||
| .slide-bar-c { | |||
| .slide-bar-wrap { | |||
| display: flex; | |||
| height: 38px; | |||
| margin: 0 0 1em; | |||
| @@ -49,6 +72,15 @@ | |||
| position: relative; | |||
| } | |||
| .slide-bar-c { | |||
| flex: 1; | |||
| display: flex; | |||
| height: 38px; | |||
| justify-content: center; | |||
| align-items: center; | |||
| position: relative; | |||
| } | |||
| .slide-bar-c .slide-bar-bg { | |||
| height: 34px; | |||
| flex: 1; | |||
| @@ -187,9 +219,39 @@ | |||
| background-color: #ddd; | |||
| cursor: not-allowed; | |||
| } | |||
| .new-pass-word-wrap { | |||
| display: flex; | |||
| height: 38px; | |||
| margin: 0 0 1em; | |||
| justify-content: center; | |||
| align-items: center; | |||
| display: none; | |||
| } | |||
| .new-pass-word-wrap .new-pass-word-c { | |||
| flex: 1; | |||
| height: 38px; | |||
| box-sizing: border-box; | |||
| justify-content: center; | |||
| align-items: center; | |||
| display: flex; | |||
| } | |||
| .new-pass-word-wrap .new-pass-word-c input { | |||
| height: 100%; | |||
| width: 100% !important; | |||
| padding: 9.5px 14px; | |||
| box-sizing: border-box; | |||
| border: none; | |||
| outline: none; | |||
| } | |||
| </style> | |||
| <div class="phone-verify-code"> | |||
| <div class="phone-c"> | |||
| <div class="phone-label _label-c required"> | |||
| <span class="_label">手机号码</span> | |||
| </div> | |||
| <div class="phone-area-c"> | |||
| <select value="+86"> | |||
| <option value="+86">+86</option> | |||
| @@ -199,17 +261,24 @@ | |||
| <input class="phoneNumber" style="width:100% !important" name="phone_number" value="{{.phone_number}}" placeholder="手机号码" required autocomplete="off" /> | |||
| </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 class="slide-bar-wrap" style="display:flex;"> | |||
| <div class="slide-bar-label _label-c required" style=""></div> | |||
| <div class="slide-bar-c" style="flex:1;"> | |||
| <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> | |||
| <div class="verify-code-c"> | |||
| <div class="verify-code-label _label-c required"> | |||
| <span class="_label">手机验证码</span> | |||
| </div> | |||
| <div class="verify-code-num-c"> | |||
| <input class="verifyCode" style="width:100% !important" name="verify_code" value="{{.verify_code}}" placeholder="请输入短信验证码" required autocomplete="off" /> | |||
| </div> | |||
| @@ -217,9 +286,28 @@ | |||
| <div class="verify-code-send-btn __disabled">获取验证码</div> | |||
| </div> | |||
| </div> | |||
| <div class="new-pass-word-wrap"> | |||
| <div class="new-pass-word-label _label-c required"> | |||
| <span class="_label">新的登录密码</span> | |||
| </div> | |||
| <div class="new-pass-word-c"> | |||
| <input class="newPassword" style="width:100% !important" name="password" type="password" placeholder="请输入新的密码" required autocomplete="off" /> | |||
| </div> | |||
| </div> | |||
| <div class="new-pass-word-wrap"> | |||
| <div class="new-pass-word-label _label-c required"></div> | |||
| <div class="field" style="flex:1;"> | |||
| <div class="ui checkbox"> | |||
| <label>{{.i18n.Tr "auth.remember_me"}}</label> | |||
| <input name="remember" type="checkbox"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <script> | |||
| window.addEventListener('load', function () { | |||
| (function() { | |||
| window.addEventListener('load', function () { | |||
| function PhoneVerifyCode(dom) { | |||
| if (!dom) return; | |||
| this.countDownNumber = 20; | |||
| @@ -236,6 +324,27 @@ | |||
| this.imgID = ''; | |||
| this.eventInit(); | |||
| this.refreshImages(); | |||
| var wrap = this.dom.closest('div.use-type'); | |||
| var oldPhoneNum = wrap.attr('ophonenumber'); | |||
| if (oldPhoneNum) { | |||
| this.dom.find('input.phoneNumber').val(oldPhoneNum); | |||
| } | |||
| var showlabel = wrap.attr('showlabel'); | |||
| if (showlabel) { | |||
| this.dom.find('._label-c ').show(); | |||
| } else { | |||
| this.dom.find('._label-c ').hide(); | |||
| } | |||
| var showNewpwd = wrap.attr('shownewpwd'); | |||
| if (showNewpwd) { | |||
| this.dom.find('.new-pass-word-wrap').show(); | |||
| } else { | |||
| this.dom.find('.new-pass-word-wrap').remove(); | |||
| } | |||
| var autofocus = wrap.attr('autofocus'); | |||
| if (autofocus) { | |||
| this.dom.find('input.phoneNumber').focus(); | |||
| } | |||
| }; | |||
| PhoneVerifyCode.prototype.eventInit = function () { | |||
| @@ -415,4 +524,5 @@ | |||
| const phoneVerifyCode = new PhoneVerifyCode($('.phone-verify-code')); | |||
| }); | |||
| })(); | |||
| </script> | |||
| @@ -23,9 +23,9 @@ | |||
| <div class="column"> | |||
| <form class="ui form" action="/user/login/phone" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| {{if .EnablePhone }} | |||
| <div class="use-type" usetype="1"> | |||
| <div class="use-type" usetype="1" autofocus="true"> | |||
| {{template "user/auth/phone_verify" .}} | |||
| </div> | |||
| {{end}} | |||
| @@ -33,13 +33,13 @@ | |||
| <input name="keep_email_private" type="checkbox" {{if .SignedUser.KeepEmailPrivate}}checked{{end}}> | |||
| </div> | |||
| </div> | |||
| {{if .EnablePhone }} | |||
| <div class="field required" style="width:400px;"> | |||
| <label for="phone">{{/* .i18n.Tr "phone" */}} 手机号码</label> | |||
| <div class="use-type" usetype="2"> | |||
| {{template "user/auth/phone_verify" .}} | |||
| </div> | |||
| {{if .EnablePhone }} | |||
| <div class="field required" style="width:391px;"> | |||
| <label for="phone">{{/* .i18n.Tr "phone" */}} 手机号码</label> | |||
| <div class="use-type" usetype="2" ophonenumber="{{.SignedUser.PhoneNumber}}"> | |||
| {{template "user/auth/phone_verify" .}} | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| <div class="field {{if .Err_Description}}error{{end}}"> | |||
| <label for="description">{{$.i18n.Tr "user.user_bio"}}</label> | |||