Merge pull request '灾备' (#31) from xumingyang_branch into master
@ -0,0 +1,16 @@
|
||||
"""
|
||||
ASGI config for dnsip project.
|
||||
|
||||
It exposes the ASGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.asgi import get_asgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dnsip.settings")
|
||||
|
||||
application = get_asgi_application()
|
@ -0,0 +1,147 @@
|
||||
"""
|
||||
Django settings for dnsip project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 4.2.13.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/4.2/ref/settings/
|
||||
"""
|
||||
import os.path
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent
|
||||
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
|
||||
|
||||
# SECURITY WARNING: keep the secret key used in production secret!
|
||||
SECRET_KEY = "django-insecure-vzm$(@logtv#4_s0s6^z_m-bng@l4s&d3_3q0=wcfmyj!j$k+f"
|
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production!
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"web.apps.WebConfig",
|
||||
"corsheaders",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"corsheaders.middleware.CorsMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
#"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "dnsip.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [os.path.join(BASE_DIR, 'templates')],
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.debug",
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "dnsip.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
|
||||
|
||||
# DATABASES = {
|
||||
# "default": {
|
||||
# "ENGINE": "django.db.backends.sqlite3",
|
||||
# "NAME": BASE_DIR / "db.sqlite3",
|
||||
# }
|
||||
# }
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': 'db1',
|
||||
'USER': 'root',
|
||||
'PASSWORD': '185102xmy',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '3306',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/4.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/4.2/howto/static-files/
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / "static", # 假设您的静态文件放在项目根目录下的static文件夹
|
||||
]
|
||||
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
CORS_ALLOW_CREDENTIALS = True
|
||||
CORS_ORIGIN_ALLOW_ALL = True
|
||||
CORS_ALLOW_HEADERS = ("*")
|
||||
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'web/documents/') # 确保这个路径存在
|
||||
MEDIA_URL = '/media/'
|
@ -0,0 +1,32 @@
|
||||
"""
|
||||
URL configuration for dnsip project.
|
||||
|
||||
The `urlpatterns` list routes URLs to views. For more information please see:
|
||||
https://docs.djangoproject.com/en/4.2/topics/http/urls/
|
||||
Examples:
|
||||
Function views
|
||||
1. Add an import: from my_app import views
|
||||
2. Add a URL to urlpatterns: path('', views.home, name='home')
|
||||
Class-based views
|
||||
1. Add an import: from other_app.views import Home
|
||||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
|
||||
Including another URLconf
|
||||
1. Import the include() function: from django.urls import include, path
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
|
||||
from django.contrib import admin
|
||||
from django.shortcuts import HttpResponse
|
||||
from django.urls import path
|
||||
from django.conf.urls.static import static
|
||||
from django.conf import settings
|
||||
from web import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("admin/", admin.site.urls),
|
||||
path('virtual_ip/',views.virtual_ip,name = 'virtual_ip'),
|
||||
path('change_state/',views.change_state,name = 'change_state'),
|
||||
path('change_state_actively/',views.change_state_actively,name='change_state_actively'),
|
||||
|
||||
]+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
@ -0,0 +1,16 @@
|
||||
"""
|
||||
WSGI config for dnsip project.
|
||||
|
||||
It exposes the WSGI callable as a module-level variable named ``application``.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from django.core.wsgi import get_wsgi_application
|
||||
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dnsip.settings")
|
||||
|
||||
application = get_wsgi_application()
|
@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env python
|
||||
"""Django's command-line utility for administrative tasks."""
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dnsip.settings")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"Couldn't import Django. Are you sure it's installed and "
|
||||
"available on your PYTHONPATH environment variable? Did you "
|
||||
"forget to activate a virtual environment?"
|
||||
) from exc
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,39 @@
|
||||
import paramiko
|
||||
|
||||
#让132成为主网关
|
||||
def change1():
|
||||
# 创建SSH对象
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
# 连接服务器
|
||||
ssh.connect(hostname='192.168.111.138', port=22, username='xumingyang', password='185102')
|
||||
# 执行命令 关闭主网关 这样的话
|
||||
stdin, stdout, stderr = ssh.exec_command("echo '185102' | sudo -S systemctl stop keepalived.service")
|
||||
|
||||
# 等待命令执行完成
|
||||
stdout.channel.recv_exit_status()
|
||||
# 获取命令输出
|
||||
keepalived_state = stdout.read().decode('utf-8')
|
||||
print(keepalived_state)
|
||||
|
||||
# 关闭连接
|
||||
ssh.close()
|
||||
|
||||
def change2():
|
||||
# 创建SSH对象
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
# 连接服务器
|
||||
ssh.connect(hostname='192.168.111.138', port=22, username='xumingyang', password='185102')
|
||||
# 执行命令 关闭主网关 这样的话
|
||||
stdin, stdout, stderr = ssh.exec_command("echo '185102' | sudo -S systemctl start keepalived.service")
|
||||
# 等待命令执行完成
|
||||
stdout.channel.recv_exit_status()
|
||||
# 获取命令输出
|
||||
keepalived_state = stdout.read().decode('utf-8')
|
||||
print(keepalived_state)
|
||||
|
||||
# 关闭连接
|
||||
ssh.close()
|
@ -0,0 +1,91 @@
|
||||
import paramiko
|
||||
|
||||
def main():
|
||||
# 创建SSH对象
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
# 连接服务器
|
||||
ssh.connect(hostname='192.168.111.138', port=22, username='xumingyang', password='185102')
|
||||
|
||||
# 执行命令获取keepalived状态
|
||||
stdin, stdout, stderr = ssh.exec_command('systemctl status keepalived.service')
|
||||
|
||||
# 获取命令输出
|
||||
keepalived_state = stdout.read().decode('utf-8')
|
||||
|
||||
# print(keepalived_state)
|
||||
|
||||
# 执行命令获取ip状态
|
||||
stdin1, stdout1, stderr1 = ssh.exec_command('ip a')
|
||||
|
||||
# 获取命令输出
|
||||
ip_a = stdout1.read().decode('utf-8')
|
||||
|
||||
print(ip_a)
|
||||
# 关闭连接
|
||||
ssh.close()
|
||||
|
||||
ssh.connect(hostname='192.168.111.132', port=22, username='xumingyang', password='252237')
|
||||
|
||||
# 执行命令获取keepalived状态
|
||||
stdin2, stdout2, stderr2 = ssh.exec_command('systemctl status keepalived.service')
|
||||
|
||||
# 获取命令输出
|
||||
keepalived_state1 = stdout2.read().decode('utf-8')
|
||||
|
||||
# print(keepalived_state1)
|
||||
|
||||
# 执行命令获取ip状态
|
||||
stdin3, stdout3, stderr3 = ssh.exec_command('ip a')
|
||||
|
||||
# 获取命令输出
|
||||
ip_a1 = stdout3.read().decode('utf-8')
|
||||
|
||||
print(ip_a1)
|
||||
# 关闭连接
|
||||
ssh.close()
|
||||
|
||||
|
||||
virtual_ip = '192.168.111.139'
|
||||
if virtual_ip in ip_a:
|
||||
message='192.168.111.138 is Master'
|
||||
else:
|
||||
message='192.168.111.138 is Backup'
|
||||
|
||||
if virtual_ip not in ip_a1:
|
||||
message2='192.168.111.132 is Backup'
|
||||
else:
|
||||
message2='192.168.111.132 is Master'
|
||||
return message+' '+message2
|
||||
|
||||
def state():
|
||||
ssh = paramiko.SSHClient()
|
||||
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
# 连接服务器
|
||||
ssh.connect(hostname='192.168.111.138', port=22, username='xumingyang', password='185102')
|
||||
stdin1, stdout1, stderr1 = ssh.exec_command('ip a')
|
||||
|
||||
# 获取命令输出
|
||||
ip_a = stdout1.read().decode('utf-8')
|
||||
|
||||
virtual_ip = '192.168.111.139'
|
||||
if virtual_ip in ip_a:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
# 关闭连接
|
||||
ssh.close()
|
||||
|
||||
def node_state(nodes_data):
|
||||
for node in nodes_data:
|
||||
if '192.168.229.138' in node['label']:
|
||||
current_color = node['color']
|
||||
if current_color == 'lightgreen' or current_color =='#00ff00':
|
||||
return 0
|
||||
return 1
|
||||
|
||||
|
||||
# if __name__ == '__main__':
|
||||
# main()
|
@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class WebConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "web"
|
@ -0,0 +1,61 @@
|
||||
# Generated by Django 4.2.13 on 2024-06-12 00:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="catagory",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("catagorynum", models.IntegerField(verbose_name="簇号")),
|
||||
("dnsname", models.CharField(max_length=100, verbose_name="域名")),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="dns_ip",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("dnsname", models.CharField(max_length=100, verbose_name="域名")),
|
||||
("ipname", models.CharField(max_length=100, verbose_name="ip")),
|
||||
("DGAdetection", models.IntegerField(verbose_name="DGA检测")),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Document",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("file", models.FileField(upload_to="documents/")),
|
||||
],
|
||||
),
|
||||
]
|
@ -0,0 +1,14 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
class dns_ip(models.Model):
|
||||
dnsname = models.CharField(verbose_name="域名",max_length=100)
|
||||
ipname = models.CharField(verbose_name="ip",max_length=100)
|
||||
DGAdetection =models.IntegerField(verbose_name='DGA检测')
|
||||
|
||||
class Document(models.Model):
|
||||
file = models.FileField(upload_to='documents/')
|
||||
|
||||
class catagory(models.Model):
|
||||
catagorynum = models.IntegerField(verbose_name="簇号")
|
||||
dnsname = models.CharField(verbose_name="域名", max_length=100)
|
@ -0,0 +1,288 @@
|
||||
/*-----------------------------------*\
|
||||
#style.css
|
||||
\*-----------------------------------*/
|
||||
|
||||
/**
|
||||
* copyright 2022 codewithsadee
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#CUSTOM PROPERTY
|
||||
\*-----------------------------------*/
|
||||
|
||||
:root {
|
||||
|
||||
/**
|
||||
* colors
|
||||
*/
|
||||
|
||||
--medium-slate-blue: hsl(240, 73%, 65%);
|
||||
--space-cadet_10: hsl(226, 54%, 26%, 0.1);
|
||||
--space-cadet: hsl(226, 54%, 26%);
|
||||
--ghost-white: hsl(227, 69%, 97%);
|
||||
--cool-gray: hsl(226, 19%, 63%);
|
||||
--cultured: hsl(0, 0%, 95%);
|
||||
--white: hsl(0, 0%, 100%);
|
||||
|
||||
/**
|
||||
* typography
|
||||
*/
|
||||
|
||||
--ff-dm-sans: 'Roboto', sans-serif;
|
||||
--ff-helvetica: 'Helvetica', sans-serif;
|
||||
|
||||
--fs-1: 3rem;
|
||||
--fs-2: 2.4rem;
|
||||
--fs-3: 1.5rem;
|
||||
--fs-4: 1.2rem;
|
||||
|
||||
--fw-500: 500;
|
||||
--fw-600: 600;
|
||||
--fw-700: 700;
|
||||
|
||||
/**
|
||||
* shadow
|
||||
*/
|
||||
|
||||
--shadow: 1px 1px 3px hsla(0, 0%, 0%, 0.15);
|
||||
|
||||
/**
|
||||
* radius
|
||||
*/
|
||||
|
||||
--radius-5: 5px;
|
||||
--radius-15: 15px;
|
||||
|
||||
/**
|
||||
* transition
|
||||
*/
|
||||
|
||||
--transition-1: 0.25s ease;
|
||||
--transition-2: 1s ease;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#RESET
|
||||
\*-----------------------------------*/
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
span,
|
||||
data { display: block; }
|
||||
|
||||
img { height: auto; }
|
||||
|
||||
table,
|
||||
tbody,
|
||||
tr,
|
||||
th,
|
||||
td {
|
||||
all: unset;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: var(--ff-dm-sans);
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--ghost-white);
|
||||
color: var(--cool-gray);
|
||||
font-size: 1.6rem;
|
||||
padding-inline: 15px;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#REUSED STYLE
|
||||
\*-----------------------------------*/
|
||||
|
||||
.flex-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.balance-card,
|
||||
.chart-card {
|
||||
width: 300px;
|
||||
height: 150px;
|
||||
position: relative;
|
||||
padding: 5px;
|
||||
border-radius: var(--radius-10);
|
||||
}
|
||||
|
||||
.text { font-size: var(--fs-3); }
|
||||
|
||||
.h2 { font-size: var(--fs-2); }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#BALANCE CARD
|
||||
\*-----------------------------------*/
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
max-width: 540px;
|
||||
margin-inline: 100px;
|
||||
left: 50px;
|
||||
}
|
||||
|
||||
.balance-card {
|
||||
background-color: var(--medium-slate-blue);
|
||||
color: var(--white);
|
||||
justify-content: space-between;
|
||||
margin-block-end: 15px;
|
||||
}
|
||||
|
||||
.balance-card .text {
|
||||
font-weight: unset;
|
||||
margin-block-end: 5px;
|
||||
}
|
||||
|
||||
.balance-card .h2 { font-weight: var(--fw-700); }
|
||||
|
||||
.balance-card .logo { width: 60px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#CHART CARD
|
||||
\*-----------------------------------*/
|
||||
|
||||
.chart-card {
|
||||
position: relative;
|
||||
margin-right: 30px;
|
||||
background-color: var(--white);
|
||||
}
|
||||
|
||||
.chart-card .h2 {
|
||||
color: var(--space-cadet);
|
||||
font-weight: var(--fw-500);
|
||||
margin-block-end: 50px;
|
||||
}
|
||||
|
||||
.chart-card .card-table {
|
||||
display: block;
|
||||
padding-block-end: 24px;
|
||||
border-block-end: 1px solid var(--space-cadet_10);
|
||||
margin-block-end: 24px;
|
||||
}
|
||||
|
||||
.chart-card .table-body {
|
||||
justify-content: space-evenly;
|
||||
align-items: stretch;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.chart-card .table-row {
|
||||
flex-direction: column-reverse;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
min-height: calc(150px + 31px);
|
||||
}
|
||||
|
||||
.chart-card .table-heading {
|
||||
color: var(--space-cadet);
|
||||
font-family: var(--ff-helvetica);
|
||||
font-size: var(--fs-4);
|
||||
}
|
||||
|
||||
.chart-card .table-data {
|
||||
min-width: 20px;
|
||||
height: 100%;
|
||||
background-color: var(--cultured);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chart-card .chart-bar {
|
||||
background-color: var(--medium-slate-blue);
|
||||
height: 100%;
|
||||
transform-origin: bottom;
|
||||
transition: transform var(--transition-2);
|
||||
}
|
||||
|
||||
.chart-card .chart-bar:hover { opacity: 0.75; }
|
||||
|
||||
.tooltip {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background-color: var(--white);
|
||||
color: var(--space-cadet);
|
||||
font-family: var(--ff-helvetica);
|
||||
font-weight: var(--fw-600);
|
||||
padding: 8px;
|
||||
border: 1px solid var(--cultured);
|
||||
border-radius: var(--radius-5);
|
||||
box-shadow: var(--shadow);
|
||||
pointer-events: none;
|
||||
opacity: 0;
|
||||
transition: var(--transition-1);
|
||||
}
|
||||
|
||||
.tooltip.active { opacity: 1; }
|
||||
|
||||
.chart-card .wrapper {
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.chart-card .meta-value {
|
||||
color: var(--space-cadet);
|
||||
font-weight: var(--fw-500);
|
||||
margin-block-start: 5px;
|
||||
}
|
||||
|
||||
.chart-card .meta-value:not(.small) { font-size: var(--fs-1); }
|
||||
|
||||
.chart-card .card-meta:last-child {
|
||||
align-self: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.piechart{
|
||||
margin-top: -180px;
|
||||
left: 600px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
position: fixed;
|
||||
padding: 5px;
|
||||
border-radius: var(--radius-10);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------*\
|
||||
#MEDIA QUERIES
|
||||
\*-----------------------------------*/
|
||||
|
||||
/**
|
||||
* responsive for large than 768px screen
|
||||
*/
|
||||
|
After Width: | Height: | Size: 710 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 1007 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 313 KiB |
After Width: | Height: | Size: 148 KiB |
After Width: | Height: | Size: 173 KiB |
After Width: | Height: | Size: 164 KiB |
After Width: | Height: | Size: 155 KiB |
After Width: | Height: | Size: 1.3 MiB |
After Width: | Height: | Size: 2.0 MiB |
After Width: | Height: | Size: 237 KiB |
After Width: | Height: | Size: 533 KiB |
After Width: | Height: | Size: 740 KiB |
After Width: | Height: | Size: 74 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 435 KiB |
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 409 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 204 KiB |
After Width: | Height: | Size: 81 KiB |
After Width: | Height: | Size: 516 B |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,20 @@
|
||||
[
|
||||
{
|
||||
"server": "shanghai",
|
||||
"stat": "busy",
|
||||
"amount": 70,
|
||||
"recentTime":70
|
||||
},
|
||||
{
|
||||
"server": "changsha",
|
||||
"stat": "busy",
|
||||
"amount": 50,
|
||||
"recentTime": 1300
|
||||
},
|
||||
{
|
||||
"server": "beijing",
|
||||
"stat": "busy",
|
||||
"amount": 56,
|
||||
"recentTime": 70
|
||||
}
|
||||
]
|
@ -0,0 +1,138 @@
|
||||
@charset "utf-8";
|
||||
|
||||
/* 公共区域版心宽度一样,左右居中 */
|
||||
|
||||
|
||||
/* .header-wrap {
|
||||
width: 1100px;
|
||||
height: 62px;
|
||||
margin: 0 auto;
|
||||
} */
|
||||
|
||||
.header_con {
|
||||
width: 1002px;
|
||||
height: 100px;
|
||||
/* background: pink; */
|
||||
/* 左右居中 */
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header_con h1 {
|
||||
width: 604px;
|
||||
height: 10px;
|
||||
/* background: orange; */
|
||||
float: left;
|
||||
padding: 34px 0 0 20px;
|
||||
}
|
||||
|
||||
.header_con form {
|
||||
width: 227px;
|
||||
height: 61px;
|
||||
/* background: orangered; */
|
||||
float: left;
|
||||
padding-top: 39px;
|
||||
padding-right: 21px;
|
||||
}
|
||||
|
||||
.header_con .search {
|
||||
width: 195px;
|
||||
height: 26px;
|
||||
background: #f1f1f1;
|
||||
border: 1px solid #e5e5e5;
|
||||
/* 清除右侧边框 */
|
||||
border-right: none;
|
||||
float: left;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
.header_con .btn {
|
||||
width: 30px;
|
||||
height: 26px;
|
||||
border: none;
|
||||
background: #f1f1f1 url("../images/search_03.jpg") no-repeat center;
|
||||
}
|
||||
|
||||
.header_con form div {
|
||||
width: 30px;
|
||||
height: 26px;
|
||||
border: 1px solid #e5e5e5;
|
||||
border-left: none;
|
||||
float: left;
|
||||
/* 给btn套盒子的时候也要加浮动 */
|
||||
}
|
||||
|
||||
#nav {
|
||||
height: 58px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
#nav .nav_con {
|
||||
width: 1002px;
|
||||
height: 58px;
|
||||
background: black;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
||||
/* 导航横向排列 */
|
||||
|
||||
#nav .nav_con li {
|
||||
width: 498px;
|
||||
height: 58px;
|
||||
float: left;
|
||||
background: black;
|
||||
/* 左右居中 */
|
||||
text-align: center;
|
||||
/* 上下居中 */
|
||||
line-height: 58px;
|
||||
border-left: 1px solid #4a4a4a;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.nav_con li a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.margin-left {
|
||||
margin-left: 25px;
|
||||
border-left: none!important;
|
||||
}
|
||||
|
||||
|
||||
/* 公共样式的footer */
|
||||
|
||||
.footer_con {
|
||||
height: 82px;
|
||||
/* background: #cccccc; */
|
||||
}
|
||||
|
||||
.footer_con .footer_l {
|
||||
height: 58px;
|
||||
float: left;
|
||||
/* background: red; */
|
||||
padding-top: 24px;
|
||||
}
|
||||
|
||||
.footer_con .footer_l a {
|
||||
font-size: 12px;
|
||||
float: left;
|
||||
color: #868686;
|
||||
border-right: 1px solid #868686;
|
||||
/* padding:字体和边框的距离哈 */
|
||||
padding: 0 7px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.footer_con .footer_l .footer-right {
|
||||
border-right: none!important;
|
||||
}
|
||||
|
||||
.footer_con .footer_r {
|
||||
height: 57px;
|
||||
color: #8a8a8a;
|
||||
font-size: 12px;
|
||||
padding-top: 25px;
|
||||
/* background: pink; */
|
||||
padding-right: 21px;
|
||||
float: right;
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
.loader {
|
||||
background: #000;
|
||||
background: radial-gradient(#222, #000);
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
}
|
||||
|
||||
.loader-inner {
|
||||
bottom: 0;
|
||||
height: 60px;
|
||||
left: 0;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.loader-line-wrap {
|
||||
animation:
|
||||
spin 2000ms cubic-bezier(.175, .885, .32, 1.275) infinite
|
||||
;
|
||||
box-sizing: border-box;
|
||||
height: 50px;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transform-origin: 50% 100%;
|
||||
width: 100px;
|
||||
}
|
||||
.loader-line {
|
||||
border: 4px solid transparent;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 100px;
|
||||
left: 0;
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100px;
|
||||
}
|
||||
.loader-line-wrap:nth-child(1) { animation-delay: -50ms; }
|
||||
.loader-line-wrap:nth-child(2) { animation-delay: -100ms; }
|
||||
.loader-line-wrap:nth-child(3) { animation-delay: -150ms; }
|
||||
.loader-line-wrap:nth-child(4) { animation-delay: -200ms; }
|
||||
.loader-line-wrap:nth-child(5) { animation-delay: -250ms; }
|
||||
|
||||
.loader-line-wrap:nth-child(1) .loader-line {
|
||||
border-color: hsl(0, 80%, 60%);
|
||||
height: 90px;
|
||||
width: 90px;
|
||||
top: 7px;
|
||||
}
|
||||
.loader-line-wrap:nth-child(2) .loader-line {
|
||||
border-color: hsl(60, 80%, 60%);
|
||||
height: 76px;
|
||||
width: 76px;
|
||||
top: 14px;
|
||||
}
|
||||
.loader-line-wrap:nth-child(3) .loader-line {
|
||||
border-color: hsl(120, 80%, 60%);
|
||||
height: 62px;
|
||||
width: 62px;
|
||||
top: 21px;
|
||||
}
|
||||
.loader-line-wrap:nth-child(4) .loader-line {
|
||||
border-color: hsl(180, 80%, 60%);
|
||||
height: 48px;
|
||||
width: 48px;
|
||||
top: 28px;
|
||||
}
|
||||
.loader-line-wrap:nth-child(5) .loader-line {
|
||||
border-color: hsl(240, 80%, 60%);
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
top: 35px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0%, 15% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
@charset "utf-8";
|
||||
|
||||
/* 重置样式表 */
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/* 统一页面文本 */
|
||||
|
||||
body {
|
||||
font-size: 16px;
|
||||
font-family: "微软雅黑";
|
||||
}
|
||||
|
||||
|
||||
/* 清除列表符号 */
|
||||
|
||||
ul,
|
||||
ol,
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
|
||||
/* 清除下划线 */
|
||||
|
||||
u,
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
/* 清除倾斜 */
|
||||
|
||||
i,
|
||||
em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
/* 清除加粗 */
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
/* 清除文本默认大小和加粗 */
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
/* 边框清零 */
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
|
||||
/* 清除聚焦时候的边框 */
|
||||
|
||||
input {
|
||||
outline: none;
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
body{
|
||||
background: url("ab.jpg") no-repeat center;
|
||||
background-size: cover;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login{
|
||||
color: #988fc7;
|
||||
float: right;
|
||||
width: 100px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.search-box{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%,-50%);
|
||||
background:#2f3640;
|
||||
height: 38px;
|
||||
border-radius: 60px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.search-box:hover > .search-txt{
|
||||
width: 240px;
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.search-box:hover > .search-btn{
|
||||
background: white;
|
||||
}
|
||||
|
||||
.search-btn{
|
||||
color: #988fc7;
|
||||
float: right;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
background: #2f3640;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: 0.4s;
|
||||
}
|
||||
|
||||
.search-txt{
|
||||
border:none;
|
||||
background: none;
|
||||
outline: none;
|
||||
float: left;
|
||||
padding: 0;
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
transition: 0.4s;
|
||||
line-height: 40px;
|
||||
width: 0px;
|
||||
}
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 8.1 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 8.8 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 827 B |
After Width: | Height: | Size: 7.1 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 19 KiB |