diff --git a/templates/user/auth/phone_verify.tmpl b/templates/user/auth/phone_verify.tmpl
index d774156d7..e6b3ac8fb 100644
--- a/templates/user/auth/phone_verify.tmpl
+++ b/templates/user/auth/phone_verify.tmpl
@@ -1,278 +1,4 @@
-
-
+
-
+
diff --git a/web_src/js/standalone/phoneverify.js b/web_src/js/standalone/phoneverify.js
new file mode 100644
index 000000000..555924c90
--- /dev/null
+++ b/web_src/js/standalone/phoneverify.js
@@ -0,0 +1,256 @@
+; (function () {
+ function PhoneVerifyCode(dom, options) {
+ if (!dom) return;
+ this.countDownNumber = 120;
+ this.options = options;
+ 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();
+ var wrap = this.dom.closest('div.use-type');
+ var readonly = wrap.attr('readonly');
+ if (readonly) {
+ this.dom.find('.phone-area-c select').attr('disabled', true);
+ this.dom.find('.phone-num-c input').attr('disabled', true);
+ this.dom.find('.slide-bar-wrap').hide();
+ this.dom.find('.verify-code-c').hide();
+ this.dom.find('.modify-phone-number').show();
+ }
+ 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();
+ }
+ var verifyCodeNoRequired = wrap.attr('verifycodenorequired');
+ if (verifyCodeNoRequired) {
+ this.dom.find('input.verifyCode').removeAttr('required');
+ }
+ };
+
+ 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: {
+ slide_id: self.imgID,
+ x: parseInt(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-trigger .icon').hide();
+ self.dom.find('.slide-trigger .icon.check').show();
+ 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');
+ self.dom.find('.slide-trigger .icon').hide();
+ self.dom.find('.slide-trigger .icon.close').show();
+ 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 phoneNumber = self.dom.find('.phone-num-c input').val();
+ if (!/^1[3578]\d{9}$/.test(phoneNumber)) {
+ self.dom.find('.phone-num-c').addClass('error');
+ return;
+ } else {
+ self.dom.find('.phone-num-c').removeClass('error');
+ var useType = self.dom.closest('div.use-type').attr('usetype') || 0;
+ $.ajax({
+ url: '/sendVerifyCode',
+ type: 'post',
+ dataType: 'json',
+ data: {
+ phone_number: phoneNumber,
+ mode: useType, // 0注册,1登录 ,2修改手机号,3找回密码
+ slide_id: self.imgID,
+ },
+ success: function (res) {
+ if (res && res.Code === 0) {
+ self.countDown();
+ } else {
+ if ($('.ui.negative.message').length) {
+ $('.ui.negative.message').eq(0).show().find('p').text(res.Message);
+ } else {
+ $('body').toast({
+ message: res.Message,
+ showProgress: 'bottom',
+ showIcon: 'warning circle',
+ class: 'warning',
+ position: 'top right',
+ });
+ }
+ self.refreshImages();
+ }
+ },
+ error: function (err) {
+ console.log(err);
+ }
+ });
+ }
+ });
+
+ this.dom.find('.modify-phone-number a').on('click', function () {
+ self.dom.find('.phone-area-c select').attr('disabled', false);
+ self.dom.find('.phone-num-c input').attr('disabled', false);
+ self.dom.find('.slide-bar-wrap').css('display', 'flex');
+ self.dom.find('.verify-code-c').css('display', 'flex');
+ self.dom.find('.modify-phone-number').hide();
+ });
+ };
+
+ 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-trigger .icon').hide();
+ this.dom.find('.slide-trigger .icon.arrow').show();
+ 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 + (self.options && self.options.Lang && self.options.Lang.second_resend ? self.options.Lang.second_resend : 'S后重发'));
+ this.canSendCode = false;
+ this.countDownEnd = false;
+ var timer = setInterval(function () {
+ count--;
+ sendBtnEl.addClass('__disabled').text(count + (self.options && self.options.Lang && self.options.Lang.second_resend ? self.options.Lang.second_resend : 'S后重发'));
+ if (count <= 0) {
+ sendBtnEl.removeClass('__disabled').text(+ (self.options && self.options.Lang && self.options.Lang.get_verification_code ? self.options.Lang.get_verification_code : '获取验证码'));
+ clearInterval(timer);
+ self.canSendCode = true;
+ self.countDownEnd = true;
+ self.refreshImages();
+ }
+ }, 1000);
+ };
+
+ window.PhoneVerifyCode = PhoneVerifyCode;
+})();
diff --git a/web_src/less/standalone/_phoneverify.less b/web_src/less/standalone/_phoneverify.less
new file mode 100644
index 000000000..4ed2940ac
--- /dev/null
+++ b/web_src/less/standalone/_phoneverify.less
@@ -0,0 +1,274 @@
+.__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-verify-code .phone-c {
+ display: flex;
+ margin: 0 0 1em;
+}
+
+.__phone-verify-code .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-verify-code .phone-c .phone-area-c select {
+ outline: none;
+}
+
+.__phone-verify-code .phone-c .phone-num-c {
+ height: 38px;
+ flex: 1;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-sizing: border-box;
+ position: relative;
+}
+
+.__phone-verify-code .phone-c .phone-num-c input {
+ height: 100%;
+ width: 100% !important;
+ padding: 9.5px 14px;
+ box-sizing: border-box;
+ outline: none;
+}
+
+.__phone-verify-code .phone-c .modify-phone-number {
+ position: absolute;
+ left: 100%;
+ width: 200px;
+ height: 100%;
+ margin-left: 10px;
+ display: none;
+}
+
+.__phone-verify-code .phone-c .modify-phone-number a {
+ font-weight: 400;
+ font-size: 14px;
+ color: rgba(0, 102, 255, 1);
+}
+
+.__phone-verify-code .slide-bar-wrap {
+ display: flex;
+ height: 38px;
+ margin: 0 0 1em;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+}
+
+.__phone-verify-code .slide-bar-c {
+ flex: 1;
+ display: flex;
+ height: 38px;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+}
+
+.__phone-verify-code .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;
+}
+
+.__phone-verify-code .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;
+}
+
+.__phone-verify-code .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;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-bar.sucess {
+ background-color: #d2f4ef;
+ border: 1px solid #52ccba;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-bar.error {
+ border-color: #f57a7a;
+ background-color: #fce1e1;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-trigger {
+ position: absolute;
+ width: 38px;
+ height: 34px;
+ background-color: #1991fa;
+ border-radius: 2px;
+ cursor: pointer;
+ top: -1px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ user-select: none;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-trigger .icon {
+ font-size: 16px;
+ color: white;
+ margin: 0;
+ height: 16px;
+ width: 16px;
+ margin-top: -5px;
+ user-select: none;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-trigger.sucess {
+ background-color: #52ccba;
+}
+
+.__phone-verify-code .slide-bar-c .slide-bar-bg .slide-trigger.error {
+ background-color: #f57a7a;
+}
+
+.__phone-verify-code .slide-bar-c .slide-image-big {
+ position: absolute;
+ width: 391px;
+ height: 196px;
+ top: 36px;
+ left: 0;
+ border-radius: 2px;
+ z-index: 100;
+ display: none;
+}
+
+.__phone-verify-code .slide-bar-c .slide-image-small {
+ position: absolute;
+ left: 0;
+ width: 51px;
+ height: 51px;
+ box-shadow: 0 0 4px rgb(35 173 255);
+}
+
+.__phone-verify-code .slide-bar-c .verify-code-c {
+ display: flex;
+ height: 38px;
+}
+
+.__phone-verify-code .verify-code-c {
+ display: flex;
+ height: 38px;
+ margin: 0 0 1em;
+ justify-content: center;
+ align-items: center;
+}
+
+.__phone-verify-code .verify-code-c .verify-code-num-c {
+ flex: 1;
+ height: 38px;
+ box-sizing: border-box;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+}
+
+.__phone-verify-code .verify-code-c .verify-code-num-c input {
+ height: 100%;
+ width: 100% !important;
+ padding: 9.5px 14px;
+ box-sizing: border-box;
+ outline: none;
+}
+
+.__phone-verify-code .verify-code-c .verify-code-send {
+ display: flex;
+ width: 120px;
+ height: 38px;
+ justify-content: center;
+ align-items: center;
+}
+
+.__phone-verify-code .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;
+}
+
+.__phone-verify-code .verify-code-c .verify-code-send .verify-code-send-btn.__disabled {
+ border: 1px solid #ddd;
+ background-color: #ddd;
+ cursor: not-allowed;
+}
+
+.__phone-verify-code .new-pass-word-wrap {
+ display: flex;
+ height: 38px;
+ margin: 0 0 1em;
+ justify-content: center;
+ align-items: center;
+ display: none;
+}
+
+.__phone-verify-code .new-pass-word-wrap .new-pass-word-c {
+ flex: 1;
+ height: 38px;
+ box-sizing: border-box;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+}
+
+.__phone-verify-code .new-pass-word-wrap .new-pass-word-c input {
+ height: 100%;
+ width: 100% !important;
+ padding: 9.5px 14px;
+ box-sizing: border-box;
+ outline: none;
+}
diff --git a/webpack.config.js b/webpack.config.js
index cd3635427..d209a1683 100755
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -20,6 +20,15 @@ for (const path of glob('web_src/less/themes/*.less')) {
themes[parse(path).name] = [path];
}
+const standalone = {};
+const stadalonePaths = [
+ ...glob('web_src/js/standalone/*.js'),
+ ...glob('web_src/less/standalone/*.less'),
+];
+for (const path of stadalonePaths) {
+ standalone[parse(path).name] = [path];
+}
+
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
@@ -29,13 +38,11 @@ module.exports = {
resolve(__dirname, 'web_src/js/index.js'),
resolve(__dirname, 'web_src/less/index.less'),
],
- swagger: [
- resolve(__dirname, 'web_src/js/standalone/swagger.js'),
- ],
jquery: [
resolve(__dirname, 'web_src/js/jquery.js'),
],
icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
+ ...standalone,
...themes,
},
devtool: false,
diff --git a/webpack_pro.config.js b/webpack_pro.config.js
index c5d204b02..7ea94bbb9 100755
--- a/webpack_pro.config.js
+++ b/webpack_pro.config.js
@@ -20,6 +20,15 @@ for (const path of glob('web_src/less/themes/*.less')) {
themes[parse(path).name] = [path];
}
+const standalone = {};
+const stadalonePaths = [
+ ...glob('web_src/js/standalone/*.js'),
+ ...glob('web_src/less/standalone/*.less'),
+];
+for (const path of stadalonePaths) {
+ standalone[parse(path).name] = [path];
+}
+
const isProduction = process.env.NODE_ENV !== 'development';
module.exports = {
@@ -29,13 +38,11 @@ module.exports = {
resolve(__dirname, 'web_src/js/index.js'),
resolve(__dirname, 'web_src/less/index.less'),
],
- swagger: [
- resolve(__dirname, 'web_src/js/standalone/swagger.js'),
- ],
jquery: [
resolve(__dirname, 'web_src/js/jquery.js'),
],
icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'),
+ ...standalone,
...themes,
},
devtool: false,