mirror of https://github.com/jumpserver/jumpserver
perf: 增加国际电话区号选择
parent
973df0360c
commit
f606dd8920
|
@ -19,3 +19,17 @@ class Status(models.TextChoices):
|
|||
failed = 'failed', _("Failed")
|
||||
error = 'error', _("Error")
|
||||
canceled = 'canceled', _("Canceled")
|
||||
|
||||
|
||||
COUNTRY_CALLING_CODES = [
|
||||
{'name': 'China(中国)', 'value': '+86'},
|
||||
{'name': 'HongKong(中国香港)', 'value': '+852'},
|
||||
{'name': 'Macao(中国澳门)', 'value': '+853'},
|
||||
{'name': 'Taiwan(中国台湾)', 'value': '+886'},
|
||||
{'name': 'America(America)', 'value': '+1'}, {'name': 'Russia(Россия)', 'value': '+7'},
|
||||
{'name': 'France(français)', 'value': '+33'},
|
||||
{'name': 'Britain(Britain)', 'value': '+44'},
|
||||
{'name': 'Germany(Deutschland)', 'value': '+49'},
|
||||
{'name': 'Japan(日本)', 'value': '+81'}, {'name': 'Korea(한국)', 'value': '+82'},
|
||||
{'name': 'India(भारत)', 'value': '+91'}
|
||||
]
|
||||
|
|
|
@ -3,6 +3,7 @@ from rest_framework import generics
|
|||
from rest_framework.permissions import AllowAny
|
||||
|
||||
from authentication.permissions import IsValidUserOrConnectionToken
|
||||
from common.const.choices import COUNTRY_CALLING_CODES
|
||||
from common.utils import get_logger, lazyproperty
|
||||
from common.utils.timezone import local_now
|
||||
from .. import serializers
|
||||
|
@ -24,7 +25,8 @@ class OpenPublicSettingApi(generics.RetrieveAPIView):
|
|||
def get_object(self):
|
||||
return {
|
||||
"XPACK_ENABLED": settings.XPACK_ENABLED,
|
||||
"INTERFACE": self.interface_setting
|
||||
"INTERFACE": self.interface_setting,
|
||||
"COUNTRY_CALLING_CODES": COUNTRY_CALLING_CODES
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ __all__ = [
|
|||
class PublicSettingSerializer(serializers.Serializer):
|
||||
XPACK_ENABLED = serializers.BooleanField()
|
||||
INTERFACE = serializers.DictField()
|
||||
COUNTRY_CALLING_CODES = serializers.ListField()
|
||||
|
||||
|
||||
class PrivateSettingSerializer(PublicSettingSerializer):
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
.margin-bottom {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.input-style {
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
|
@ -22,6 +23,19 @@
|
|||
height: 100%;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.scrollable-menu {
|
||||
height: auto;
|
||||
max-height: 18rem;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
.input-group-btn .btn-secondary {
|
||||
color: #464a4c;
|
||||
background-color: #eceeef;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block html_title %}{% trans 'Forgot password' %}{% endblock %}
|
||||
|
@ -57,9 +71,26 @@
|
|||
placeholder="{% trans 'Email account' %}" value="{{ email }}">
|
||||
</div>
|
||||
<div id="validate-sms" class="validate-field margin-bottom">
|
||||
<input type="tel" id="sms" name="sms" class="form-control input-style"
|
||||
placeholder="{% trans 'Mobile number' %}" value="{{ sms }}">
|
||||
<small style="color: #999; margin-left: 5px">{{ form.sms.help_text }}</small>
|
||||
<div class="input-group">
|
||||
<div class="input-group-btn">
|
||||
<button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
<span class="country-code-value">+86</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu scrollable-menu">
|
||||
{% for country in countries %}
|
||||
<li>
|
||||
<a href="#" class="dropdown-item d-flex justify-content-between">
|
||||
<span class="country-name text-left">{{ country.name }}</span>
|
||||
<span class="country-code">{{ country.value }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<input type="tel" id="sms" name="sms" class="form-control input-style"
|
||||
placeholder="{% trans 'Mobile number' %}" value="{{ sms }}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="margin-bottom challenge-required">
|
||||
<input type="text" id="code" name="code" class="form-control input-style"
|
||||
|
@ -76,7 +107,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(function (){
|
||||
$(function () {
|
||||
const validateSelectRef = $('#validate-backend-select')
|
||||
const formType = $('input[name="form_type"]').val()
|
||||
validateSelectRef.val(formType)
|
||||
|
@ -84,19 +115,31 @@
|
|||
selectChange(formType);
|
||||
}
|
||||
})
|
||||
|
||||
$(".dropdown-menu li a").click(function (evt) {
|
||||
const inputGroup = $('.input-group');
|
||||
const inputGroupAddon = inputGroup.find('.country-code-value');
|
||||
const selectedCountry = $(evt.target).closest('li');
|
||||
const selectedCountryCode = selectedCountry.find('.country-code').html();
|
||||
inputGroupAddon.html(selectedCountryCode)
|
||||
});
|
||||
|
||||
|
||||
function getQueryString(name) {
|
||||
const reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");
|
||||
const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
|
||||
const r = window.location.search.substr(1).match(reg);
|
||||
if(r !== null)
|
||||
if (r !== null)
|
||||
return unescape(r[2])
|
||||
return null
|
||||
}
|
||||
|
||||
function selectChange(name) {
|
||||
$('.validate-field').hide()
|
||||
$('#validate-' + name).show()
|
||||
$('#validate-' + name + '-tip').show()
|
||||
$('input[name="form_type"]').attr('value', name)
|
||||
}
|
||||
|
||||
function sendChallengeCode(currentBtn) {
|
||||
let time = 60;
|
||||
const token = getQueryString('token')
|
||||
|
@ -104,7 +147,7 @@
|
|||
|
||||
const formType = $('input[name="form_type"]').val()
|
||||
const email = $('#email').val()
|
||||
const sms = $('#sms').val()
|
||||
let sms = $('#sms').val();
|
||||
const errMsg = "{% trans 'The {} cannot be empty' %}"
|
||||
|
||||
if (formType === 'sms') {
|
||||
|
@ -118,10 +161,11 @@
|
|||
return
|
||||
}
|
||||
}
|
||||
|
||||
sms = $(".input-group .country-code-value").html() + sms
|
||||
const data = {
|
||||
form_type: formType, email: email, sms: sms,
|
||||
}
|
||||
|
||||
function onSuccess() {
|
||||
const originBtnText = currentBtn.innerHTML;
|
||||
currentBtn.disabled = true
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.views.generic import FormView, RedirectView
|
|||
|
||||
from authentication.errors import IntervalTooShort
|
||||
from authentication.utils import check_user_property_is_correct
|
||||
from common.const.choices import COUNTRY_CALLING_CODES
|
||||
from common.utils import FlashMessageUtil, get_object_or_none, random_string
|
||||
from common.utils.verify_code import SendAndVerifyCodeUtil
|
||||
from users.notifications import ResetPasswordSuccessMsg
|
||||
|
@ -108,7 +109,7 @@ class UserForgotPasswordView(FormView):
|
|||
for k, v in cleaned_data.items():
|
||||
if v:
|
||||
context[k] = v
|
||||
|
||||
context['countries'] = COUNTRY_CALLING_CODES
|
||||
context['form_type'] = 'email'
|
||||
context['XPACK_ENABLED'] = settings.XPACK_ENABLED
|
||||
validate_backends = self.get_validate_backends_context(has_phone)
|
||||
|
|
Loading…
Reference in New Issue