init project

main
kongfp 7 months ago
commit e993468eb1

167
.gitignore vendored

@ -0,0 +1,167 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
.idea/
migrations
pictures
avatars
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

@ -0,0 +1,40 @@
FROM python:3.8
# 安装netcat
RUN apt-get update
# 可选:设置镜像源为国内
COPY pip.conf /root/.pip/pip.conf
# 容器内创建 myproject 文件夹
ENV APP_HOME=/home/myproject
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
# 将当前目录加入到工作目录中(. 表示当前目录)
ADD . $APP_HOME
# 更新pip版本
RUN /usr/local/bin/python -m pip install --upgrade pip
# 安装vim
RUN apt-get install -y vim
# 安装netcat
RUN apt-get install -y netcat
# 安装项目依赖
RUN pip install -r requirements.txt
# 移除\r in windows
RUN sed -i 's/\r//' ./start.sh
# 给start.sh可执行权限
RUN chmod +x ./start.sh
RUN chmod 777 -R /home/myproject/logs/
EXPOSE 8000
# 数据迁移,并启动服务
ENTRYPOINT /bin/bash ./start.sh

@ -0,0 +1,3 @@
import pymysql
pymysql.install_as_MySQLdb()

@ -0,0 +1,16 @@
"""
ASGI config for General-Platform-Backend 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/3.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'General-Platform-Backend.settings')
application = get_asgi_application()

@ -0,0 +1,221 @@
"""
Django settings for General-PlatformBackend project.
Generated by 'django-admin startproject' using Django 3.2.19.
For more information on this file, see
https://docs.djangoproject.com/en/3.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.2/ref/settings/
"""
import datetime
import os
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/3.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-g0&+1(bgmf2*-tll=p=61pqe_v%cpq3%x9vsual%=tohdhmfy2'
# 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',
'corsheaders',
'app.apps.AppConfig',
'rest_framework',
'rest_framework_simplejwt'
]
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 = 'General-Platform-Backend.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [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 = 'General-Platform-Backend.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.getenv("MYSQL_DATABASE") or 'general_platform_v1',
'USER': os.getenv("MYSQL_USER") or 'root',
'PASSWORD': os.getenv("MYSQL_PASSWORD") or '123abc',
'HOST': os.getenv("MYSQL_HOST") or '127.0.0.1',
'PORT': os.getenv("MYSQL_PORT") or '3306',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.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/3.2/topics/i18n/
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = '/static/'
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
LOGGING = {
'version': 1, # 保留字
'disable_existing_loggers': False, # 是否禁用已经存在的日志实例
'formatters': { # 定义日志的格式
'standard': {
'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
'[%(levelname)s]%(message)s'
},
'simple': {
'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
},
'collect': {
'format': '%(message)s'
}
},
'filters': { # 定义日志的过滤器
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
'handlers': { # 日志处理程序
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
'file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(BASE_DIR, "logs/debug.log"), # 日志文件
'backupCount': 10, # 保留的最大文件数,超过则删除日期最早的
'maxBytes': 1024 * 1024 * 100, # 文件大小
'formatter': 'standard',
'encoding': 'utf-8',
},
},
'loggers': { # 日志实例 记录器
'mylogger': { # 默认的logger应用如下配置
'handlers': ['console', 'file'],
'level': 'DEBUG',
'propagate': True, # 是否向上一级logger实例传递日志信息
},
},
}
AUTH_USER_MODEL = 'app.AuthUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
# 'rest_framework.permissions.IsAuthenticated',
'rest_framework.permissions.AllowAny',
],
}
SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": datetime.timedelta(days=7),
"AUTH_HEADER_TYPES": ("JWT",),
}
# 解决跨域
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = ["*"]
# CORS_ORIGIN_WHITELIST = ('*',)
# 对应的发送的请求的跨域
CORS_ALLOW_METHODS = (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
'VIEW',
)

@ -0,0 +1,28 @@
"""General-Platform-Backend URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.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.urls import path, include, re_path
from django.views.static import serve
from .settings import MEDIA_ROOT
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('app.urls')),
]
urlpatterns += [
re_path(r'^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
]

@ -0,0 +1,16 @@
"""
WSGI config for General-Platform-Backend 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/3.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'General-Platform-Backend.settings')
application = get_wsgi_application()

@ -0,0 +1,7 @@
from django.contrib import admin
from app.models import AuthUser
from django.contrib.auth.admin import UserAdmin
# Register your models here.
admin.site.register(AuthUser, UserAdmin)

@ -0,0 +1,6 @@
from django.apps import AppConfig
class AppConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'app'

@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-
"""静态配置"""
PAGE_SIZE = 10
# 行业分类
industry_map = {
1001: u"IT服务",
1002: u"制造业",
1003: u"批发/零售",
1004: u"生活服务",
1005: u"文化/体育/娱乐业",
1006: u"建筑/房地产",
1007: u"教育",
1008: u"运输/物流/仓储",
1009: u"医疗",
1010: u"政府",
1011: u"金融",
1012: u"能源/采矿",
1013: u"农林渔牧",
1014: u"其他行业",
}
model_type_classic = 1001
model_type_machine = 1002
model_type_map = {
model_type_classic: u"经典算法",
model_type_machine: u"机器学习",
}
# 1000/all/默认, 1001/在线1002/离线1003/运行中1004/故障
device_status_default = 1000
device_status_online = 1001
device_status_offline = 1002
device_status_ongoing = 1003
device_status_error = 1004
device_status_map = {
1000: u"全部",
1001: u"在线",
1002: u"离线",
1003: u"运行中",
1004: u"故障",
}

@ -0,0 +1,338 @@
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class AuthUser(AbstractUser):
GENDER = ((0, ''), (1, ''))
STATUS = ((1, "正常"), (2, "删除"))
enterprise_id = models.IntegerField(default=1, verbose_name="企业id", null=True, blank=True)
avatar = models.ImageField(upload_to='avatars', default='avatars/default.png', verbose_name="头像")
gender = models.IntegerField(choices=GENDER, default=1, verbose_name='性别')
phone_number = models.CharField(max_length=12, verbose_name='手机号', null=True, blank=True)
status = models.IntegerField(verbose_name='状态', default=1)
note = models.CharField(max_length=2048, verbose_name="备注", null=True, blank=True)
class Meta:
db_table = "auth_user"
class EnterpriseModel(models.Model):
suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
name = models.CharField(max_length=255, verbose_name="企业名称", null=False)
province = models.CharField(max_length=50, verbose_name="省份", null=True)
city = models.CharField(max_length=50, verbose_name="城市", null=True)
addr = models.CharField(max_length=255, verbose_name="地址", null=True)
industry = models.IntegerField(verbose_name="工业", null=True)
contact = models.CharField(max_length=100, verbose_name="联系", null=True)
phone = models.CharField(max_length=50, verbose_name="电话", null=True)
summary = models.CharField(max_length=255, verbose_name="总结", null=True)
logo = models.TextField(null=True)
account = models.CharField(max_length=20, verbose_name="账户", null=False)
pwd = models.CharField(max_length=100, verbose_name="密码", null=False)
start_valid_date = models.DateField(verbose_name="有效开始日期", null=True)
end_valid_date = models.DateField(verbose_name="有效结束日期", null=True)
status = models.IntegerField(default=0, verbose_name="是否删除")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise"
class ServerModel(models.Model):
STATUS = ((1001, "在线"), (1002, "离线"))
suid = models.CharField(max_length=10, default="", verbose_name="服务器suid", null=True, blank=True)
name = models.CharField(max_length=255, default="", verbose_name="服务器名称", null=True, blank=True)
banner = models.CharField(max_length=128, default="", verbose_name="标语", null=True, blank=True)
description = models.CharField(max_length=1024, default="", verbose_name="描述", null=True, blank=True)
status = models.IntegerField(verbose_name='服务器状态', choices=STATUS, default=1001)
type = models.IntegerField(verbose_name='类型', null=True)
server_ip = models.CharField(verbose_name="地址", max_length=512, null=True)
server_port = models.IntegerField(verbose_name="端口", null=True)
server_username = models.CharField(verbose_name="用户", max_length=512, null=True)
server_password = models.CharField(verbose_name="密码", max_length=512, null=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "server"
class HardwareModel(models.Model):
server_id = models.IntegerField(verbose_name="服务器id", null=False)
name = models.CharField(max_length=255, default="", verbose_name="硬件名称", null=True, blank=True)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "hardware"
class ServerLogModel(models.Model):
server_id = models.IntegerField(verbose_name="服务器id", null=False)
log_level = models.CharField(verbose_name="日志等级", max_length=16)
server_log = models.CharField(verbose_name="日志", max_length=1024, blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
class Meta:
db_table = "server_log"
class EnterpriseNodeModel(models.Model):
suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
entity_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
name = models.CharField(max_length=255, verbose_name="名称", null=False)
parent = models.IntegerField(verbose_name='父节点', default=None, null=True)
addr = models.CharField(max_length=255, verbose_name="地址", default="", blank=True)
lola = models.CharField(max_length=255, verbose_name="经纬度", default="", blank=True)
contact = models.CharField(max_length=255, verbose_name="联系人", default="", blank=True)
phone = models.CharField(max_length=255, verbose_name="联系人方式", default="", blank=True)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
status = models.IntegerField(default=0, verbose_name="是否删除")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_node"
class DeviceClassificationModel(models.Model):
name = models.CharField(max_length=255, verbose_name="名称", null=False)
suid = models.CharField(max_length=10, default="", verbose_name="分类suid", null=True, blank=True)
status = models.IntegerField(default=0, verbose_name="是否删除")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "device_classification"
class EnterpriseDeviceModel(models.Model):
STATUS = ((1001, "在线"), (1002, "离线"), (1003, "故障"))
suid = models.CharField(max_length=10, default="", verbose_name="服务器suid", null=True, blank=True)
entity_id = models.IntegerField(verbose_name='企业id', null=False)
entity_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=True)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
classification = models.CharField(max_length=10, default="", verbose_name="分类suid", null=True, blank=True)
name = models.CharField(max_length=255, verbose_name="名称", null=False)
addr = models.CharField(max_length=255, verbose_name="地址", null=False)
device_model = models.CharField(max_length=255, verbose_name="设备型号", null=True, default="", blank=True)
param = models.CharField(max_length=255, verbose_name="参数", null=True, default="", blank=True)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
status = models.IntegerField(default=1001, choices=STATUS, verbose_name="设备状态")
is_used = models.IntegerField(default=1, verbose_name="是否启用")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_device"
class AlgModelModel(models.Model):
STATUS = ((1000, "删除"), (1001, "在线"), (1002, "离线"), (1003, "故障"))
name = models.CharField(max_length=255, verbose_name="名称", null=False)
suid = models.CharField(max_length=10, default="", verbose_name="分类suid", null=True, blank=True)
model_type = models.IntegerField(default=1002, verbose_name="模型类型1001/经典算法1002/深度学习")
classification = models.IntegerField(verbose_name="模型分类的id")
industry = models.CharField(max_length=255, verbose_name="适用行业", default="通用", blank=True)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
default_version = models.CharField(max_length=100, verbose_name="默认版本", default="", blank=True)
provider = models.CharField(max_length=100, verbose_name="提供方", default="", blank=True)
status = models.IntegerField(default=1001, choices=STATUS, verbose_name="状态")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "model"
class ModelClassificationModel(models.Model):
name = models.CharField(max_length=255, verbose_name="名称", null=False)
# suid = models.CharField(max_length=10, default="", verbose_name="分类suid", null=True, blank=True)
# status = models.IntegerField(default=0, verbose_name="是否删除")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
# update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "model_classification"
class ModelVersionModel(models.Model):
model_id = models.IntegerField(verbose_name='模型id', null=False)
version = models.CharField(max_length=100, verbose_name="版本", null=False)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
model_file = models.CharField(max_length=32, verbose_name="模型文件的md5", default="", blank=True)
config_file = models.CharField(max_length=32, verbose_name="模型配置文件的md5", default="", blank=True)
config_str = models.CharField(max_length=1024, verbose_name="模型默认配置参数json字符串", default="", blank=True)
is_default = models.IntegerField(default=1, verbose_name="1/默认0/非默认")
status = models.IntegerField(default=0, verbose_name="是否删除1/删除0/正常")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "model_version"
class ModelHubModel(models.Model):
name = models.CharField(max_length=255, verbose_name="名称", null=False)
host = models.CharField(max_length=255, verbose_name="host", null=False)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
port = models.IntegerField(default=1, verbose_name="port")
path = models.CharField(max_length=255, verbose_name="路径", default="", blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "model_hub"
# 企业关联模型表
class EnterpriseBusiModelModel(models.Model):
name = models.CharField(max_length=255, verbose_name="名称", null=False)
suid = models.CharField(max_length=10, default="", verbose_name="分类suid", null=True, blank=True)
entity_id = models.IntegerField(verbose_name='企业id', null=False)
entity_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
comment = models.CharField(max_length=255, verbose_name="备注", default="", blank=True)
base_models = models.CharField(max_length=255, verbose_name="关联基础模型", null=False)
business_logic = models.CharField(max_length=32, verbose_name="业务代码压缩包文件md5", null=True)
business_conf_file = models.CharField(max_length=32, verbose_name="业务配置参数压缩包文件md5", null=True)
business_conf_param = models.CharField(max_length=255, verbose_name='业务配置的参数json字符串eg: ''{"a":1, "b":2}''', null=True)
status = models.IntegerField(default=0, verbose_name="是否删除")
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_busi_model"
# 企业关联模型节点表
class EnterpriseBusiModelNodeModel(models.Model):
suid = models.CharField(max_length=10, default="", verbose_name="suid", null=True, blank=True)
busi_model_id = models.IntegerField(verbose_name='企业关联模型表id', null=False)
entity_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
busi_model_suid = models.CharField(max_length=10, default="", verbose_name="企业关联模型表suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=False)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_busi_model_node"
# 企业关联模型节点设备表
class EnterpriseBusiModelNodeDeviceModel(models.Model):
suid = models.CharField(max_length=10, default="", verbose_name="suid", null=True, blank=True)
busi_model_id = models.IntegerField(verbose_name='企业关联模型表id', null=False)
entity_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
busi_model_suid = models.CharField(max_length=10, default="", verbose_name="企业关联模型表suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=False)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
device_id = models.IntegerField(verbose_name='设备id', null=False)
device_suid = models.CharField(max_length=10, default="", verbose_name="设备suid", null=True, blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_busi_model_node_device"
# 企业告警配置表
class EnterpriseAlertDeviceModel(models.Model):
CODE = ((0, ""), (1, ""))
enterprise_suid = models.CharField(max_length=10, default="", verbose_name="企业suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=False)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
is_sms = models.IntegerField(verbose_name='是否使用sms', null=False, choices=CODE, default=0)
sms_to = models.CharField(max_length=11, default="", verbose_name="sms", null=True, blank=True)
is_email = models.IntegerField(verbose_name='是否使用email', null=False, choices=CODE, default=0)
email_to = models.CharField(max_length=255, default="", verbose_name="email", null=True, blank=True)
freq = models.CharField(max_length=255, default="", verbose_name="email", null=True, blank=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "enterprise_alert"
class WarningStatisticsModel(models.Model):
CODE = ((0, ""), (1, ""))
server_id = models.IntegerField(verbose_name="平台id", null=True)
server_suid = models.CharField(max_length=10, default="", verbose_name="服务器suid", null=True, blank=True)
device_id = models.IntegerField(verbose_name='设备id', null=True)
device_suid = models.CharField(max_length=10, default="", verbose_name="设备suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=True)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
picture_path = models.CharField(verbose_name="图片地址", max_length=512, null=True)
product_name = models.CharField(verbose_name="产品名称", null=False, max_length=128)
product_info = models.CharField(verbose_name="产品信息", null=True, max_length=128)
warning_name = models.CharField(verbose_name="告警名称", null=True, max_length=128)
warning_type = models.CharField(verbose_name="告警类型", null=True, max_length=128)
warning_code = models.CharField(verbose_name="告警代码", null=False, max_length=128)
warning_level = models.CharField(verbose_name="告警等级", null=False, max_length=128)
trigger_time = models.DateTimeField(auto_now_add=True, verbose_name="触发时间", null=False)
is_ignore = models.IntegerField(verbose_name="是否忽略", default=0, choices=CODE)
is_checked = models.IntegerField(verbose_name="是否查看", default=0, choices=CODE)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "warning_statistics"
class ComputeConfigModel(models.Model):
CODE = ((0, ""), (1, ""))
# suid = models.CharField(max_length=10, default="", verbose_name="suid", null=True, blank=True)
server_id = models.IntegerField(verbose_name="平台id", null=True)
server_suid = models.CharField(max_length=10, default="", verbose_name="服务器suid", null=True, blank=True)
device_id = models.IntegerField(verbose_name='设备id', null=True)
device_suid = models.CharField(max_length=10, default="", verbose_name="设备suid", null=True, blank=True)
node_id = models.IntegerField(verbose_name='节点id', null=True)
node_suid = models.CharField(max_length=10, default="", verbose_name="节点suid", null=True, blank=True)
model_id = models.IntegerField(verbose_name='模型id', null=True)
model_suid = models.CharField(max_length=10, default="", verbose_name="模型suid", null=True, blank=True)
percentage = models.DecimalField(max_digits=3, decimal_places=2, verbose_name="百分比")
efficiency = models.IntegerField(default=0, verbose_name="处理效率(每秒几帧)", null=True)
status = models.IntegerField(default=0, verbose_name="是否删除", choices=CODE)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "compute_config"
class FilesModel(models.Model):
CODE = ((0, ""), (1, ""))
filename = models.CharField(max_length=255, default="", verbose_name="文件名", null=True, blank=True)
filepath = models.CharField(max_length=255, default="", verbose_name="文件路径", null=True, blank=True)
md5_str = models.CharField(max_length=32, default="", verbose_name="文件md5", null=True, blank=True)
filesize = models.IntegerField(verbose_name='文件大小', default=None, null=True)
filetype = models.CharField(max_length=50, default="", verbose_name="文件类型", null=True, blank=True)
user = models.IntegerField(verbose_name='拥有者', default=0, null=True)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
class Meta:
db_table = "files"
class MessageModel(models.Model):
CODE = ((0, ""), (1, ""))
message = models.CharField(max_length=1024, default="", verbose_name="消息内容", null=True, blank=True)
info_type = models.CharField(verbose_name="消息类型", default="系统消息", null=True, max_length=128)
trigger_time = models.DateTimeField(auto_now_add=True, verbose_name="触发时间", null=False)
is_ignore = models.IntegerField(verbose_name="是否忽略", default=0, choices=CODE)
is_checked = models.IntegerField(verbose_name="是否查看", default=0, choices=CODE)
create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', null=True)
update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', null=True)
class Meta:
db_table = "message"

@ -0,0 +1,8 @@
from rest_framework.pagination import PageNumberPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 10
page_query_param = "page"
page_size_query_param = "pageSize"
max_page_size = 100

@ -0,0 +1,491 @@
import copy
import datetime
import json
import random
import re
from decimal import Decimal
from django.db.models import F
from rest_framework import serializers
from django_filters.rest_framework import FilterSet
import django_filters
from app import consts, shortuuid
from app.models import AuthUser, ServerModel, AlgModelModel, ModelClassificationModel, EnterpriseModel, \
EnterpriseDeviceModel, DeviceClassificationModel, WarningStatisticsModel, EnterpriseNodeModel, ComputeConfigModel, \
ModelVersionModel, EnterpriseAlertDeviceModel, ModelHubModel, EnterpriseBusiModelModel, \
EnterpriseBusiModelNodeModel, EnterpriseBusiModelNodeDeviceModel, ServerLogModel, FilesModel, MessageModel
import logging
logger = logging.getLogger('mylogger')
def md5_validate(v: str) -> bool:
md5_pattern = re.compile(r'^[a-fA-F0-9]{32}$')
# 匹配字符串
if md5_pattern.match(v):
return True
return False
class AuthUserSerializer(serializers.ModelSerializer):
class Meta:
model = AuthUser
fields = ["id", "username", "avatar", "is_superuser", "date_joined", "gender", "phone_number", "status", "note"]
def to_representation(self, instance):
ret = super().to_representation(instance)
ret["gender_ch"] = instance.get_gender_display()
return ret
class ServerSerializer(serializers.ModelSerializer):
class Meta:
model = ServerModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
ret["state"] = consts.device_status_map.get(ret["status"], None)
# TODO 暂时模拟服务器使用情况
ret["cpu"] = random.randint(20, 30)
ret["mem"] = random.randint(20, 30)
ret["storage"] = random.randint(20, 30)
ret["gpu"] = random.randint(20, 30)
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
class ServerLogSerializer(serializers.ModelSerializer):
class Meta:
model = ServerLogModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
class EnterpriseSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseModel
# fields = "__all__"
exclude = ["pwd"]
def to_representation(self, instance):
ret = super().to_representation(instance)
ret["industry"] = consts.industry_map.get(ret["industry"], None)
# ret["valid_data"] = f"{ret.pop('start_valid_date')}至{ret.pop('end_valid_date')}"
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
# 有效期无需更新
else:
data.pop("start_valid_date", None)
data.pop("end_valid_date", None)
ret = super().to_internal_value(data)
return ret
class EnterpriseBusiModelSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseBusiModelModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
ret["basemodel_list"] = json.loads(ret.pop("base_models", "{}"))
# node_id_list
all_node_id_list = EnterpriseBusiModelNodeModel.objects.filter(busi_model_id=instance.id).all().values("node_id")
node_ids = list()
for node_id in all_node_id_list:
node_ids.append(node_id.get("node_id"))
all_node_objs = EnterpriseNodeModel.objects.filter(id__in=node_ids).all().annotate(node_id=F('id'), node_name=F('name')).values("node_id", "node_name")
ret["link_node_list"] = all_node_objs
return ret
def to_internal_value(self, data):
data = self.insert_busi_model(data)
all_fields = self.get_fields()
filtered_data = {key: value for key, value in data.items() if key in all_fields}
ret = super().to_internal_value(filtered_data)
return ret
def insert_busi_model(self, data):
if not data.get("entity_suid"):
entity_obj = EnterpriseModel.objects.filter(id=data.get("entity_id")).last()
entity_suid = entity_obj.suid if entity_obj else ""
data['entity_suid'] = entity_suid
if not (data.get("suid") or data.get("id")):
data['suid'] = shortuuid.ShortUUID().random(10)
base_model_ids = [int(model_id) for model_id in data['basemodel_ids'].split(',')]
logging.info("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
logging.info(base_model_ids)
base_model = []
for base_model_id in base_model_ids:
base_model_info = AlgModelModel.objects.filter(id=base_model_id).get()
logging.info("#####################")
logging.info(base_model_info)
base_model.append({
'id': base_model_id,
'suid': base_model_info.suid,
'name': base_model_info.name,
})
data['base_models'] = json.dumps(base_model, ensure_ascii=False)
new_data = copy.copy(data)
return new_data
class EnterpriseBusiModelNodeSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseBusiModelNodeModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
ret = super().to_internal_value(data)
return ret
class EnterpriseBusiModelNodeDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseBusiModelNodeDeviceModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
class AlgModelSerializer(serializers.ModelSerializer):
class Meta:
model = AlgModelModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
try:
model_class = ModelClassificationModel.objects.filter(id=instance.classification).get()
except:
model_class = None
ret["classification_name"] = model_class.name if model_class else None
ret["model_type"] = consts.model_type_map[instance.model_type]
ret["update_time"] = str(instance.update_time)
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
class ModelClassificationSerializer(serializers.ModelSerializer):
class Meta:
model = ModelClassificationModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
class ModelVersionSerializer(serializers.ModelSerializer):
class Meta:
model = ModelVersionModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
if not md5_validate(data.get("model_file")):
raise Exception("模型文件格式错误")
config_file = data.get("config_file")
if config_file and not md5_validate(config_file):
raise Exception("模型配置文件格式错误")
status = data.get("status")
# 删除时更新模型的版本
if status:
AlgModelModel.objects.filter(id=data.get("model_id")).update(default_version="")
ret = super().to_internal_value(data)
return ret
class ModelHubSerializer(serializers.ModelSerializer):
class Meta:
model = ModelHubModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
class EnterpriseDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseDeviceModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
##TODO 设备状态
# ret["state"] = None
try:
classification_obj = DeviceClassificationModel.objects.filter(id=ret["classification"]).get()
except:
classification_obj = None
ret["classification"] = classification_obj.name if classification_obj else None
ret["is_cam"] = "摄像" in classification_obj.name if classification_obj else False
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
class EnterpriseAlertDeviceSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseAlertDeviceModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
class DeviceClassificationSerializer(serializers.ModelSerializer):
class Meta:
model = DeviceClassificationModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
class WarningStatisticsSerializer(serializers.ModelSerializer):
class Meta:
model = WarningStatisticsModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
try:
node_obj = EnterpriseNodeModel.objects.filter(id=instance.node_id).get()
except:
node_obj = None
ret["node_name"] = node_obj.name if node_obj else ""
return ret
class EnterpriseNodeListSerializer(serializers.ListSerializer):
@property
def data_with_children(self):
data = super().data
for single in data:
children = EnterpriseNodeModel.objects.filter(parent=single.get("id")).all()
if children:
single["children"] = EnterpriseNodeSerializer(children, many=True).data_with_children
else:
single["children"] = []
return data
class EnterpriseNodeSerializer(serializers.ModelSerializer):
class Meta:
model = EnterpriseNodeModel
fields = "__all__"
list_serializer_class = EnterpriseNodeListSerializer
def to_representation(self, instance):
ret = super().to_representation(instance)
# children = EnterpriseNodeModel.objects.filter(parent=instance.id).all()
#
# if children:
# ret["children"] = EnterpriseNodeSerializer(children, many=True).data
return ret
def to_internal_value(self, data):
if not (data.get("suid") or data.get("id")):
suid = shortuuid.ShortUUID().random(10)
data["suid"] = suid
ret = super().to_internal_value(data)
return ret
@property
def data_with_children(self):
data = super().data
children = EnterpriseNodeModel.objects.filter(parent=data.get("id")).all()
if children:
data["children"] = EnterpriseNodeSerializer(children, many=True).data_with_children
else:
data["children"] = []
return data
class ComputeConfigSerializer(serializers.ModelSerializer):
class Meta:
model = ComputeConfigModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
ret["percentage"] = f"{100 * instance.percentage}%"
try:
model_obj = AlgModelModel.objects.filter(id=instance.model_id).get()
except:
model_obj = None
ret["name"] = model_obj.name if model_obj else None
return ret
def to_internal_value(self, data):
percentage = data.get("percentage")
if isinstance(percentage, str) and percentage.endswith("%"):
data["percentage"] = (Decimal(percentage.strip("%")) / Decimal('100.0')).quantize(Decimal('0.00'))
ret = super().to_internal_value(data)
return ret
class FilesSerializer(serializers.ModelSerializer):
class Meta:
model = FilesModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
ret = super().to_internal_value(data)
return ret
class MessageSerializer(serializers.ModelSerializer):
class Meta:
model = MessageModel
fields = "__all__"
def to_representation(self, instance):
ret = super().to_representation(instance)
return ret
def to_internal_value(self, data):
ret = super().to_internal_value(data)
return ret

@ -0,0 +1,138 @@
"""Concise UUID generation."""
import math
import secrets
import uuid as _uu
from typing import List
from typing import Optional
def int_to_string(
number: int, alphabet: List[str], padding: Optional[int] = None
) -> str:
"""
Convert a number to a string, using the given alphabet.
The output has the most significant digit first.
"""
output = ""
alpha_len = len(alphabet)
while number:
number, digit = divmod(number, alpha_len)
output += alphabet[digit]
if padding:
remainder = max(padding - len(output), 0)
output = output + alphabet[0] * remainder
return output[::-1]
def string_to_int(string: str, alphabet: List[str]) -> int:
"""
Convert a string to a number, using the given alphabet.
The input is assumed to have the most significant digit first.
"""
number = 0
alpha_len = len(alphabet)
for char in string:
number = number * alpha_len + alphabet.index(char)
return number
class ShortUUID(object):
def __init__(self, alphabet: Optional[str] = None) -> None:
if alphabet is None:
alphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ" "abcdefghijkmnopqrstuvwxyz"
self.set_alphabet(alphabet)
@property
def _length(self) -> int:
"""Return the necessary length to fit the entire UUID given the current alphabet."""
return int(math.ceil(math.log(2**128, self._alpha_len)))
def encode(self, uuid: _uu.UUID, pad_length: Optional[int] = None) -> str:
"""
Encode a UUID into a string (LSB first) according to the alphabet.
If leftmost (MSB) bits are 0, the string might be shorter.
"""
if not isinstance(uuid, _uu.UUID):
raise ValueError("Input `uuid` must be a UUID object.")
if pad_length is None:
pad_length = self._length
return int_to_string(uuid.int, self._alphabet, padding=pad_length)
def decode(self, string: str, legacy: bool = False) -> _uu.UUID:
"""
Decode a string according to the current alphabet into a UUID.
Raises ValueError when encountering illegal characters or a too-long string.
If string too short, fills leftmost (MSB) bits with 0.
Pass `legacy=True` if your UUID was encoded with a ShortUUID version prior to
1.0.0.
"""
if not isinstance(string, str):
raise ValueError("Input `string` must be a str.")
if legacy:
string = string[::-1]
return _uu.UUID(int=string_to_int(string, self._alphabet))
def uuid(self, name: Optional[str] = None, pad_length: Optional[int] = None) -> str:
"""
Generate and return a UUID.
If the name parameter is provided, set the namespace to the provided
name and generate a UUID.
"""
if pad_length is None:
pad_length = self._length
# If no name is given, generate a random UUID.
if name is None:
u = _uu.uuid4()
elif name.lower().startswith(("http://", "https://")):
u = _uu.uuid5(_uu.NAMESPACE_URL, name)
else:
u = _uu.uuid5(_uu.NAMESPACE_DNS, name)
return self.encode(u, pad_length)
def random(self, length: Optional[int] = None) -> str:
"""Generate and return a cryptographically secure short random string of `length`."""
if length is None:
length = self._length
return "".join(secrets.choice(self._alphabet) for _ in range(length))
def get_alphabet(self) -> str:
"""Return the current alphabet used for new UUIDs."""
return "".join(self._alphabet)
def set_alphabet(self, alphabet: str) -> None:
"""Set the alphabet to be used for new UUIDs."""
# Turn the alphabet into a set and sort it to prevent duplicates
# and ensure reproducibility.
new_alphabet = list(sorted(set(alphabet)))
if len(new_alphabet) > 1:
self._alphabet = new_alphabet
self._alpha_len = len(self._alphabet)
else:
raise ValueError("Alphabet with more than " "one unique symbols required.")
def encoded_length(self, num_bytes: int = 16) -> int:
"""Return the string length of the shortened UUID."""
factor = math.log(256) / math.log(self._alpha_len)
return int(math.ceil(factor * num_bytes))
# For backwards compatibility
_global_instance = ShortUUID()
encode = _global_instance.encode
decode = _global_instance.decode
uuid = _global_instance.uuid
random = _global_instance.random
get_alphabet = _global_instance.get_alphabet
set_alphabet = _global_instance.set_alphabet

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,42 @@
from django.urls import path, include, re_path
from app import views, user_views
urlpatterns = [
path('login/', user_views.UserViewSet.as_view({'post': 'login'})),
path('getAsyncRoutes/', user_views.AsyncRoutesViewSet.as_view({'get': 'list'})),
path('get_user_info/', user_views.UserViewSet.as_view({'get': 'get_user_info'})),
path('users/', user_views.UserViewSet.as_view({'post': 'create', "get": "list"})),
path('server/', views.ServerModelViewSet.as_view({'post': 'create', "get": "list"})),
path('server_log/', views.ServerLogModelViewSet.as_view({'post': 'create', "get": "list"})),
path('enterprise/', views.EnterpriseModelViewSet.as_view({'post': 'create', "get": "list"})),
path('enterprise_node/', views.EnterpriseNodeModelViewSet.as_view({'post': 'create', "get": "list"})),
path('enterprise_alert/', views.EnterpriseAlertModelViewSet.as_view({'post': 'create', "get": "list"})),
path('models/', views.AlgModelModelViewSet.as_view({'post': 'create', "get": "list"})),
path('models_classification/', views.ModelClassificationModelViewSet.as_view({'post': 'create', "get": "list"})),
path('models_version/', views.ModelVersionModelViewSet.as_view({'post': 'create', "get": "list"})),
path('models_hub/', views.ModelHubModelViewSet.as_view({'post': 'create', "get": "list"})),
path('device_classfication/', views.DeviceClassificationModelViewSet.as_view({'post': 'create', "get": "list"})),
path('devices/', views.EnterpriseDeviceModelViewSet.as_view({'post': 'create', "get": "list"})),
path('enterprise_business_model/',
views.EnterpriseBusiModelModelViewSet.as_view({'post': 'create', "get": "list"})),
path('enterprise_model_node_device/',
views.EnterpriseBusiModelNodeDeviceModelViewSet.as_view({'post': 'create', "get": "list"})),
path('warning_statistics/', views.WarningStatisticsModelViewSet.as_view({'post': 'create', "get": "list"})),
path('compute_config/', views.ComputeConfigModelViewSet.as_view({'post': 'create', "get": "list"})),
path('files/', views.FilesModelViewSet.as_view({'post': 'create', "get": "list", "delete": "destroy"})),
path('messages/', views.MessageModelViewSet.as_view({'post': 'create', "get": "list"})),
path('set_default_version/', views.ModelVersionModelViewSet.as_view({'post': 'set_default_version'})),
path('data_overview/', views.DataOverviewModelViewSet.as_view({'get': 'list'})),
path('device_and_warnings/', views.DeviceAndWarningsModelViewSet.as_view({'get': 'list'})),
path('warnings_and_message/', views.WarningsAndMessageModelViewSet.as_view({'get': 'list'})),
path('classify_warnings/', views.ClassifyWarningsModelViewSet.as_view({'get': 'list'})),
]

@ -0,0 +1,218 @@
import datetime
import logging
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import permission_classes as single_permission
from rest_framework.permissions import IsAuthenticated
from app.pagination import MyPageNumberPagination
from app.serializers import AuthUserSerializer
from app.models import AuthUser, EnterpriseModel
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
logger = logging.getLogger('mylogger')
class UserViewSet(ModelViewSet):
serializer_class = AuthUserSerializer
pagination_class = MyPageNumberPagination
authentication_classes = []
permission_classes = []
@staticmethod
def login(request, *args, **kwargs):
"""登录 POST"""
data = request.data
username = data.get('username')
password = data.get('password')
# 验证是否过期
enterprise_obj = EnterpriseModel.objects.filter(account=username, pwd=password).last()
if not enterprise_obj:
response = {
'success': False,
'msg': "该账号不存在",
'data': {
'username': None,
'roles': [],
'token': None,
'expires': None
}
}
return Response(response)
else:
flag = datetime.date.today() < enterprise_obj.end_valid_date
if not flag:
response = {
'success': False,
'msg': f"该账号已过期,有效时间为{enterprise_obj.start_valid_date}{enterprise_obj.end_valid_date}",
'data': {
'username': None,
'roles': [],
'token': None,
'expires': None
}
}
return Response(response)
serializer = TokenObtainPairSerializer(data=request.data)
try:
serializer.is_valid(raise_exception=True)
except Exception as e:
response = {
'success': False,
'msg': str(e),
'data': {
'username': None,
'roles': [],
'token': None,
'expires': None
}
}
return Response(response)
response = {
'success': True,
'msg': '登录成功',
'data': {
'username': username,
'roles': ['admin'],
'accessToken': serializer.validated_data.get("access"),
'refreshToken': serializer.validated_data.get("refresh"),
}
}
return Response(response)
@staticmethod
def get_user_info(request, *args, **kwargs):
return Response({
"code": 0,
"success": True,
"data": {
"userInfo": {
"id": 1,
"createTime": "2023-10-08T08:02:30.775742Z",
"updateTime": "2024-01-23T08:51:08.648364Z",
"userName": "admin",
"nickName": "管理员",
"phone": "",
"email": "",
"avatarId": 1,
"roleId": 1,
"postId": None,
"deptId": None,
"roleIds": "1",
"postIds": "",
"remark": "",
"enable": None,
"lastLoginTime": "2024-01-23T08:51:08.558393Z",
"roles": [
{
"label": "管理员",
"value": 1
}
],
"avatarUrl": "uploads/image/user/avatar/39c63ddb96a31b9610cd976b896ad4f0_20231016113731.jpg"
}
},
"msg": "获取成功"
})
@single_permission([IsAuthenticated])
def create(self, request, *args, **kwargs):
"""注册 POST 用户名 手机号 状态 性别 部门"""
data = request.data
username = data.get('username')
if not username:
return Response({'msg': '用户名不能为空'})
user_id = data.pop("id", None)
password = data.pop('password', None)
note = data.get("note", None)
# 新增用户
if not user_id:
try:
if AuthUser.objects.filter(username=username).first():
return Response({'msg': '该用户名已存在,请换一个', "success": False, "status": 400})
if not password:
password = "#Yaxin0504"
user = AuthUser.objects.create_user(username=username, password=password, note=note)
return Response({'msg': '用户添加成功', 'success': True, "status": 200})
except Exception as e:
response = {
"msg": f'添加失败, 原因:{e}',
"success": False,
"status": 400
}
return Response(response)
else:
try:
partial = kwargs.pop('partial', True)
try:
user = AuthUser.objects.filter(id=user_id).get()
except Exception as e:
logger.error(f"查询用户报错:{e}")
return Response({"msg": "该用户不存在", "status": 400, "success": False, "data": None})
if password:
user.set_password(password)
user.save()
if data:
serializer = self.get_serializer(user, data=data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response({'msg': '用户更新成功', 'success': True, "status": 200})
except Exception as e:
response = {
"msg": f'用户更新失败, 原因:{e}',
"success": False,
"status": 400
}
return Response(response)
@single_permission([IsAuthenticated])
def list(self, request, *args, **kwargs):
data = request.query_params
user_id = data.get("id")
status = data.get("status", 1)
self.queryset = AuthUser.objects.filter(status=status).all().order_by("-id")
if not user_id:
return Response({
"data": super().list(request, *args, **kwargs).data,
"msg": None,
"success": True,
"status": 200
})
else:
try:
instance = self.queryset.filter(id=user_id).get()
except Exception as e:
logger.error(f"查询用户{user_id}报错:{e}")
return Response({"msg": "该用户不存在", "status": 400, "success": False, "data": None})
serializer = self.get_serializer(instance)
return Response({
"data": serializer.data,
"msg": None,
"success": True,
"status": 200
})
class AsyncRoutesViewSet(ModelViewSet):
def list(self, request, *args, **kwargs):
return Response(
{
"success": True,
"data": []
}
)

File diff suppressed because it is too large Load Diff

@ -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', 'General-Platform-Backend.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,6 @@
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
[install]
trusted-host = https://pypi.tuna.tsinghua.edu.cn
[list]
format=columns

Binary file not shown.

@ -0,0 +1,25 @@
#!/bin/bash
#uwsgi --ini /home/myproject/uwsgi.ini&&
export MYSQL_DATABASE="general_platform"
export MYSQL_USER="general"
export MYSQL_PASSWORD="#Yaxin0504"
export MYSQL_HOST="127.0.0.1"
export MYSQL_PORT="3306"
while ! nc -z db 3306 ; do
echo "Waiting for the MySQL Server"
sleep 3
done
pip install -r requirements.txt&&
python manage.py makemigrations&&
python manage.py migrate&&
nohup python3 manage.py runserver 0.0.0.0:8000 &&
echo '通用平台项目启动完成'
tail -f /dev/null

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save