perf: Modify the layout to flex

pull/15760/head
wangruidong 2025-07-18 15:50:50 +08:00 committed by 老广
parent c4a348aac6
commit 6095e9c9bd
5 changed files with 148 additions and 112 deletions

View File

@ -69,23 +69,27 @@
} }
.login-content { .login-content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 500px; height: 500px;
width: 1000px; width: 1000px;
margin-top: auto;
margin-bottom: auto;
} }
body { body {
position: relative; box-sizing: border-box;
min-height: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
width: 100vw; width: 100vw;
height: 100vh; height: 100vh;
background-color: #f3f3f3; background-color: #f3f3f3;
{#height: calc(100vh - (100vh - 470px) / 3);#} {#height: calc(100vh - (100vh - 470px) / 3);#}
} }
.captcha { .captcha {
float: right; float: right;
} }
@ -138,7 +142,7 @@
} }
.jms-title { .jms-title {
{#padding: 22px 10px 10px;#} {#padding: 22px 10px 10px;#}
} }
.more-login-items { .more-login-items {
@ -318,7 +322,7 @@
</div> </div>
<div class="left-form-box {% if not form.challenge and not form.captcha %} no-captcha-challenge {% endif %}"> <div class="left-form-box {% if not form.challenge and not form.captcha %} no-captcha-challenge {% endif %}">
<div class="mobile-logo" style="padding-bottom: 45px; box-sizing: border-box"> <div class="mobile-logo" style="padding-bottom: 45px; box-sizing: border-box">
<div class="jms-title"> <div class="jms-title">
<img style="width: 60px; height: 60px" src="{{ INTERFACE.logo_logout }}" alt="Logo"/> <img style="width: 60px; height: 60px" src="{{ INTERFACE.logo_logout }}" alt="Logo"/>
<span style="padding-left: 10px">{{ INTERFACE.login_title }}</span> <span style="padding-left: 10px">{{ INTERFACE.login_title }}</span>
</div> </div>
@ -330,17 +334,18 @@
</h2> </h2>
<ul class=" nav navbar-top-links navbar-right"> <ul class=" nav navbar-top-links navbar-right">
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle login-page-language" data-bs-toggle="dropdown" href="#" target="_blank"> <a class="dropdown-toggle login-page-language" data-bs-toggle="dropdown" href="#"
target="_blank">
<i class="fa fa-globe fa-lg" style="margin-right: 2px"></i> <i class="fa fa-globe fa-lg" style="margin-right: 2px"></i>
<span>{{ current_lang.title }}<b class="caret"></b></span> <span>{{ current_lang.title }}<b class="caret"></b></span>
</a> </a>
<ul class="dropdown-menu profile-dropdown dropdown-menu-right"> <ul class="dropdown-menu profile-dropdown dropdown-menu-right">
{% for lang in langs %} {% for lang in langs %}
<li> <li>
<a href="{% url 'i18n-switch' lang=lang.code %}"> <a href="{% url 'i18n-switch' lang=lang.code %}">
<span>{{ lang.title }}</span> <span>{{ lang.title }}</span>
</a> </a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</li> </li>
@ -350,11 +355,11 @@
<form id="login-form" action="" method="post" role="form" novalidate="novalidate"> <form id="login-form" action="" method="post" role="form" novalidate="novalidate">
{% csrf_token %} {% csrf_token %}
<div style="line-height: 17px;margin-bottom: 20px;color: #999999;"> <div style="line-height: 17px;margin-bottom: 20px;color: #999999;">
{% if form.non_field_errors %} {% if form.non_field_errors %}
<p class="help-block red-fonts"> <p class="help-block red-fonts">
{{ form.non_field_errors.as_text }} {{ form.non_field_errors.as_text }}
</p> </p>
{% endif %} {% endif %}
</div> </div>
{% bootstrap_field form.username show_label=False %} {% bootstrap_field form.username show_label=False %}
@ -365,15 +370,15 @@
name="{{ form.password.html_name }}"> name="{{ form.password.html_name }}">
{% if form.password.errors %} {% if form.password.errors %}
<p class="help-block" style="text-align: left"> <p class="help-block" style="text-align: left">
{{ form.password.errors.as_text }} {{ form.password.errors.as_text }}
</p> </p>
{% endif %} {% endif %}
</div> </div>
{% if form.challenge %} {% if form.challenge %}
{% bootstrap_field form.challenge show_label=False %} {% bootstrap_field form.challenge show_label=False %}
{% elif form.mfa_type %} {% elif form.mfa_type %}
<div class="form-group" style="display: flex"> <div class="form-group" style="display: flex">
{% include '_mfa_login_field.html' %} {% include '_mfa_login_field.html' %}
</div> </div>
{% elif form.captcha %} {% elif form.captcha %}
<div class="captcha-field"> <div class="captcha-field">
@ -403,25 +408,25 @@
</div> </div>
{% if demo_mode %} {% if demo_mode %}
<div> <div>
<p class="red-fonts" style='text-align: center;'> <p class="red-fonts" style='text-align: center;'>
{% trans 'Username' %}: demo {% trans 'Password' %}: jumpserver {% trans 'Username' %}: demo {% trans 'Password' %}: jumpserver
</p> </p>
</div> </div>
{% endif %} {% endif %}
<div class="more-login"> <div class="more-login">
{% if auth_methods %} {% if auth_methods %}
<div class="more-methods-title {{ current_lang.code }}"> <div class="more-methods-title {{ current_lang.code }}">
{% trans "More login options" %} {% trans "More login options" %}
</div> </div>
<div class="more-login-items"> <div class="more-login-items">
{% for method in auth_methods %} {% for method in auth_methods %}
<a href="{{ method.url }}" class="more-login-item"> <a href="{{ method.url }}" class="more-login-item">
<i class="fa"><img src="{{ method.logo }}" height="15" width="15"/> </i> <i class="fa"><img src="{{ method.logo }}" height="15" width="15"/> </i>
{{ method.name }} {{ method.name }}
</a> </a>
{% endfor %} {% endfor %}
</div> </div>
{% else %} {% else %}
<div class="text-center" style="display: inline-block;"> <div class="text-center" style="display: inline-block;">
@ -447,14 +452,16 @@
$('#password-hidden').val(passwordEncrypted); //返回给密码输入input $('#password-hidden').val(passwordEncrypted); //返回给密码输入input
$('#login-form').submit(); //post提交 $('#login-form').submit(); //post提交
} }
function checkHealth() { function checkHealth() {
let url = "{% url 'health' %}"; let url = "{% url 'health' %}";
requestApi({ requestApi({
url: url, url: url,
method: "GET", method: "GET",
flash_message: false, flash_message: false,
}) })
} }
setInterval(checkHealth, 30 * 1000); setInterval(checkHealth, 30 * 1000);
</script> </script>
</html> </html>

View File

@ -15,41 +15,55 @@
<style> <style>
.passwordBox { .passwordBox {
max-width: 560px; max-width: 560px;
margin: 0 auto; margin-bottom: auto;
padding: 100px 20px 20px 20px; padding: 100px 20px 20px 20px;
width: 100%;
} }
.ibox-content { .ibox-content {
padding: 30px; padding: 30px;
} }
.ibox-context-margin { .ibox-context-margin {
margin: 20px 0 0 0; margin: 20px 0 0 0;
} }
body {
box-sizing: border-box;
min-height: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
.wrapper {
margin: auto;
}
</style> </style>
{% block custom_head_css_js %} {% endblock %} {% block custom_head_css_js %} {% endblock %}
</head> </head>
<body class="gray-bg"> <body class="gray-bg">
<div class="passwordBox animated fadeInDown"> <div class="passwordBox animated fadeInDown">
<div class="row"> <div class="row">
<div class="col-md-12"> <div class="col-md-12">
<div class="ibox-content"> <div class="ibox-content">
<h2 class="font-bold"> <h2 class="font-bold">
{% block title %}{% endblock %} {% block title %}{% endblock %}
</h2> </h2>
<div class="ibox-context-margin"> <div class="ibox-context-margin">
{% block content %} {% endblock %} {% block content %} {% endblock %}
</div>
</div> </div>
</div> </div>
</div> </div>
<hr/> </div>
<div class="row"> <hr/>
<div class="col-md-12"> <div class="row">
{% include '_copyright.html' %} <div class="col-md-12">
</div> {% include '_copyright.html' %}
</div> </div>
</div> </div>
</div>
</body> </body>
{% include '_foot_js.html' %} {% include '_foot_js.html' %}
{% block custom_foot_js %} {% endblock %} {% block custom_foot_js %} {% endblock %}

View File

@ -18,14 +18,9 @@
} }
.markdown-footer { .markdown-footer {
position: absolute; flex-grow: 0;
bottom: 0; flex-shrink: 0;
left: 50%;
width: 285px; width: 285px;
transform: translate(-50%, -50%);
@media (min-width: 768px) {
top: 97%;
}
} }
.markdown-footer p { .markdown-footer p {
@ -55,7 +50,7 @@
}); });
const markdownContent = `{{ INTERFACE.footer_content|escapejs }}`; const markdownContent = `{{ INTERFACE.footer_content|escapejs }}`;
const markdownRef = document.getElementById('markdown-output'); const markdownRef = document.getElementById('markdown-output');
if (markdownRef && markdownContent) { if (markdownRef && markdownContent) {
const renderedContent = md.render(markdownContent.trim()); const renderedContent = md.render(markdownContent.trim());
markdownRef.innerHTML = renderedContent; markdownRef.innerHTML = renderedContent;

View File

@ -3,39 +3,59 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title> {{ INTERFACE.login_title }} </title> <title> {{ INTERFACE.login_title }} </title>
<link rel="shortcut icon" href="{{ INTERFACE.favicon }}" type="image/x-icon"> <link rel="shortcut icon" href="{{ INTERFACE.favicon }}" type="image/x-icon">
{% include '_head_css_js.html' %} {% include '_head_css_js.html' %}
<link href="{% static 'css/jumpserver.css' %}" rel="stylesheet"> <link href="{% static 'css/jumpserver.css' %}" rel="stylesheet">
<link href="{% static 'css/style.css' %}" rel="stylesheet"> <link href="{% static 'css/style.css' %}" rel="stylesheet">
<link rel="stylesheet" href="{% static 'css/otp.css' %}" /> <link rel="stylesheet" href="{% static 'css/otp.css' %}"/>
<script src="{% static "js/plugins/qrcode/qrcode.js" %}"></script> <script src="{% static "js/plugins/qrcode/qrcode.js" %}"></script>
</head> <style>
body {
box-sizing: border-box;
min-height: 100%;
display: flex;
align-items: center;
flex-direction: column;
}
<body style="background-color: #f3f3f4"> header {
<header> width: 100%;
<div class="logo"> flex-grow: 0;
<a href="{% url 'index' %}"> flex-shrink: 0;
<img src="{{ INTERFACE.logo_logout }}" alt="" width="50px" height="50px"/> }
</a>
<span style="font-size: 21px; line-height: 50px">{{ INTERFACE.login_title }}</span> .wrapper {
</div> margin: auto;
<div> }
<a href="{% url 'index' %}">{% trans 'Home page' %}</a> </style>
</div>
</header> </head>
<body>
{% block body %} <body style="background-color: #f3f3f4">
{% endblock %} <header>
</body> <div class="logo">
<footer> <a href="{% url 'index' %}">
<div style="margin-top: 100px;"> <img src="{{ INTERFACE.logo_logout }}" alt="" width="50px" height="50px"/>
{% include '_copyright.html' %} </a>
</div> <span style="font-size: 21px; line-height: 50px">{{ INTERFACE.login_title }}</span>
</footer> </div>
{% include '_foot_js.html' %} <div>
</body> <a href="{% url 'index' %}">{% trans 'Home page' %}</a>
</div>
</header>
<div class="wrapper">
{% block body %}
{% endblock %}
</div>
<footer>
<div style="margin-top: 100px;">
{% include '_copyright.html' %}
</div>
</footer>
{% include '_foot_js.html' %}
</body>
</html> </html>

View File

@ -20,11 +20,11 @@
<div id="wrapper"> <div id="wrapper">
<div id="page-wrapper" class="gray-bg"> <div id="page-wrapper" class="gray-bg">
{% include '_header_bar.html' %} {% include '_header_bar.html' %}
<div class="alert alert-info help-message alert-dismissable page-message" style="display: none"> <div class="alert alert-info help-message alert-dismissable page-message" style="display: none">
<button aria-hidden="true" data-dismiss="alert" class="close hide-btn" type="button">×</button> <button aria-hidden="true" data-dismiss="alert" class="close hide-btn" type="button">×</button>
{% block help_message %} {% block help_message %}
{% endblock %} {% endblock %}
</div> </div>
{% include '_message.html' %} {% include '_message.html' %}
{% block content %}{% endblock %} {% block content %}{% endblock %}
{% include '_footer.html' %} {% include '_footer.html' %}
@ -35,23 +35,23 @@
{% include '_foot_js.html' %} {% include '_foot_js.html' %}
{% block custom_foot_js %} {% endblock %} {% block custom_foot_js %} {% endblock %}
<script> <script>
function getMessagePathKey() { function getMessagePathKey() {
var path = window.location.pathname; var path = window.location.pathname;
var key = 'message_' + btoa(path); var key = 'message_' + btoa(path);
return key return key
}
$(document).ready(function () {
var pathKey = getMessagePathKey();
var hidden = window.localStorage.getItem(pathKey);
var hasMessage = $('.page-message').text().trim().length > 5;
if (!hidden && hasMessage) {
$(".help-message").show();
} }
}).on('click', '.hide-btn', function () {
var pathKey = getMessagePathKey(); $(document).ready(function () {
window.localStorage.setItem(pathKey, '1') var pathKey = getMessagePathKey();
}) var hidden = window.localStorage.getItem(pathKey);
var hasMessage = $('.page-message').text().trim().length > 5;
if (!hidden && hasMessage) {
$(".help-message").show();
}
}).on('click', '.hide-btn', function () {
var pathKey = getMessagePathKey();
window.localStorage.setItem(pathKey, '1')
})
</script> </script>
</html> </html>