| @ -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 |