Parcourir la source

uid管理系统项目代码

pengzhibo168 il y a 5 ans
commit
2f50cfef12

+ 0 - 0
AnsjerUIDManage/__init__.py


+ 16 - 0
AnsjerUIDManage/asgi.py

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

+ 189 - 0
AnsjerUIDManage/config.py

@@ -0,0 +1,189 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import datetime, os
+
+SERVER_TYPE = os.environ.get('DJANGO_SETTINGS_MODULE')
+print(SERVER_TYPE)
+
+OAUTH_ACCESS_TOKEN_SECRET = 'a+jbnw%@1%zy^=@dn62%'
+OAUTH_REFRESH_TOKEN_SECRET = 'r+jbnw%@1%zy^=@dn62%'
+
+# access_token超时
+# OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(hours=1)
+OAUTH_ACCESS_TOKEN_TIME = datetime.timedelta(days=30)
+# refresh_token超时
+OAUTH_REFRESH_TOKEN_TIME = datetime.timedelta(days=30)
+
+SERVER_HOST = 'localhost'
+
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+UNICODE_ASCII_CHARACTER_SET = ('abcdefghijklmnopqrstuvwxyz'
+                               'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+                               '0123456789')
+
+# 不同环境配置
+# if SERVER_TYPE == 'AnsjerUIDManage.local_settings':
+#     from AnsjerUIDManage.config_local import *
+# elif SERVER_TYPE == 'AnsjerUIDManage.test_settings':
+#     from AnsjerUIDManage.config_test import *
+# elif SERVER_TYPE == 'AnsjerUIDManage.formal_settings':
+#     from AnsjerUIDManage.config_formal import *
+
+ONLINE_DEVICE = 1000000
+
+SALES = {
+    2020: [
+        {
+            'name': 'United States',
+            'value': [3768901, 23.337, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1886988, 9.027, '日本']
+        },
+        {
+            'name': 'Russia',
+            'value': [1940038, 7.923, '俄国']
+        },
+        {
+            'name': 'Germany',
+            'value': [1319651, 6.253, '德国']
+        },
+        {
+            'name': 'France',
+            'value': [1291157, 5.825, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [1041917, 4.567, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [859811, 3.875, '意大利']
+        }
+    ],
+    2019: [
+        {
+            'name': 'United States',
+            'value': [2768900, 37.374, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1086988, 14.672, '日本']
+        },
+        {
+            'name': 'Russia',
+            'value': [940038, 12.689, '俄国']
+        },
+        {
+            'name': 'Germany',
+            'value': [919651, 12.413, '德国']
+        },
+        {
+            'name': 'France',
+            'value': [691157, 9.329, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [541917, 7.315, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [459811, 6.206, '意大利']
+        }
+    ],
+    2018: [
+        {
+            'name': 'United States',
+            'value': [2068912, 32.329, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [1007988, 15.751, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [909653, 14.214, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [900038, 14.064, '俄国']
+        },
+
+        {
+            'name': 'France',
+            'value': [601158, 9.394, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [501920, 7.843, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [409813, 6.404, '意大利']
+        }
+    ],
+    2017: [
+        {
+            'name': 'United States',
+            'value': [1668900, 30.914, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [906988, 16.800, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [809651, 14.998, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [800038, 14.820, '俄国']
+        },
+        {
+            'name': 'France',
+            'value': [501157, 9.283, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [401920, 7.445, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [309822, 5.739, '意大利']
+        }
+    ],
+    2016: [
+        {
+            'name': 'United States',
+            'value': [1468900, 31.943, '美国']
+        },
+        {
+            'name': 'Japan',
+            'value': [806988, 17.549, '日本']
+        },
+        {
+            'name': 'Germany',
+            'value': [709651, 15.432, '德国']
+        },
+        {
+            'name': 'Russia',
+            'value': [700038, 15.223, '俄国']
+        },
+
+        {
+            'name': 'France',
+            'value': [401157, 8.724, '法国']
+        },
+        {
+            'name': 'United Kingdom',
+            'value': [301917, 6.566, '英国']
+        },
+        {
+            'name': 'Italy',
+            'value': [209811, 4.562, '意大利']
+        }
+    ]
+
+}

+ 29 - 0
AnsjerUIDManage/generacode.py

@@ -0,0 +1,29 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+
+from Object.TokenObject import TokenObject
+import base64
+import requests
+
+token = TokenObject()
+token = token.generate({'userID': str(2)})
+
+file = open('./file/UID30000.txt', mode='r', encoding='utf-8')
+content = file.read()
+content = '1Il' + content
+content = content + 'lll'
+content = content.encode(encoding='utf-8')
+content = base64.b64encode(content).decode().strip()
+file.close()
+
+url = 'http://192.168.136.35:8000/upload'
+postData = {
+    'area': 0,
+    'token': token['access_token'],
+    'fileName': content
+}
+# postData = json.dumps(postData)
+print(postData)
+res = requests.post(url=url, data=postData)
+print(res)

+ 205 - 0
AnsjerUIDManage/settings.py

@@ -0,0 +1,205 @@
+"""
+Django settings for AnsjerUIDManage project.
+
+Generated by 'django-admin startproject' using Django 3.0.7.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/3.0/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/3.0/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'k#i*q_^=nhr^63ytqenfg!ecqizq60*6_x@sp_6+%u^b24%+fj'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = False
+
+ALLOWED_HOSTS = ['*']
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.admin',
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'Model.apps.ModelConfig',
+    'corsheaders',
+]
+
+MIDDLEWARE = [
+    'django.middleware.security.SecurityMiddleware',
+    'Service.LogMiddleware.LogMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    #'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+    'corsheaders.middleware.CorsMiddleware',
+    'corsheaders.middleware.CorsPostCsrfMiddleware',
+]
+
+ROOT_URLCONF = 'AnsjerUIDManage.urls'
+CORS_ALLOW_CREDENTIALS = True
+CORS_ORIGIN_ALLOW_ALL = True
+CORS_ALLOW_METHODS = (
+    'DELETE',
+    'GET',
+    'OPTIONS',
+    'PATCH',
+    'POST',
+    'PUT',
+    'VIEW',
+)
+
+CORS_ALLOW_HEADERS = (
+    'XMLHttpRequest',
+    'X_FILENAME',
+    'accept',
+    'accept-encoding',
+    'authorization',
+    'content-type',
+    'dnt',
+    'origin',
+    'user-agent',
+    'x-csrftoken',
+    'x-requested-with',
+    'Pragma',
+)
+
+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 = 'AnsjerUIDManage.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
+
+DATABASES = {
+    # 'default': {
+    #     'ENGINE': 'django.db.backends.sqlite3',
+    #     'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+    #     'CHECK_SAME_THREAD': False
+    # }
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': 'ansjer_uid',
+        'USER': 'root',
+        'PASSWORD': '123456',
+        'HOST': 'localhost',
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/3.0/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.0/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/3.0/howto/static-files/
+
+STATIC_URL = '/static/'
+
+# 日志模块
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'error_format': {
+            # 'format': '{"asctime":"%(asctime)s","thread":"%(threadName)s:%(thread)d","errorline":"%(lineno)d","errorlevel":"%(levelname)s","errorcontent":"%(message)s"}'
+            'format': '%(asctime)s %(threadName)s %(thread)d %(lineno)d %(levelname)s %(message)s'
+        },
+    },
+    'filters': {
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+            'include_html': True,
+        },
+        'default': {
+            'level': 'ERROR',
+            'class': 'logging.handlers.RotatingFileHandler',
+            'filename': BASE_DIR + '/static/log/error.log',
+            'maxBytes': 1024 * 1024 * 5,  # 5 MB
+            'backupCount': 5,
+            'formatter': 'error_format',
+        },
+        'console': {
+            'level': 'ERROR',
+            'class': 'logging.StreamHandler',
+            'formatter': 'error_format'
+        },
+    },
+    'loggers': {
+        'django': {
+            'handlers': ['default', 'console'],
+            # 'handlers': ['mail_admins','default','console'],
+            'level': 'ERROR',
+            'propagate': False
+        },
+    }
+}

+ 30 - 0
AnsjerUIDManage/urls.py

@@ -0,0 +1,30 @@
+"""AnsjerUIDManage URL Configuration
+
+The `urlpatterns` list routes URLs to views. For more information please see:
+    https://docs.djangoproject.com/en/3.0/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, re_path
+
+from Controller import UserController, FileController, UIDController, LogController, SalesController
+
+urlpatterns = [
+    path('admin/', admin.site.urls),
+    re_path('user/(?P<operation>.*)', UserController.UserView.as_view()),
+    path('upload', FileController.UploadUIDFileView.as_view()),
+    path('download', FileController.DownloadUIDFileView.as_view()),
+    re_path('uid/(?P<operation>.*)', UIDController.UIDView.as_view()),
+    re_path('log/(?P<operation>.*)', LogController.LogView.as_view()),
+    path('sales', SalesController.SalesView.as_view()),
+    path('device/online', SalesController.DeviceOnlineView.as_view())
+]

+ 16 - 0
AnsjerUIDManage/wsgi.py

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

+ 289 - 0
Controller/FileController.py

@@ -0,0 +1,289 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import base64
+import json
+import time
+import xlwt
+
+from django.http import StreamingHttpResponse, HttpResponse, QueryDict
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import UIDModel, UserUIDModel, UserModel, LogModel
+from Object.RedisObject import RedisObject
+from Object.TokenObject import TokenObject
+from Object.ResponseObject import ResponseObject
+from Service.CommonService import CommonService
+
+
+class UploadUIDFileView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UploadUIDFileView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        fileName = request.FILES.get('fileName', None)
+        return self.validate(fileName, request_dict, request)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        fileName = request.FILES.get('fileName', None)
+        return self.validate(fileName, request_dict, request)
+
+    def validate(self, fileName, request_dict, request):
+        token = request_dict.get('token', None)
+        area = request_dict.get('area', None)
+        isReset = request_dict.get('isReset', 0)
+        content = request_dict.get('fileName', None)
+        print('content')
+        print(content)
+
+        content = base64.b64decode(content).decode().strip()
+        content = content[3:(len(content) - 3)]
+        uids = content.split('\n')
+        print(uids)
+
+        response = ResponseObject()
+
+        tko = TokenObject(token)
+        if tko.code != 0:
+            return response.json(tko.code)
+
+        # if not fileName and not area:
+        #     return response.json(444, 'fileName,area')
+
+        data = {}
+        duplicate = []
+        for line in uids:
+
+            if data.__contains__(line):
+                duplicate.append(line)
+            else:
+                data[line] = ''
+
+        if isReset == 0:
+            return self.do_insert(data, duplicate, area, response, request, tko)
+        else:
+            return self.do_reset(data, response, area, request, tko)
+
+    def do_insert(self, data, duplicate, area, response, request, token):
+        bulk = []
+        count = 0
+        add_time = int(time.time())
+        update_time = int(time.time())
+        keys = data.keys()
+        # redisObject = RedisObject(db=3)
+        for item in keys:
+            key = item.strip()
+            # value = redisObject.get_data(key)
+            # if value is False:
+            #     # redisObject.set_data(key, '1', 600)
+            # else:
+            #     duplicate.append(key)
+            #     continue
+            bulk.append(UIDModel(
+                uid=item.strip(),
+                uid_extra='',
+                status=0,
+                add_time=add_time,
+                update_time=update_time,
+                area=area
+            ))
+            try:
+                if (count % 5000) == 0:
+                    UIDModel.objects.bulk_create(bulk)
+                    bulk.clear()
+            except Exception as e:
+                print(repr(e))
+                return response.json(174, str(e))
+            count += 1
+
+        if len(bulk) > 0:
+            UIDModel.objects.bulk_create(bulk)
+            bulk.clear()
+        del data
+        del bulk
+
+        # print('重复:')
+        # print(duplicate)
+
+        operation = self.formatOperation(operation='上传', quantity=int(count), area=int(area))
+        self.add_log(request, operation, token)
+        return response.json(0, {'count': count, 'duplicate_count': len(duplicate), 'data': duplicate})
+
+    def do_reset(self, data, response, area, request, token):
+        keys = data.keys()
+        uids = []
+        count = 0
+        for key in keys:
+            uids.append(key)
+            if len(uids) % 5000 == 0:
+                count += self.do_update_uid_status(uids, area)
+                uids.clear()
+
+        if len(uids) > 0:
+            count += self.do_update_uid_status(uids, area)
+            uids.clear()
+
+        operation = self.formatOperation('重置', int(count), int(area))
+        self.add_log(request, operation, token)
+        return response.json(0)
+
+    def do_update_uid_status(self, uids, area):
+        uid_qs = UIDModel.objects.filter(uid__in=uids, area=area, status=2)
+        if uid_qs.exists():
+            for uid in uid_qs:
+                if uid.status == 2:
+                    uid.status = 1
+            UIDModel.objects.bulk_update(uid_qs, fields=['status'])
+            return uid_qs.count()
+        return 0
+
+    def add_log(self, request, operation, token):
+        ip = CommonService.get_ip_address(request)
+        now_time = time.time()
+        content = json.dumps(request.POST)
+        user_qs = UserModel.objects.filter(id=token.userID)
+
+        log = {
+            'status': 200,
+            'content': content,
+            'ip': ip,
+            'time': now_time,
+            'url': 'upload',
+            'operation': operation,
+            'user': user_qs[0]
+        }
+
+        try:
+            LogModel.objects.create(**log)
+        except Exception as e:
+            print(repr(e))
+
+    def formatOperation(self, operation, quantity, area):
+        str = '{operation}{quantity}个{area}UID'
+        if area == 0:
+            return str.format(operation=operation, quantity=quantity, area='国内')
+        else:
+            return str.format(operation=operation, quantity=quantity, area='国外')
+
+class DownloadUIDFileView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(DownloadUIDFileView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        token = request_dict.get('token', None)
+        area = request_dict.get('area', None)
+        quantity = int(request_dict.get('quantity', None))
+        fileType = request_dict.get('fileType', None)
+        response = ResponseObject()
+
+        # print(area)
+        # print(quantity)
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if not area:
+            return response.json(444, 'area')
+
+        area = int(area)
+
+        if area >= 0 and quantity > 0:
+
+            uid_qs = UserUIDModel.objects.filter(user__id=token.userID, uid__status=1, uid__area=area). \
+                values('uid__id', 'uid__uid', 'uid__uid_extra', 'uid__add_time', 'uid__update_time', 'uid__area')
+            count = uid_qs.count()
+            if count < quantity:
+                return response.json(444, '设备UID不足')
+
+            if uid_qs.exists():
+                uid_qs = uid_qs[0:quantity]
+                if fileType == 'txt':
+                    return self.download_txt(uid_qs)
+                elif fileType == 'excel':
+                    return self.download_excel(uid_qs)
+                else:
+                    return response.json(444, 'fileType')
+            else:
+                return response.json(444, '111')
+        else:
+            return response.json(444, '222')
+
+    def download_txt(self, uid_qs):
+        updates = []
+        content = ''
+        for item in uid_qs:
+            content += item['uid__uid']
+            content += '\n'
+            updates.append(UIDModel(
+                id=item['uid__id'],
+                uid=item['uid__uid'],
+                uid_extra=item['uid__uid_extra'],
+                status=2,
+                add_time=item['uid__add_time'],
+                update_time=item['uid__update_time'],
+                area=item['uid__area']
+            ))
+            if len(updates) % 5000 == 0:
+                UIDModel.objects.bulk_update(updates, fields=["status"])
+                updates.clear()
+            # print(item['uid__uid'])
+
+        if len(updates) > 0:
+            UIDModel.objects.bulk_update(updates, fields=["status"])
+            updates.clear()
+
+        del updates
+        content = content[0:len(content) - 1]
+        response = StreamingHttpResponse(content)
+        response['Content-Type'] = 'application/octet-stream'
+        response['Content-Disposition'] = 'attachment;filename=UID'+time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.txt'
+        return response
+
+    def download_excel(self, uid_qs):
+        response = HttpResponse(content_type='application/vnd.ms-excel')
+        response['Content-Disposition'] = 'attachment; filename=UID' + time.strftime('-%Y-%m-%d-%H-%M-%S', time.localtime()) + '.xls'
+        workbook = xlwt.Workbook(encoding='utf-8')
+        sheet1 = workbook.add_sheet('UID')
+        row1 = [u'设备UID']
+        for i in range(0, len(row1)):
+            sheet1.write(0, i, row1[i])
+
+        num = 1
+        updates = []
+        for item in uid_qs:
+            uid = item['uid']
+            sheet1.write(num, 0, uid)
+            num += 1
+            updates.append(UIDModel(
+                id=item['id'],
+                uid=item['uid'],
+                uid_extra=item['uid_extra'],
+                status=1,
+                add_time=item['add_time'],
+                update_time=item['update_time'],
+                area=item['area']
+            ))
+
+        UIDModel.objects.bulk_update(updates, fields=["status"])
+        workbook.save(response)
+        return response
+

+ 68 - 0
Controller/LogController.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import LogModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class LogView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(LogView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = TokenObject(request_dict.get('token', None))
+        response = ResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'query':
+            return self.do_query(request_dict, token, response)
+        elif operation == 'queryAll':
+            return self.do_query_all(request_dict, token, response)
+        else:
+            return response.json(404)
+
+    def do_query(self, request_dict, token: TokenObject, response):
+        page = request_dict.get('page', None)
+        line = request_dict.get('line', None)
+
+        if page and line:
+            log_qs = LogModel.objects.filter(user__id=token.userID).values('id', 'operation', 'time', 'ip')
+            if log_qs.exists():
+                page = int(page)
+                line = int(line)
+                start = (page - 1) * line
+                count = log_qs.count()
+                data = log_qs[start:(start + line)]
+                return response.json(0, {'count': count, 'data': list(data)})
+            else:
+                return response.json(0, {'count': 0, 'data': []})
+        else:
+            return response.json(444)
+
+    def do_query_all(self, request_dict, token: TokenObject, response: ResponseObject):
+        log_qs = LogModel.objects.filter(user__id=token.userID).values('id', 'operation', 'time', 'ip')
+        if log_qs.exists():
+            count = log_qs.count()
+            return response.json(0, {'count': count, 'data': list(log_qs)})
+        else:
+            return response.json(0, {'count': 0, 'data': []})

+ 107 - 0
Controller/SalesController.py

@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import datetime
+import json
+import random
+
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from AnsjerUIDManage.config import SALES, ONLINE_DEVICE
+from Object.ResponseObject import ResponseObject
+
+
+class SalesView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(SalesView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        year = request_dict.get('year', 0)
+        response = ResponseObject()
+        if year:
+            year = int(year)
+            if year == 0:
+                data = SALES.copy()
+                data[2020] = self.get_last_year_data(SALES[2020])
+                return response.json(0, {'data': self.format_data(data)})
+            elif 2015 < year < 2020:
+                data = {year: SALES[year]}
+                return response.json(0, {'data': self.format_data(data)})
+            elif year == 2020:
+                data = {year: self.get_last_year_data(SALES[year])}
+                return response.json(0, {'data': self.format_data(data)})
+            else:
+                return response.json(444)
+        else:
+            return response.json(444)
+
+    def get_last_year_data(self, data):
+        result = []
+        month = datetime.datetime.now().month
+        print(month)
+        sum = 0
+        for item in data:
+            value = item['value']
+            sale = int(value[0] / 12 * month)
+            sum += sale
+
+        for item in data:
+            tmp = {}
+            tmp['name'] = item['name']
+            value = item['value']
+            sale = int(value[0] / 12 * month)
+            percent = round(sale * 100 / sum, 3)
+
+            tmpValue = []
+            tmpValue.append(sale)
+            tmpValue.append(percent)
+            tmpValue.append(value[2])
+            tmp['value'] = tmpValue
+            result.append(tmp)
+        print(result)
+        return result
+
+    def format_data(self, data: dict):
+        result = []
+        keys = data.keys()
+        for key in keys:
+            tmp = {
+                'time': key,
+                'data': data[key]
+            }
+            result.append(tmp)
+        return result
+
+
+class DeviceOnlineView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(DeviceOnlineView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request_dict = request.GET
+        return self.validate(request_dict)
+
+    def post(self, request, *args, **kwargs):
+        request_dict = request.POST
+        return self.validate(request_dict)
+
+    def validate(self, request_dict):
+        response = ResponseObject()
+        return response.json(0,{'online': random.randint((0.9 * ONLINE_DEVICE), ONLINE_DEVICE)})
+
+
+
+

+ 237 - 0
Controller/UIDController.py

@@ -0,0 +1,237 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import time
+
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+from django.db.models import Avg,Max,Min,Count,Sum, Q  #   引入函数
+
+from Model.models import UIDModel, UserModel, UserUIDModel, HistoryUIDModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class UIDView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UIDView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validate(request_dict, operation)
+
+    def validate(self, request_dict, operation):
+        token = request_dict.get('token', None)
+        response = ResponseObject()
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        if operation == 'quantity':
+            return self.do_quantity(request_dict, response)
+        elif operation == 'allot':
+            return self.do_allot(request_dict, response)
+        elif operation == 'remove':
+            return self.do_remove(request_dict, response)
+        else:
+            return response.json(309)
+
+    # 查询当前可用的UID的数量
+    def do_quantity(self, request_dict, response):
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission == '0':
+                return self.do_admin_quantity(request_dict, response, user.username)
+            else:
+                return self.do_not_admin_quantity(request_dict, response, user.username)
+        else:
+            return response.json(9)
+
+    # 管理员的查询UID数量操作
+    def do_admin_quantity(self, request_dict, response, admin):
+        datas = []
+        domestic = UIDModel.objects.filter(area=0, status=0).count()
+        foreign = UIDModel.objects.filter(area=1, status=0).count()
+        item = {}
+        item['isAdmin'] = 1
+        item['domestic'] = domestic
+        item['foreign'] = foreign
+        item['username'] = admin
+        datas.append(item)
+
+        user_qs = UserModel.objects.filter(~Q(Q(permission='0')))
+        for user in user_qs:
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+
+        return response.json(0, {'data': datas})
+
+    # 非管理员的查询UID数量操作
+    def do_not_admin_quantity(self, request_dict, response, username):
+        user_qs = UserModel.objects.filter(username=username)
+        if user_qs.exists():
+            user = user_qs[0]
+            datas = []
+            item = {'isAdmin': 0}
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=0).aggregate(num=Count('uid__status'))
+            item['domestic'] = result['num']
+            result = UserUIDModel.objects.filter(user__id=user.id, uid__status=1, uid__area=1).aggregate(num=Count('uid__status'))
+            item['foreign'] = result['num']
+            item['username'] = user.username
+            datas.append(item)
+            return response.json(0, {'data': datas})
+        else:
+            return response.json(444)
+
+    # 分配UID
+    def do_allot(self, request_dict, response):
+        username = request_dict.get('username', None)
+        quantity = int(request_dict.get('quantity', None))
+        area = request_dict.get('area', None)
+        token = request_dict.get('token', None)
+
+        token = TokenObject(token)
+        if token.code != 0:
+            return response.json(token.code)
+        user = UserModel.objects.get(id=token.userID)
+
+        if not user or '0' not in user.permission:
+            return response.json(404)
+
+        # 要分配的对象
+        allot_user_qs = UserModel.objects.filter(username=username)
+        if not allot_user_qs.exists():
+            return response.json(444, 'username')
+
+        # 取出对应区域可用的UID分配给allot_user
+        uid_qs = UIDModel.objects.filter(area=area, status=0)
+        count = uid_qs.count()
+        if count < quantity:
+            return response.json(444, '设备UID不足')
+
+        updates = []
+        datas = []
+        if uid_qs.exists():
+            uid_qs = uid_qs[0:quantity]
+            for item in uid_qs:
+                item.status = 1
+                item.update_time = time.time()
+                user_uid = UserUIDModel()
+                user_uid.uid = item
+                user_uid.user = allot_user_qs[0]
+                datas.append(user_uid)
+                updates.append(item)
+
+                if len(datas) % 5000 == 0:
+                    UserUIDModel.objects.bulk_create(datas)
+                    UIDModel.objects.bulk_update(updates, fields=['status', 'update_time'])
+                    datas.clear()
+                    updates.clear()
+            if len(datas) > 0:
+                UserUIDModel.objects.bulk_create(datas)
+                UIDModel.objects.bulk_update(updates, fields=['status', 'update_time'])
+                datas.clear()
+                updates.clear()
+
+            del datas
+            del updates
+            return response.json(0)
+        else:
+            return response.json(444)
+
+    # 把UID表中的数据移动到HistoryUID表中
+    def do_remove(self, request_dict, response):
+        token = TokenObject(request_dict.get('token', None))
+        id = request_dict.get('id', None)
+        start = request_dict.get('start', None)
+        stop = request_dict.get('stop', None)
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        # 通过userID查找用户,判断是否是管理员
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = user_qs[0]
+            if user.permission != '0':
+                return response.json(404)
+        else:
+            return response.json(9)
+
+        if id:
+            return self.do_remove_by_id(id, response)
+        elif start and stop:
+            return self.do_bulk_remove(int(start), int(stop), response)
+        else:
+            return response.json(444, 'id,start,stop')
+
+    # 移除单条UID记录,id:记录id
+    def do_remove_by_id(self, id, response):
+        id = int(id)
+        uid_qs = UIDModel.objects.filter(id=id)
+        if not uid_qs.exists():
+            return response.json(173)
+
+        uid = uid_qs[0]
+        if uid:
+            data = {
+                'uid': uid.uid,
+                'uid_extra': uid.uid_extra,
+                'status': uid.status,
+                'add_time': uid.add_time,
+                'update_time': uid.update_time,
+                'area': uid.area
+            }
+            HistoryUIDModel.objects.create(**data)
+            uid.delete()
+            return response.json(0)
+        else:
+            return response.json(444, 'id')
+
+    # 批量移除UID记录。start:开始的UID记录的id;stop:结束的UID记录的id
+    def do_bulk_remove(self, start, stop, response):
+        uid_qs = UIDModel.objects.filter(id__range=(start, stop))
+        histories = []
+        if uid_qs.exists():
+            for item in uid_qs:
+                histories.append(HistoryUIDModel(
+                    uid=item.uid,
+                    uid_extra=item.uid_extra,
+                    status=item.status,
+                    add_time=item.add_time,
+                    update_time=item.update_time,
+                    area=item.area
+                ))
+                if len(histories) % 5000 == 0:
+                    HistoryUIDModel.objects.bulk_create(histories)
+                    histories.clear()
+            if len(histories) > 0:
+                HistoryUIDModel.objects.bulk_create(histories)
+                histories.clear()
+            uid_qs.delete()
+            return response.json(0)
+        else:
+            return response.json(173)

+ 158 - 0
Controller/UserController.py

@@ -0,0 +1,158 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+from django.db.models import Q
+from django.utils.decorators import method_decorator
+from django.views import View
+from django.views.decorators.csrf import csrf_exempt
+
+from Model.models import UserModel
+from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
+
+
+class UserView(View):
+
+    @method_decorator(csrf_exempt)
+    def dispatch(self, request, *args, **kwargs):
+        return super(UserView, self).dispatch(request, *args, **kwargs)
+
+    def get(self, request, *args, **kwargs):
+        # print('get')
+        request.encoding = 'utf-8'
+        request_dict = request.GET
+        operation = kwargs.get('operation')
+        return self.validation(request_dict, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        request_dict = request.POST
+        operation = kwargs.get('operation')
+        return self.validation(request_dict, operation)
+
+    def validation(self, request_dict, operation):
+        if operation == 'login':
+            return self.login(request_dict)
+        elif operation == 'logout':
+            return self.logout(request_dict)
+        elif operation == 'query':
+            return self.do_query(request_dict)
+        elif operation == 'modify':
+            return self.do_modify_password(request_dict)
+        else:
+            return ResponseObject().json(309)
+
+    def login(self, request_dict):
+        username = request_dict.get('username', None)
+        password = request_dict.get('password', None)
+
+        response = ResponseObject()
+
+        if username is None or password is None:
+            return response.json(444)
+
+        user = UserModel.objects.filter(username=username)
+        if user.exists():
+            if user[0].password != password:
+                return response.json(99)
+            else:
+                token = TokenObject()
+                res = token.generate({'userID': user[0].id})
+                res['permission'] = user[0].permission
+                res['username'] = user[0].username
+                user[0].online = 1
+                update = {
+                    'online': 1
+                }
+                user.update(**update)
+                return response.json(0, res)
+        else:
+            return response.json(99)
+
+    def do_query(self, request_dict):
+        # print('do_query')
+        token = TokenObject(request_dict.get('token', None))
+        # page = request_dict.get('page', None)
+        # line = request_dict.get('line', None)
+        # username = request_dict.get('username', None)
+        response = ResponseObject()
+
+        if token.code != 0:
+            return response.json(token.code)
+
+        # if username:
+        #     user_qs = UserModel.objects.filter(username__icontains=username)
+        #     if user_qs.exists():
+        #         users = list(user_qs.values('username'))
+        #         return response.json(0, {'data': users})
+        #     else:
+        #         return response.json(0, {'data': []})
+        # elif page and line:
+        #     print('query_page')
+        #     user_qs = UserModel.objects.filter(id=token.userID)
+        #     if user_qs.exists():
+        #         user = user_qs[0]
+        #         if user.permission == '0':
+        #             return self.do_query_pagination(int(page), int(line), response)
+        #         else:
+        #             return response.json(404)
+        #     else:
+        #         return response.json(9)
+
+        user_qs = UserModel.objects.filter(~Q(Q(permission='0'))).values('id', 'username')
+
+        return response.json(0, {'data': list(user_qs)})
+
+    def do_query_pagination(self, page, line, response):
+        # print('query start')
+        user_qs = UserModel.objects.filter().values()
+        if user_qs.exists():
+            count = user_qs.count()
+            start = (page - 1) * line
+            end = start + line
+            users = list(user_qs[start:end])
+            # print('query end')
+            return response.json(0, {'count': count, 'data': users})
+        else:
+            return response.json(0, {'count': 0, 'data': []})
+
+    def do_modify_password(self, request_dict):
+        token = request_dict.get('token', None)
+        old_password = request_dict.get('oldPassword', None)
+        new_password = request_dict.get('newPassword', None)
+        token = TokenObject(token)
+
+        response = ResponseObject()
+        if token.code != 0:
+            return response.json(token.code)
+
+        if old_password and new_password:
+            user_qs = UserModel.objects.filter(id=token.userID)
+            if user_qs.exists():
+                if user_qs[0].password != old_password:
+                    return response.json(47)
+                user = {
+                    'password': new_password
+                }
+                user_qs.update(**user)
+                return response.json(0)
+            else:
+                return response.json(9)
+        else:
+            return response.json(444)
+
+    def logout(self, request_dict):
+        token = request_dict.get('token', None)
+        token = TokenObject(token)
+        response = ResponseObject()
+        if token.code != 0:
+            return response.json(0)
+
+        user_qs = UserModel.objects.filter(id=token.userID)
+        if user_qs.exists():
+            user = {
+                'online': 0
+            }
+            user_qs.update(**user)
+            return response.json(0)
+        else:
+            return response.json(0)

+ 0 - 0
Model/__init__.py


+ 3 - 0
Model/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
Model/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class ModelConfig(AppConfig):
+    name = 'Model'

+ 88 - 0
Model/models.py

@@ -0,0 +1,88 @@
+from django.db import models
+
+# Create your models here.
+
+
+class UserModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    username = models.CharField(unique=True, max_length=128, null=False, verbose_name='用户名')
+    password = models.CharField(max_length=128, null=False, verbose_name='密码')
+    permission = models.CharField(max_length=24, null=False, verbose_name='权限')
+    login_time = models.IntegerField(blank=True, default=0, verbose_name='登录时间')
+    online = models.SmallIntegerField(default=0, verbose_name='是否在线')
+
+    class Meta:
+        verbose_name = '用户表'
+        verbose_name_plural = verbose_name
+        db_table = 'user'
+
+
+class UIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  #0:国内;1:国外
+
+    class Meta:
+        verbose_name = 'uid表'
+        verbose_name_plural = verbose_name
+        db_table = 'uid'
+
+
+class UserUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户表id')
+    uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联uid表id')
+
+    class Meta:
+        verbose_name = '用户与UID的关联表'
+        verbose_name_plural = verbose_name
+        db_table = 'user_uid'
+
+
+class PermissionModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    type = models.SmallIntegerField(null=False, verbose_name='权限枚举')
+    description = models.TextField(default='', verbose_name='权限描述')
+
+    class Meta:
+        verbose_name = '权限表'
+        verbose_name_plural = verbose_name
+        db_table = 'permission'
+
+
+class LogModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    operation = models.CharField(max_length=100, default='', verbose_name='操作描述')
+    time = models.IntegerField(default=0, verbose_name='操作时间')
+    ip = models.CharField(default='', max_length=24, verbose_name='用户ip')
+    user = models.ForeignKey(UserModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联用户id')
+    content = models.TextField(default='', verbose_name='请求参数')
+    status = models.IntegerField(default=0, verbose_name='请求状态')
+    url = models.CharField(max_length=150, default='', verbose_name='请求路径')
+
+    class Meta:
+        ordering = ('-time',)
+        verbose_name = '日志表'
+        verbose_name_plural = verbose_name
+        db_table = 'log'
+
+
+class HistoryUIDModel(models.Model):
+    id = models.AutoField(primary_key=True)
+    uid = models.CharField(max_length=20, null=False, db_index=True, unique=True, verbose_name='设备id')
+    uid_extra = models.TextField(default='', verbose_name='uid的额外描述')
+    status = models.SmallIntegerField(default=0, verbose_name='使用状态')
+    add_time = models.IntegerField(default=0, verbose_name='添加时间')
+    update_time = models.IntegerField(default=0, verbose_name='更新时间')
+    area = models.SmallIntegerField(default=0, verbose_name='区域')  # 0:国内;1:国外
+
+    class Meta:
+        verbose_name = '历史UID表'
+        verbose_name_plural = verbose_name
+        db_table = 'history_uid'
+
+

+ 3 - 0
Model/tests.py

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

+ 3 - 0
Model/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 86 - 0
Object/RedisObject.py

@@ -0,0 +1,86 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerOA
+@software: PyCharm
+@DATE: 2018/8/8 17:00
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: RedisObject.py
+@Contact: chanjunkai@163.com
+"""
+import redis
+
+from AnsjerUIDManage.config import SERVER_HOST
+from AnsjerUIDManage.config import SERVER_TYPE
+
+# SERVER_HOST = '192.168.136.45'
+
+'''
+db=3  -> 统计在线人数用
+'''
+
+
+class RedisObject:
+
+    def __init__(self, db=0,SERVER_HOST = SERVER_HOST):
+        if db == 3:
+            if SERVER_TYPE != 'Ansjer.formal_settings':
+                db = 4
+        self.POOL = redis.ConnectionPool(host=SERVER_HOST, port=6379, db=db)
+        self.CONN = redis.Redis(connection_pool=self.POOL)
+
+    def set_data(self, key, val, expire=0):
+        try:
+            self.CONN.set(key, val)
+            if expire > 0:
+                self.CONN.expire(key, expire)
+        except Exception as e:
+            return False
+        else:
+            return True
+
+    def get_data(self, key):
+        try:
+            val = self.CONN.get(key)
+        except Exception as e:
+            print(repr(e))
+            return False
+        else:
+            if val:
+                return val.decode('utf-8')
+            else:
+                return False
+
+    def del_data(self, key):
+        try:
+            val = self.CONN.delete(key)
+        except Exception as e:
+            print(repr(e))
+            return False
+        else:
+            return True
+
+    def get_size(self):
+        return self.CONN.dbsize()
+
+    # 向列表插入数据
+    def rpush(self, name, val):
+        self.CONN.rpush(name, val)
+
+    # 获取列表长度
+    def llen(self, name):
+        return self.CONN.llen(name=name)
+
+    # 获取列表所有数据
+    def lrange(self, name, start, end):
+        return self.CONN.lrange(name, start, end)
+
+    def get_ttl(self, key):
+        ttl = self.CONN.ttl(key)
+        if ttl:
+            return ttl
+        else:
+            return 0

+ 101 - 0
Object/ResponseObject.py

@@ -0,0 +1,101 @@
+from django.shortcuts import HttpResponse
+import simplejson as json
+
+
+class ResponseObject(object):
+
+    def __init__(self, lang='cn'):
+        self.lang = lang
+
+    def data(self, code, res={}):
+        data_cn = {
+            0: '成功',
+            5: '请一分钟后再尝试',
+            8: '用户账号已存在',
+            9: '用户账号不存在',
+            10: res,
+            42: '两次输入的新密码错误',
+            43: '客户端服务器已关闭,请下载新版本使用',
+            44: '系统错误,发送邮件失败',
+            45: '系统错误,生成令牌出错!',
+            46: '系统错误,发送短信失败!',
+            47: '旧密码不正确',
+            74: '关联旧用户失败!',
+            79: '您已经申请过重置密码,请到邮箱进行确认!',
+            89: '您已经获得了验证码,请在10分钟后检查或再次确认。',
+            99: '账户或密码错误',
+            101: '手机的用户账号已经存在!',
+            102: '手机的用户账号不存在!',
+            103: '邮箱用户帐户已经存在!',
+            104: '邮箱用户帐户不存在!',
+            107: '用户名格式不符合规则!',
+            108: '邮箱格式不符合规则!',
+            110: '因为用户未激活,用户是无效用户!',
+            111: '您输入的密码不正确!',
+            120: '验证码已过期或不存在、请重新获得验证码!',
+            121: '验证码错了!',
+            138: '手机格式不符合规则!',
+            173: '数据不存在!',
+            174: '数据已存在',
+            305: '令牌格式是错误的,相关参数是不存在的!',
+            307: '令牌已过期!',
+            309: '你没有权限访问',
+            404: 'You don not have permission to access this!',
+            444: '请确认参数的正确性!',
+            1112: '您输入的两次密码不一致!',
+            208: '只能预定当天的或者以后的!',
+        }
+        data_en = {
+            0: 'Success',
+            5: 'Please try again one minute later!',
+            8: 'User accounts already exist',
+            9: 'User accounts is not exist',
+            10: res,
+            42: 'The new password entered twice is incorrect',
+            43: 'The client server is closed. Please download the new version for use',
+            44: 'System error,send email fail!',
+            45: 'System error,generate token fail!',
+            46: 'System error, sending SMS failed!',
+            47: 'Old password is incorrect',
+            74: 'Failed to connect old users!',
+            79: 'You have applied for reset password, please go to email for confirmation!',
+            89: 'You have already obtained the verification code, please check it or get it again after 10 minutes.',
+            99: ' ERROR Incorrect account or password',
+            101: 'The user account of the mobile phone has already existed!',
+            102: 'The user account of the mobile phone does not exist!',
+            103: 'The mailbox user account has already existed!',
+            104: 'The mailbox user account does not exist!',
+            107: 'The username format does not conform to the rules!',
+            108: 'The mailbox format does not conform to the rules! ',
+            110: 'Because the user is not activated, the user is an invalid user!',
+            111: 'The password you entered is incorrect!',
+            120: 'The captcha has expired or does not exist, please obtain the captcha again!',
+            121: 'The verification code is wrong!',
+            138: 'The phone format does not conform to the rules! ',
+            173: 'Data does not exists!',
+            174: 'Data already exists',
+            305: 'The Token format is wrong and the related parameter is None!',
+            307: 'The Token has expired!',
+            309: 'You have no access',
+            404: 'You don not have permission to access this!',
+            444: 'Please confirm the correctness of the parameters!',
+            1112: 'The two passwords you entered do not match!',
+        }
+
+        if self.lang == 'cn':
+            msg = data_cn
+        else:
+            msg = data_en
+        try:
+            message = msg[code]
+        except Exception as e:
+            message = '系统错误,code不存在'
+        return {'code': code, 'msg': message, 'res': res}
+
+    def formal(self, code, res={}):
+        formal_data = self.data(code, res)
+        return json.dumps(formal_data,ensure_ascii=False)
+
+    def json(self, code, res={}):
+        result = self.formal(code, res)
+        return HttpResponse(result)

+ 122 - 0
Object/TokenObject.py

@@ -0,0 +1,122 @@
+#!/usr/bin/env python3  
+# -*- coding: utf-8 -*-  
+"""
+@Copyright (C) ansjer cop Video Technology Co.,Ltd.All rights reserved.
+@AUTHOR: ASJRD018
+@NAME: AnsjerOA
+@software: PyCharm
+@DATE: 2018/8/13 15:36
+@Version: python3.6
+@MODIFY DECORD:ansjer dev
+@file: TokenObject.py
+@Contact: chanjunkai@163.com
+"""
+from AnsjerUIDManage.config import OAUTH_ACCESS_TOKEN_SECRET, OAUTH_REFRESH_TOKEN_SECRET, OAUTH_ACCESS_TOKEN_TIME, \
+    OAUTH_REFRESH_TOKEN_TIME
+import jwt, time
+from Object.RedisObject import RedisObject
+
+
+class TokenObject:
+
+    def __init__(self, token=None):
+        self.token = token
+        self.lang = None
+        self.userID = None
+        self.user = ''
+        self.code = 0
+        # 令牌校验
+        self.valid()
+
+    def valid(self):
+        if self.token is None:
+            self.code = 309
+            return
+        try:
+            res = jwt.decode(self.token, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256')
+            # print(res)
+            self.userID = res.get('userID', None)
+            self.lang = res.get('lang', None)
+            self.user = res.get('user', '')
+            # 刷新登录时间
+            # if self.userID:
+            #     print(self.user)
+            #     redisObj = RedisObject(db=3)
+            #     redisObj.set_data(key=self.userID, val=self.user, expire=300)
+
+        except jwt.ExpiredSignatureError as e:
+            print('过期')
+            print(repr(e))
+            self.code = 309
+            return
+        except Exception as e:
+            self.code = 309
+            return
+        else:
+            if not self.userID:
+                self.code = 309
+                return
+            else:
+                if self.userID:
+                    self.code = 0
+                    return res
+                else:
+                    self.code = 309
+                    return
+    # token加密
+    def generate(self, data={}):
+        try:
+            access_expire = int(OAUTH_ACCESS_TOKEN_TIME.total_seconds())
+            refresh_expire = int(OAUTH_REFRESH_TOKEN_TIME.total_seconds())
+            now_stamp = int(time.time())
+            access_data = data
+            refresh_data = data
+            access_data['exp'] = access_expire + now_stamp
+            refresh_data['exp'] = refresh_expire + now_stamp
+            access_token = jwt.encode(access_data,
+                                      OAUTH_ACCESS_TOKEN_SECRET,
+                                      algorithm='HS256')
+            refresh_token = jwt.encode(
+                refresh_data,
+                OAUTH_REFRESH_TOKEN_SECRET,
+                algorithm='HS256')
+            res = {
+                'access_token': access_token.decode('utf-8'),
+                'access_expire': access_expire,
+                'refresh_expire': refresh_expire,
+                'refresh_token': refresh_token.decode('utf-8'),
+            }
+        except Exception as e:
+            self.code = 309
+            print(repr(e))
+        else:
+            self.code = 0
+            return res
+
+    def refresh(self):
+        if not self.token:
+            self.code = 309
+            return
+        try:
+            res = jwt.decode(self.token, OAUTH_REFRESH_TOKEN_SECRET, algorithms='HS256')
+        except jwt.ExpiredSignatureError as e:
+            print('过期')
+            print(repr(e))
+            self.code = 309
+        except Exception as e:
+            self.code = 309
+            print(repr(e))
+        else:
+            self.code = 0
+            userID = res.get('userID', '')
+            user = res.get('user', '')
+            lang = self.lang
+            refreshRes = self.generate(data={'userID': userID, 'lang':lang , 'user': user})
+            return refreshRes
+
+# import jwt
+#
+#
+# token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySUQiOiIxNTMzODg0NDE4NTE5MTM4MDAxMzgwMDAiLCJleHAiOjE1NTU1NTEwNjUsInVzZXIiOiIxMTFAcXEuY29tIiwibGFuZyI6ImVuIn0.waPlfIBucSA7rFfnsxOKIVJ_cL6xiP33cAiz1IDoteY'
+# res = jwt.decode(token, 'a+jbgnw%@1%zy^=@dn62%', algorithms='HS256')
+# print(res)

+ 224 - 0
Service/CommonService.py

@@ -0,0 +1,224 @@
+# -*- coding: utf-8 -*-
+import datetime
+import time
+from pathlib import Path
+from random import Random
+import ipdb
+import simplejson as json
+from django.core import serializers
+from django.utils import timezone
+from pyipip import IPIPDatabase
+from AnsjerUIDManage.config import BASE_DIR, UNICODE_ASCII_CHARACTER_SET
+
+
+# 复用性且公用较高封装代码在这
+class CommonService:
+    # 添加模糊搜索
+    @staticmethod
+    def get_kwargs(data={}):
+        kwargs = {}
+        for (k, v) in data.items():
+            if v is not None and v != u'':
+                kwargs[k + '__icontains'] = v
+        return kwargs
+
+    # 定义静态方法
+    # 格式化query_set转dict
+    @staticmethod
+    def qs_to_dict(query_set):
+        sqlJSON = serializers.serialize('json', query_set)
+        sqlList = json.loads(sqlJSON)
+        sqlDict = dict(zip(["datas"], [sqlList]))
+        return sqlDict
+
+    # 获取文件大小
+    @staticmethod
+    def get_file_size(file_path='', suffix_type='', decimal_point=0):
+
+        # for x in ['bytes', 'KB', 'MB', 'GB', 'TB']:
+        # path = Path() / 'D:/TestServer/123444.mp4'
+        path = Path() / file_path
+        size = path.stat().st_size
+        mb_size = 0.0
+        if suffix_type == 'MB':
+            mb_size = size / 1024.0 / 1024.0
+        if decimal_point != 0:
+            mb_size = round(mb_size, decimal_point)
+        return mb_size
+
+    @staticmethod
+    def get_param_flag(data=[]):
+        # print(data)
+        flag = True
+        for v in data:
+            if v is None:
+                flag = False
+                break
+        return flag
+
+    @staticmethod
+    def get_ip_address(request):
+        """
+        获取ip地址
+        :param request:
+        :return:
+        """
+        try:
+            real_ip = request.META['HTTP_X_FORWARDED_FOR']
+            clientIP = real_ip.split(",")[0]
+        except:
+            try:
+                clientIP = request.META['REMOTE_ADDR']
+            except Exception as e:
+                clientIP = ''
+        return clientIP
+
+    # @获取一天每个小时的datetime.datetime
+    @staticmethod
+    def getTimeDict(times):
+        time_dict = {}
+        t = 0
+        for x in range(24):
+            if x < 10:
+                x = '0' + str(x)
+            else:
+                x = str(x)
+            a = times.strftime("%Y-%m-%d") + " " + x + ":00:00"
+            time_dict[t] = timezone.datetime.strptime(a, '%Y-%m-%d %H:%M:%S')
+            t += 1
+        return time_dict
+
+    # 根据ip获取地址
+    @staticmethod
+    def getAddr(ip):
+        base_dir = BASE_DIR
+        # ip数据库
+        db = IPIPDatabase(base_dir + '/DB/17monipdb.dat')
+        addr = db.lookup(ip)
+        ts = addr.split('\t')[0]
+        return ts
+
+    # 通过ip检索ipip指定信息 lang为CN或EN
+    @staticmethod
+    def getIpIpInfo(ip, lang, update=False):
+        ipbd_dir = BASE_DIR + "/DB/mydata4vipday2.ipdb"
+        db = ipdb.City(ipbd_dir)
+        if update:
+            rr = db.reload(ipbd_dir)
+        info = db.find_map(ip, lang)
+        return info
+
+    @staticmethod
+    def getUserID(userPhone='13800138000', getUser=True, setOTAID=False, μs=True):
+        if μs == True:
+            if getUser == True:
+                timeID = str(round(time.time() * 1000000))
+                userID = timeID + userPhone
+
+                return userID
+            else:
+                if setOTAID == False:
+                    timeID = str(round(time.time() * 1000000))
+                    ID = userPhone + timeID
+
+                    return ID
+                else:
+                    timeID = str(round(time.time() * 1000000))
+                    eID = '13800' + timeID + '138000'
+                    return eID
+        else:
+            if getUser == True:
+                timeID = str(round(time.time() * 1000))
+                userID = timeID + userPhone
+
+                return userID
+            else:
+                if setOTAID == False:
+                    timeID = str(round(time.time() * 1000))
+                    ID = userPhone + timeID
+
+                    return ID
+                else:
+                    timeID = str(round(time.time() * 1000))
+                    eID = '13800' + timeID + '138000'
+                    return eID
+
+    # 生成随机数
+    @staticmethod
+    def RandomStr(randomlength=8, number=True):
+        str = ''
+        if number == False:
+            characterSet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsT' \
+                           'tUuVvWwXxYyZz0123456789'
+        else:
+            characterSet = '0123456789'
+
+        length = len(characterSet) - 1
+
+        random = Random()
+        for index in range(randomlength):
+            str += characterSet[random.randint(0, length)]
+        return str
+
+    # 生成订单好
+    @staticmethod
+    def createOrderID():
+        random_id = CommonService.RandomStr(6, True)
+        order_id = datetime.datetime.now().strftime('%Y%m%d%H%M%S') + str(random_id)
+        print('orderID:')
+        print(order_id)
+        return order_id
+
+    # qs转换list datetime处理
+    @staticmethod
+    def qs_to_list(qs):
+        res = []
+        # print(qs)
+        for ps in qs:
+            try:
+                if 'add_time' in ps:
+                    ps['add_time'] = ps['add_time'].strftime("%Y-%m-%d %H:%M:%S")
+                if 'update_time' in ps:
+                    ps['update_time'] = ps['update_time'].strftime("%Y-%m-%d %H:%M:%S")
+                if 'end_time' in ps:
+                    ps['end_time'] = ps['end_time'].strftime("%Y-%m-%d %H:%M:%S")
+                if 'data_joined' in ps:
+                    if ps['data_joined']:
+                        ps['data_joined'] = ps['data_joined'].strftime("%Y-%m-%d %H:%M:%S")
+                    else:
+                        ps['data_joined'] = ''
+                if 'userID__data_joined' in ps:
+                    if ps['userID__data_joined']:
+                        ps['userID__data_joined'] = ps['userID__data_joined'].strftime("%Y-%m-%d %H:%M:%S")
+                    else:
+                        ps['userID__data_joined'] = ''
+            except Exception as e:
+                pass
+            res.append(ps)
+        return res
+
+    # 获取当前时间
+    @staticmethod
+    def get_now_time_str(n_time, tz):
+        n_time = int(n_time)
+        if tz:
+            n_time = n_time + 3600 * float(tz)
+        n_date = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(int(n_time)))
+        return n_date
+
+    # 生成随机数
+    @staticmethod
+    def encrypt_data(randomlength=8, number=False):
+        str = ''
+        if number == False:
+            characterSet = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsT' \
+                           'tUuVvWwXxYyZz0123456789'
+        else:
+            characterSet = '0123456789'
+
+        length = len(characterSet) - 1
+
+        random = Random()
+        for index in range(randomlength):
+            str += characterSet[random.randint(0, length)]
+        return str

+ 136 - 0
Service/LogMiddleware.py

@@ -0,0 +1,136 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import json
+import threading
+import time
+
+from django.utils.deprecation import MiddlewareMixin
+
+from Model.models import UserModel, LogModel
+from Object import TokenObject
+from Object.TokenObject import TokenObject
+from Service.CommonService import CommonService
+
+
+class LogMiddleware(MiddlewareMixin):
+
+    # def process_request(self, request):
+        # if request.path == '/upload':
+        #     request.encoding = 'utf-8'
+        #     request_dict = request.POST
+        #     print(request.POST)
+        #     request.POST = request_dict
+
+    def process_response(self, request, response):
+
+        if request.path != '/favicon.ico':
+            self.start_log_thread(request, response)
+        return response
+
+    def start_log_thread(self, request, response):
+        print('start_log_thread')
+        asy = threading.Thread(target=add_log, args=(request, response))
+        asy.start()
+
+
+def add_log(request, response):
+    request.encoding = 'utf-8'
+    if request.method == 'GET':
+        request_dict = request.GET
+    elif request.method == 'POST':
+        request_dict = request.POST
+    else:
+        return
+
+    # print(response.content.decode().strip())
+    request_path = request.path.strip().strip('/')
+    print(request_path)
+    jsonObject = {}
+    if request_path == 'download':
+        if response.status_code != 200:
+            return
+    else:
+        jsonObject = json.loads(response.content.decode().strip())
+        code = jsonObject.get('code')
+        if code is None or code != 0 and response.status_code != 200:
+            print('code is {code}'.format(code=code))
+            return
+
+    token = request_dict.get('token', None)
+    # print(token)
+    token = TokenObject(token)
+
+    status = response.status_code
+    # 去除密码
+    contentDict = dict(request_dict)
+    # print(contentDict)
+    password = contentDict.get('password')
+    if password:
+        contentDict.pop('password')
+
+    content = json.dumps(contentDict)
+    ip = CommonService.get_ip_address(request)
+    now_time = time.time()
+
+    if token.code == 0:
+        user_qs = UserModel.objects.filter(id=token.userID)
+    else:
+        # print(token.code)
+        username = request_dict.get('username', None)
+        if username is None:
+            print('username')
+            return
+        user_qs = UserModel.objects.filter(username=username)
+
+    if not user_qs.exists():
+        # print('exists')
+        return
+
+    user = user_qs[0]
+    operation = ''
+    # print(request_path)
+    if request_path == 'user/login':
+        operation = '登录账号'
+    elif request_path == 'user/logout':
+        operation = '退出登录'
+    elif request_path == 'user/modify':
+        operation = '修改密码'
+    elif request_path == 'upload':
+        area = request_dict.get('area', None)
+        count = jsonObject['res']['count']
+        operation = formatOperation('上传', int(count), int(area))
+    elif request_path == 'uid/allot':
+        area = request_dict.get('area', None)
+        quantity = request_dict.get('quantity', None)
+        if area and quantity:
+            operation = formatOperation('分配', int(quantity), int(area))
+    elif request_path == 'download':
+        area = request_dict.get('area', None)
+        quantity = request_dict.get('quantity', None)
+        if area and quantity:
+            operation = formatOperation('下载', int(quantity), int(area))
+    else:
+        return
+
+    log = {
+        'status': status,
+        'content': content,
+        'ip': ip,
+        'time': now_time,
+        'url': request_path,
+        'operation': operation,
+        'user': user
+    }
+
+    try:
+        LogModel.objects.create(**log)
+    except Exception as e:
+        print(repr(e))
+
+
+def formatOperation(operation, quantity, area):
+    str = '{operation}{quantity}个{area}UID'
+    if area == 0:
+        return str.format(operation=operation, quantity=quantity, area='国内')
+    else:
+        return str.format(operation=operation, quantity=quantity, area='国外')

+ 21 - 0
manage.py

@@ -0,0 +1,21 @@
+#!/usr/bin/env python
+"""Django's command-line utility for administrative tasks."""
+import os
+import sys
+
+
+def main():
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'AnsjerUIDManage.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()