system消息通知:修复已读消息bug;permission:接口权限完成。
							parent
							
								
									c9a34da1a5
								
							
						
					
					
						commit
						2514d98173
					
				
							
								
								
									
										15
									
								
								README.md
								
								
								
								
							
							
						
						
									
										15
									
								
								README.md
								
								
								
								
							| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
# Django-Vue-Admin
 | 
			
		||||
 | 
			
		||||
[](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [](https://pypi.org/project/django-simpleui/#history) [](https://python.org/)  [](https://nodejs.org/zh-cn/download/releases/)[](https://pypi.org/project/django-simpleui/)
 | 
			
		||||
[](https://gitee.com/liqianglog/django-vue-admin/blob/master/LICENSE) [](https://pypi.org/project/django-simpleui/#history) [](https://python.org/)  
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -68,9 +68,6 @@ git clone https://gitee.com/liqianglog/django-vue-admin.git
 | 
			
		|||
cd dvadmin-ui
 | 
			
		||||
 | 
			
		||||
# 安装依赖
 | 
			
		||||
npm install
 | 
			
		||||
 | 
			
		||||
# 建议不要直接使用cnpm安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题。
 | 
			
		||||
npm install --registry=https://registry.npm.taobao.org
 | 
			
		||||
 | 
			
		||||
# 启动服务
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +92,12 @@ npm run build:prod
 | 
			
		|||
~~~bash
 | 
			
		||||
1. 进入项目目录 cd dvadmin-backend
 | 
			
		||||
2. 在项目根目录中,复制 ./conf/env.example.py 文件为一份新的到 ./conf 文件夹下,并重命名为 env.py
 | 
			
		||||
 | 
			
		||||
3. 在 env.py 中配置数据库信息
 | 
			
		||||
	mysql数据库版本建议:5.7以上
 | 
			
		||||
	mysql数据库字符集:utf8mb4
 | 
			
		||||
	mysql数据库排序规则:utf8mb4_0900_ai_ci
 | 
			
		||||
	
 | 
			
		||||
4. 安装依赖环境
 | 
			
		||||
	pip3 install -r requirements.txt
 | 
			
		||||
5. 执行迁移命令:
 | 
			
		||||
| 
						 | 
				
			
			@ -104,10 +106,13 @@ npm run build:prod
 | 
			
		|||
6. 初始化数据
 | 
			
		||||
	python3 manage.py init
 | 
			
		||||
7. 启动项目
 | 
			
		||||
	python3 manage.py runserver 0.0.0.0:8000
 | 
			
		||||
	python3 manage.py runserver 127.0.0.1:8000
 | 
			
		||||
 | 
			
		||||
定时任务启动命令:
 | 
			
		||||
	celery -A application  worker -B --loglevel=info
 | 
			
		||||
注:
 | 
			
		||||
	Windows 运行celery 需要安装 pip install eventlet
 | 
			
		||||
	celery -A application  worker -P eventlet --loglevel=info
 | 
			
		||||
 | 
			
		||||
初始账号:admin 密码:123456
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ from conf.env import *
 | 
			
		|||
 | 
			
		||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
 | 
			
		||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 | 
			
		||||
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
 | 
			
		||||
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
 | 
			
		||||
# Quick-start development settings - unsuitable for production
 | 
			
		||||
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,6 +54,7 @@ INSTALLED_APPS = [
 | 
			
		|||
]
 | 
			
		||||
 | 
			
		||||
MIDDLEWARE = [
 | 
			
		||||
    'vadmin.op_drf.middleware.PermissionModeMiddleware',  # 权限中间件
 | 
			
		||||
    'corsheaders.middleware.CorsMiddleware',
 | 
			
		||||
    'django.middleware.security.SecurityMiddleware',
 | 
			
		||||
    'django.contrib.sessions.middleware.SessionMiddleware',
 | 
			
		||||
| 
						 | 
				
			
			@ -202,7 +203,7 @@ LOGGING = {
 | 
			
		|||
    'loggers': {
 | 
			
		||||
        # default日志
 | 
			
		||||
        '': {
 | 
			
		||||
            'handlers': ['console','error','file'],
 | 
			
		||||
            'handlers': ['console', 'error', 'file'],
 | 
			
		||||
            'level': 'INFO',
 | 
			
		||||
        },
 | 
			
		||||
        # 数据库相关日志
 | 
			
		||||
| 
						 | 
				
			
			@ -300,19 +301,19 @@ USERNAME_FIELD = 'username'
 | 
			
		|||
# ************** 登录验证码配置  ************** #
 | 
			
		||||
# ================================================= #
 | 
			
		||||
CAPTCHA_STATE = CAPTCHA_STATE
 | 
			
		||||
#字母验证码
 | 
			
		||||
CAPTCHA_IMAGE_SIZE = (160, 60)   # 设置 captcha 图片大小
 | 
			
		||||
CAPTCHA_LENGTH = 4   # 字符个数
 | 
			
		||||
CAPTCHA_TIMEOUT = 1   # 超时(minutes)
 | 
			
		||||
#加减乘除验证码
 | 
			
		||||
# 字母验证码
 | 
			
		||||
CAPTCHA_IMAGE_SIZE = (160, 60)  # 设置 captcha 图片大小
 | 
			
		||||
CAPTCHA_LENGTH = 4  # 字符个数
 | 
			
		||||
CAPTCHA_TIMEOUT = 1  # 超时(minutes)
 | 
			
		||||
# 加减乘除验证码
 | 
			
		||||
CAPTCHA_OUTPUT_FORMAT = '%(image)s %(text_field)s %(hidden_field)s '
 | 
			
		||||
CAPTCHA_FONT_SIZE = 40 # 字体大小
 | 
			
		||||
CAPTCHA_FONT_SIZE = 40  # 字体大小
 | 
			
		||||
CAPTCHA_FOREGROUND_COLOR = '#0033FF'  # 前景色
 | 
			
		||||
CAPTCHA_BACKGROUND_COLOR = '#F5F7F4'  # 背景色
 | 
			
		||||
CAPTCHA_NOISE_FUNCTIONS = (
 | 
			
		||||
                           # 'captcha.helpers.noise_arcs', # 线
 | 
			
		||||
                           # 'captcha.helpers.noise_dots', # 点
 | 
			
		||||
                           )
 | 
			
		||||
    # 'captcha.helpers.noise_arcs', # 线
 | 
			
		||||
    # 'captcha.helpers.noise_dots', # 点
 | 
			
		||||
)
 | 
			
		||||
# CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.random_char_challenge'
 | 
			
		||||
CAPTCHA_CHALLENGE_FUNCT = 'captcha.helpers.math_challenge'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -320,5 +321,10 @@ API_LOG_ENABLE = True
 | 
			
		|||
# API_LOG_METHODS = 'ALL' # ['POST', 'DELETE']
 | 
			
		||||
# API_LOG_METHODS = ['POST', 'DELETE'] # ['POST', 'DELETE']
 | 
			
		||||
BROKER_URL = f'redis://:{REDIS_PASSWORD if REDIS_PASSWORD else ""}@{os.getenv("REDIS_HOST") or REDIS_HOST}:' \
 | 
			
		||||
             f'{REDIS_PORT}/{locals().get("CELERY_DB",2)}'    #Broker使用Redis
 | 
			
		||||
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'    #Backend数据库
 | 
			
		||||
             f'{REDIS_PORT}/{locals().get("CELERY_DB", 2)}'  # Broker使用Redis
 | 
			
		||||
CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'  # Backend数据库
 | 
			
		||||
# ================================================= #
 | 
			
		||||
# ************** 其他配置  ************** #
 | 
			
		||||
# ================================================= #
 | 
			
		||||
# 接口权限
 | 
			
		||||
INTERFACE_PERMISSION = {locals().get("INTERFACE_PERMISSION", False)}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ from django.urls import re_path, include
 | 
			
		|||
from django.views.static import serve
 | 
			
		||||
from rest_framework.views import APIView
 | 
			
		||||
 | 
			
		||||
from apps.vadmin.op_drf.response import SuccessResponse
 | 
			
		||||
from vadmin.utils.response import SuccessResponse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CaptchaRefresh(APIView):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,20 @@
 | 
			
		|||
"""
 | 
			
		||||
django中间件
 | 
			
		||||
"""
 | 
			
		||||
import logging
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth.models import AnonymousUser
 | 
			
		||||
from django.utils.deprecation import MiddlewareMixin
 | 
			
		||||
 | 
			
		||||
from apps.vadmin.permission.models import Menu
 | 
			
		||||
from apps.vadmin.system.models import OperationLog
 | 
			
		||||
from ..utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \
 | 
			
		||||
    get_login_location
 | 
			
		||||
    get_login_location, get_request_canonical_path, get_request_user
 | 
			
		||||
from ..utils.response import ErrorJsonResponse
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ApiLoggingMiddleware(MiddlewareMixin):
 | 
			
		||||
| 
						 | 
				
			
			@ -77,3 +83,78 @@ class PermissionModeMiddleware(MiddlewareMixin):
 | 
			
		|||
    """
 | 
			
		||||
    权限模式拦截判断
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def process_request(self, request):
 | 
			
		||||
        """
 | 
			
		||||
        判断环境变量中,是否为演示模式(正常可忽略此判断)
 | 
			
		||||
        :param request:
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        white_list = ['/admin/logout/', '/admin/login/']
 | 
			
		||||
        if os.getenv('DEMO_ENV') and not request.method == 'GET' and request.path not in white_list:
 | 
			
		||||
            return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!')
 | 
			
		||||
 | 
			
		||||
    def has_interface_permission(self, request, method, view_path, user=None):
 | 
			
		||||
        """
 | 
			
		||||
        接口权限验证,优先级:
 | 
			
		||||
        (1)接口是否接入权限管理, 是:继续; 否:通过
 | 
			
		||||
        (2)认证的user是否superuser, 是:通过; 否:继续
 | 
			
		||||
        (3)user的角色有该接口权限, 是:通过, 否:不通过
 | 
			
		||||
 | 
			
		||||
        auth_code含义: auth_code >=0, 表示接口认证通过; auth_code < 0, 表示无接口访问权限, 具体含义如下
 | 
			
		||||
         -1:
 | 
			
		||||
         -10: 该请求已认证的用户没有这个接口的访问权限
 | 
			
		||||
           0:
 | 
			
		||||
           1: 白名单
 | 
			
		||||
          10: 该接口没有录入权限系统, 放行 请求中认证的用户为超级管理员, 直接放行
 | 
			
		||||
          20: 请求中认证的用户是superuser放行
 | 
			
		||||
          30: 请求中认证的用户对应的角色中,某个角色包含了该接口的访问权限, 放行
 | 
			
		||||
        1. 先获取所有录入系统的接口
 | 
			
		||||
        2  判断此用户是否为 superuser
 | 
			
		||||
        3. 获取此用户所请求的接口
 | 
			
		||||
        4. 获取此用户关联角色所有有权限的接口
 | 
			
		||||
 | 
			
		||||
        :param interface: 接口模型
 | 
			
		||||
        :param path: 接口路径
 | 
			
		||||
        :param method: 请求方法
 | 
			
		||||
        :param project: 接口所属项目
 | 
			
		||||
        :param args:
 | 
			
		||||
        :param kwargs:
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        interface_dict = Menu.get_interface_dict()
 | 
			
		||||
        # (1) 接口是否接入权限管理, 是:继续; 否:通过
 | 
			
		||||
        if not view_path in interface_dict.get(method, []):
 | 
			
		||||
            return 10
 | 
			
		||||
        # (2)认证的user是否superuser, 是:通过; 否:继续
 | 
			
		||||
        if user.is_superuser or (hasattr(user, 'role') and user.role.filter(status='1', admin=True).count()):
 | 
			
		||||
            return 20
 | 
			
		||||
        # (3)user的角色有该接口权限, 是:通过, 否:不通过
 | 
			
		||||
        if view_path in user.get_user_interface_dict:
 | 
			
		||||
            return 30
 | 
			
		||||
        return -10
 | 
			
		||||
 | 
			
		||||
    def process_view(self, request, view_func, view_args, view_kwargs):
 | 
			
		||||
        if not settings.INTERFACE_PERMISSION:
 | 
			
		||||
            return
 | 
			
		||||
        user = get_request_user(request)
 | 
			
		||||
 | 
			
		||||
        if user and not isinstance(user, AnonymousUser):
 | 
			
		||||
            method = request.method.upper()
 | 
			
		||||
            if method == 'GET': # GET 不设置接口权限
 | 
			
		||||
                return
 | 
			
		||||
            view_path = get_request_canonical_path(request, *view_args, **view_kwargs)
 | 
			
		||||
            auth_code = self.has_interface_permission(request, method, view_path, user)
 | 
			
		||||
            logger.info(f"[{user.username}] {method}:{view_path}, 权限认证:{auth_code}")
 | 
			
		||||
            if auth_code >= 0:
 | 
			
		||||
                return
 | 
			
		||||
            return ErrorJsonResponse(data={}, msg=f'无接口访问权限!')
 | 
			
		||||
 | 
			
		||||
    def process_response(self, request, response):
 | 
			
		||||
        """
 | 
			
		||||
        主要请求处理完之后记录
 | 
			
		||||
        :param request:
 | 
			
		||||
        :param response:
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        return response
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
from django.db.models import IntegerField, ForeignKey, CharField, CASCADE
 | 
			
		||||
from django.core.cache import cache
 | 
			
		||||
from django.db.models import IntegerField, ForeignKey, CharField, CASCADE, Q
 | 
			
		||||
 | 
			
		||||
from ...op_drf.models import CoreModel
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +35,31 @@ class Menu(CoreModel):
 | 
			
		|||
    visible = CharField(max_length=8, verbose_name="显示状态")
 | 
			
		||||
    isCache = CharField(max_length=8, verbose_name="是否缓存")
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def get_interface_dict(cls):
 | 
			
		||||
        """
 | 
			
		||||
        获取所有接口列表
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        interface_dict = cache.get('permission_interface_dict', {})
 | 
			
		||||
        if not interface_dict:
 | 
			
		||||
            for ele in Menu.objects.filter(~Q(interface_path=''), ~Q(interface_path=None), status='1', ).values(
 | 
			
		||||
                    'interface_path', 'interface_method'):
 | 
			
		||||
                if ele.get('interface_method') in interface_dict:
 | 
			
		||||
                    interface_dict[ele.get('interface_method', '')].append(ele.get('interface_path'))
 | 
			
		||||
                else:
 | 
			
		||||
                    interface_dict[ele.get('interface_method', '')] = [ele.get('interface_path')]
 | 
			
		||||
            cache.set('permission_interface_dict', interface_dict, 84600)
 | 
			
		||||
        return interface_dict
 | 
			
		||||
 | 
			
		||||
    @classmethod
 | 
			
		||||
    def delete_cache(cls):
 | 
			
		||||
        """
 | 
			
		||||
        清空缓存中的接口列表
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        cache.delete('permission_interface_dict')
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = '菜单管理'
 | 
			
		||||
        verbose_name_plural = verbose_name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django.contrib.auth.models import UserManager, AbstractUser
 | 
			
		||||
from django.core.cache import cache
 | 
			
		||||
from django.db.models import IntegerField, ForeignKey, CharField, TextField, ManyToManyField, CASCADE
 | 
			
		||||
 | 
			
		||||
from ...op_drf.fields import CreateDateTimeField, UpdateDateTimeField
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +29,29 @@ class UserProfile(AbstractUser):
 | 
			
		|||
    create_datetime = CreateDateTimeField()
 | 
			
		||||
    update_datetime = UpdateDateTimeField()
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def get_user_interface_dict(self):
 | 
			
		||||
        interface_dict = cache.get(f'permission_interface_dict{self.username}', {})
 | 
			
		||||
        if not interface_dict:
 | 
			
		||||
            for ele in self.role.filter(status='1', menu__status='1').values('menu__interface_path',
 | 
			
		||||
                                                                             'menu__interface_method').distinct():
 | 
			
		||||
                interface_path = ele.get('menu__interface_path')
 | 
			
		||||
                if interface_path is None or interface_path == '':
 | 
			
		||||
                    continue
 | 
			
		||||
                if ele.get('menu__interface_method') in interface_dict:
 | 
			
		||||
                    interface_dict[ele.get('menu__interface_method', '')].append(interface_path)
 | 
			
		||||
                else:
 | 
			
		||||
                    interface_dict[ele.get('menu__interface_method', '')] = [interface_path]
 | 
			
		||||
            cache.set(f'permission_interface_dict_{self.username}', interface_dict, 84600)
 | 
			
		||||
        return interface_dict
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def delete_cache(self):
 | 
			
		||||
        """
 | 
			
		||||
        清空缓存中的接口列表
 | 
			
		||||
        :return:
 | 
			
		||||
        """
 | 
			
		||||
        return cache.delete(f'permission_interface_dict_{self.username}')
 | 
			
		||||
    class Meta:
 | 
			
		||||
        verbose_name = '用户管理'
 | 
			
		||||
        verbose_name_plural = verbose_name
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,11 +87,9 @@ class CommonPermission(CustomPermission):
 | 
			
		|||
        return int(instance.dept_belong_id) in list(set(dept_list))
 | 
			
		||||
 | 
			
		||||
    def has_permission(self, request: Request, view: APIView):
 | 
			
		||||
        """判断是否为演示模式"""
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def has_object_permission(self, request: Request, view: APIView, instance):
 | 
			
		||||
        self.message = f"没有此数据操作权限!"
 | 
			
		||||
        res = self.check_queryset(request, instance)
 | 
			
		||||
        print(res)
 | 
			
		||||
        return res
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,6 +37,10 @@ class MenuCreateUpdateSerializer(CustomModelSerializer):
 | 
			
		|||
        #         raise APIException(message=f'仅Manger能创建/更新角色为公共角色')
 | 
			
		||||
        return super().validate(attrs)
 | 
			
		||||
 | 
			
		||||
    def save(self, **kwargs):
 | 
			
		||||
        Menu.delete_cache()
 | 
			
		||||
        return super().save(**kwargs)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Menu
 | 
			
		||||
        fields = '__all__'
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +95,7 @@ class DeptTreeSerializer(serializers.ModelSerializer):
 | 
			
		|||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Dept
 | 
			
		||||
        fields = ('id', 'label', 'parentId','status')
 | 
			
		||||
        fields = ('id', 'label', 'parentId', 'status')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# ================================================= #
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,7 @@ class GetUserProfileView(APIView):
 | 
			
		|||
        user_dict = UserProfileSerializer(request.user).data
 | 
			
		||||
        permissions_list = ['*:*:*'] if user_dict.get('admin') else Menu.objects.filter(
 | 
			
		||||
            role__userprofile=request.user).values_list('perms', flat=True)
 | 
			
		||||
        delete_cache = request.user.delete_cache
 | 
			
		||||
        return SuccessResponse({
 | 
			
		||||
            'permissions': [ele for ele in permissions_list if ele],
 | 
			
		||||
            'roles': Role.objects.filter(userprofile=request.user).values_list('roleKey', flat=True),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,9 +22,9 @@ from django.urls import re_path, include
 | 
			
		|||
from rest_framework.documentation import include_docs_urls
 | 
			
		||||
from rest_framework.views import APIView
 | 
			
		||||
 | 
			
		||||
from .op_drf.response import SuccessResponse
 | 
			
		||||
from .permission.views import GetUserProfileView, GetRouters
 | 
			
		||||
from .utils.login import LoginView, LogoutView
 | 
			
		||||
from .utils.response import SuccessResponse
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CaptchaRefresh(APIView):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,10 +8,10 @@ from django.contrib.auth.models import AbstractBaseUser
 | 
			
		|||
from django.contrib.auth.models import AnonymousUser
 | 
			
		||||
from django.core.cache import cache
 | 
			
		||||
from django.urls.resolvers import ResolverMatch
 | 
			
		||||
from rest_framework.authentication import BaseAuthentication
 | 
			
		||||
from rest_framework.settings import api_settings as drf_settings
 | 
			
		||||
from user_agents import parse
 | 
			
		||||
 | 
			
		||||
from apps.vadmin.utils.authentication import OpAuthJwtAuthentication
 | 
			
		||||
 | 
			
		||||
logger = logging.getLogger(__name__)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,18 +26,8 @@ def get_request_user(request, authenticate=True):
 | 
			
		|||
    user: AbstractBaseUser = getattr(request, 'user', None)
 | 
			
		||||
    if user and user.is_authenticated:
 | 
			
		||||
        return user
 | 
			
		||||
    authentication: BaseAuthentication = None
 | 
			
		||||
    for authentication_class in drf_settings.DEFAULT_AUTHENTICATION_CLASSES:
 | 
			
		||||
        try:
 | 
			
		||||
            authentication = authentication_class()
 | 
			
		||||
            user_auth_tuple = authentication.authenticate(request)
 | 
			
		||||
            if user_auth_tuple is not None:
 | 
			
		||||
                user, token = user_auth_tuple
 | 
			
		||||
                if authenticate:
 | 
			
		||||
                    request.user = user
 | 
			
		||||
                return user
 | 
			
		||||
        except Exception:
 | 
			
		||||
            pass
 | 
			
		||||
    user, tokrn = OpAuthJwtAuthentication().authenticate(request)
 | 
			
		||||
    print(22, user)
 | 
			
		||||
    return user or AnonymousUser()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,9 +117,11 @@ def get_request_canonical_path(request, *args, **kwargs):
 | 
			
		|||
    for value in resolver_match.args:
 | 
			
		||||
        path = path.replace(f"/{value}", "/{id}")
 | 
			
		||||
    for key, value in resolver_match.kwargs.items():
 | 
			
		||||
        path = path.replace(f"/{value}", f"/{{{key}}}")
 | 
			
		||||
        if key == 'pk':
 | 
			
		||||
            pass
 | 
			
		||||
            path = path.replace(f"/{value}", f"/{{id}}")
 | 
			
		||||
            continue
 | 
			
		||||
        path = path.replace(f"/{value}", f"/{{{key}}}")
 | 
			
		||||
 | 
			
		||||
    return path
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
"""
 | 
			
		||||
常用的Response以及Django的Response、DRF的Response
 | 
			
		||||
"""
 | 
			
		||||
from django.http.response import DjangoJSONEncoder
 | 
			
		||||
from django.http.response import DjangoJSONEncoder, JsonResponse
 | 
			
		||||
from rest_framework.response import Response
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -56,3 +56,36 @@ class ErrorResponse(Response):
 | 
			
		|||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return str(self.std_data)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SuccessJsonResponse(JsonResponse):
 | 
			
		||||
    """
 | 
			
		||||
    标准JsonResponse, SuccessJsonResponse(data)SuccessJsonResponse(data=data)
 | 
			
		||||
    (1)仅SuccessResponse无法使用时才能推荐使用SuccessJsonResponse
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, data, msg='success', encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs):
 | 
			
		||||
        std_data = {
 | 
			
		||||
            "code": 200,
 | 
			
		||||
            "data": data,
 | 
			
		||||
            "msg": msg,
 | 
			
		||||
            "status": 'success'
 | 
			
		||||
        }
 | 
			
		||||
        super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ErrorJsonResponse(JsonResponse):
 | 
			
		||||
    """
 | 
			
		||||
    标准JsonResponse, 仅ErrorResponse无法使用时才能使用ErrorJsonResponse
 | 
			
		||||
    (1)默认错误码返回2001, 也可以指定其他返回码:ErrorJsonResponse(code=xxx)
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    def __init__(self, data, msg='error', code=201, encoder=OpDRFJSONEncoder, safe=True, json_dumps_params=None,
 | 
			
		||||
                 **kwargs):
 | 
			
		||||
        std_data = {
 | 
			
		||||
            "code": code,
 | 
			
		||||
            "data": data,
 | 
			
		||||
            "msg": msg,
 | 
			
		||||
            "status": 'error'
 | 
			
		||||
        }
 | 
			
		||||
        super().__init__(std_data, encoder, safe, json_dumps_params, **kwargs)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,3 +39,5 @@ CAPTCHA_STATE = True
 | 
			
		|||
# 操作日志配置
 | 
			
		||||
API_LOG_ENABLE = True
 | 
			
		||||
API_LOG_METHODS = ['POST', 'DELETE', 'PUT'] # 'ALL' or ['POST', 'DELETE']
 | 
			
		||||
# 接口权限
 | 
			
		||||
INTERFACE_PERMISSION = True
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,9 +39,9 @@
 | 
			
		|||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
import { getToken } from "@/utils/auth";
 | 
			
		||||
  import {getToken} from "@/utils/auth";
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    // 值
 | 
			
		||||
    value: [String, Object, Array],
 | 
			
		||||
| 
						 | 
				
			
			@ -135,8 +135,12 @@ export default {
 | 
			
		|||
    },
 | 
			
		||||
    // 上传成功回调
 | 
			
		||||
    handleUploadSuccess(res, file) {
 | 
			
		||||
      this.$message.success("上传成功");
 | 
			
		||||
      this.$emit("input", res.url);
 | 
			
		||||
      if (res.code === 200) {
 | 
			
		||||
        this.$message.success("上传成功");
 | 
			
		||||
        this.$emit("input", res.data.file);
 | 
			
		||||
      } else {
 | 
			
		||||
        this.$message.error(res.msg);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    // 删除文件
 | 
			
		||||
    handleDelete(index) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue