diff --git a/test_client/src/router/index.js b/test_client/src/router/index.js index fd6855c..b5297fa 100644 --- a/test_client/src/router/index.js +++ b/test_client/src/router/index.js @@ -216,23 +216,11 @@ export const asyncRoutes = [ meta: { title: '轮播图', icon: '', perms: ['banner_manage'] } }, { - path: 'user', - name: 'User', - component: () => import('@/views/system/user.vue'), - meta: { title: '用户管理', icon: '', perms: ['user_manage'] } + path: 'admin', + name: 'Admin', + component: () => import('@/views/system/admin.vue'), + meta: { title: '管理员', icon: '', perms: ['admin_manage'] } }, - { - path: 'organization', - name: 'Organization', - component: () => import('@/views/system/organization'), - meta: { title: '部门管理', icon: '', perms: ['organization_manage'] } - }, - { - path: 'role', - name: 'Role', - component: () => import('@/views/system/role'), - meta: { title: '角色管理', icon: '', perms: ['role_manage'] } - } ] }, // 404 page must be placed at the end !!! diff --git a/test_client/src/views/system/admin.vue b/test_client/src/views/system/admin.vue new file mode 100644 index 0000000..9ab245e --- /dev/null +++ b/test_client/src/views/system/admin.vue @@ -0,0 +1,161 @@ + + diff --git a/test_mini/app.js b/test_mini/app.js index 8d91138..97d8a49 100644 --- a/test_mini/app.js +++ b/test_mini/app.js @@ -48,9 +48,9 @@ App({ globalData: { userInfo: null, userinfo: null, // 服务器传回的消费者信息 - host: 'https://apitest.ctcshe.com', + // host: 'https://apitest.ctcshe.com', mediahost: 'https://apitest.ctcshe.com', - // host: 'http://127.0.0.1:8000', + host: 'http://127.0.0.1:8000', // mediahost: 'http://127.0.0.1:8000', token : '', subject:null, diff --git a/test_mini/pages/login/login.js b/test_mini/pages/login/login.js index cacd932..be6a234 100644 --- a/test_mini/pages/login/login.js +++ b/test_mini/pages/login/login.js @@ -92,6 +92,7 @@ Page({ that.data.form.nickname = e.detail.userInfo.nickName that.data.form.avatar = e.detail.userInfo.avatarUrl } + if(that.isPhone(that.data.form.phone)){ that.denglu(that.data.form) }else{ @@ -107,7 +108,7 @@ Page({ }) }, denglu: function (data) { - api.request('crm/consumer/register/', 'POST', data).then(res => { + api.request('/crm/consumer/register/', 'POST', data).then(res => { getApp().onLaunch() wx.switchTab({ url: '/pages/main/main', diff --git a/test_server/crm/authentication.py b/test_server/crm/authentication.py index 5e76228..73d6e93 100644 --- a/test_server/crm/authentication.py +++ b/test_server/crm/authentication.py @@ -4,23 +4,27 @@ from rest_framework import exceptions from django.utils.translation import ugettext as _ from crm.models import Consumer - -class ConsumerTokenAuthentication(JSONWebTokenAuthentication): +from rbac.models import UserProfile + +class MyTokenAuthentication(JSONWebTokenAuthentication): def authenticate_credentials(self, payload): """ - 返回登陆消费者 + 返回登陆人员(学员或管理员) """ id = payload['user_id'] - if not id: msg = _('签名有误.') raise exceptions.AuthenticationFailed(msg) - - try: - consumer = Consumer.objects.get(id=id) - except Consumer.DoesNotExist: - msg = _('消费者不存在') - raise exceptions.AuthenticationFailed(msg) - - - return consumer \ No newline at end of file + if 'type' in payload and payload['type'] == 'consumer': + try: + user = Consumer.objects.get(id=id) + except Consumer.DoesNotExist: + msg = _('消费者不存在') + raise exceptions.AuthenticationFailed(msg) + else: + try: + user = UserProfile.objects.get(id=id) + except UserProfile.DoesNotExist: + msg = _('管理员不存在') + raise exceptions.AuthenticationFailed(msg) + return user \ No newline at end of file diff --git a/test_server/crm/permission.py b/test_server/crm/permission.py index 69a8e61..980ff5a 100644 --- a/test_server/crm/permission.py +++ b/test_server/crm/permission.py @@ -1,6 +1,47 @@ +from rbac.permission import RbacPermission +from rbac.permission import get_permission_list +from rbac.models import UserProfile +from crm.models import Consumer from rest_framework.permissions import IsAuthenticated +# 学员接口列表 +ConsumerPerms = [ + 'paper_list', + 'gen_monitest', + 'my_collects', + 'my_paid', + 'examtest_selftest', + 'examtest_selffx', + 'examtest_create', + 'questioncat_list' +] + +class MyPermission(RbacPermission): -class IsConsumerAuthenticated(IsAuthenticated): def has_permission(self, request, view): - return bool(request.user) \ No newline at end of file + """ + 权限校验逻辑 + :param request: + :param view: + :return: + """ + perms = [] + if 'perms' in request.session: + perms = request.session['perms'] + elif isinstance(request.user,UserProfile): # 如果是管理员表 + perms = get_permission_list(request.user) + elif isinstance(request.user,Consumer): + perms = ConsumerPerms + if perms: + if 'admin' in perms: + return True + elif not hasattr(view, 'perms_map'): + return True + else: + perms_map = view.perms_map + _method = request._request.method.lower() + for i in perms_map: + for method, alias in i.items(): + if (_method == method or method == '*') and alias in perms: + return True + return False \ No newline at end of file diff --git a/test_server/crm/views.py b/test_server/crm/views.py index 2c96469..30b43b3 100644 --- a/test_server/crm/views.py +++ b/test_server/crm/views.py @@ -1,36 +1,32 @@ -from rest_framework.filters import SearchFilter, OrderingFilter -from rest_framework.permissions import IsAuthenticated -from rest_framework.views import APIView -from rest_framework.viewsets import ModelViewSet -from rest_framework.response import Response -from rest_framework.permissions import IsAuthenticated -from rest_framework.decorators import action -from rest_framework import status -from django_filters.rest_framework import DjangoFilterBackend -from openpyxl import Workbook, load_workbook -import requests -from rest_framework_jwt.authentication import JSONWebTokenAuthentication -from rest_framework_jwt.serializers import jwt_encode_handler import json import random -from rest_framework_jwt.settings import api_settings +import warnings from calendar import timegm from datetime import datetime -import warnings - +import requests +from django_filters.rest_framework import DjangoFilterBackend +from openpyxl import Workbook, load_workbook +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.filters import OrderingFilter, SearchFilter +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework.viewsets import ModelViewSet +from rest_framework_jwt.authentication import JSONWebTokenAuthentication +from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler +from rest_framework_jwt.settings import api_settings +from crm.zhenzismsclient import ZhenziSmsClient +from examtest.models_paper import WorkScope +from question.models import Questioncat +from question.serializers import QuestionSerializer +from server import settings from utils.custom import CommonPagination -from rbac.permission import RbacPermission -from crm.authentication import ConsumerTokenAuthentication -from crm.permission import IsConsumerAuthenticated + from .models import Company, Consumer, PaySubject, SendCode from .serializers import CompanySerializer, ConsumerSerializer -from question.serializers import QuestionSerializer -from examtest.models_paper import WorkScope -from server import settings -from question.models import Questioncat -from crm.zhenzismsclient import ZhenziSmsClient appid = 'wxf1e9471c93f05ad6' secret = '4bf7f9bd6c52634586bbe792a1f0a834' @@ -41,6 +37,7 @@ sms_url = 'https://sms_developer.zhenzikj.com' def jwt_payload_handler(user): payload = { 'user_id': user.pk, + 'type':'consumer', 'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA } if api_settings.JWT_ALLOW_REFRESH: @@ -60,9 +57,9 @@ class CompanyViewSet(ModelViewSet): """ 客户企业:增删改查 """ - perms_map = ( - {'*': 'admin'}, {'*': 'company_all'}, {'get': 'company_list'}, {'post': 'company_create'}, - {'put': 'company_update'}, {'delete': 'company_delete'}) + perms_map = [ + {'get': 'company_list'}, {'post': 'company_create'}, + {'put': 'company_update'}, {'delete': 'company_delete'}] queryset = Company.objects.filter(is_delete=0).all() serializer_class = CompanySerializer pagination_class = None #不分页 @@ -70,35 +67,14 @@ class CompanyViewSet(ModelViewSet): search_fields = ('^name',) ordering_fields = ('id',) ordering = ['-id'] - - def check_permissions(self, request): - """ - Check if the request should be permitted. - Raises an appropriate exception if the request is not permitted. - """ - if request.method == 'GET': - pass - else: - for permission in self.get_permissions(): - if not permission.has_permission(request, self): - self.permission_denied( - request, message=getattr(permission, 'message', None) - ) - - def destroy(self, request, *args, **kwargs): #逻辑删除 - instance = self.get_object() - # self.perform_destroy(instance) - instance.is_delete = True - instance.save() - return Response(status=status.HTTP_204_NO_CONTENT) class ConsumerViewSet(ModelViewSet): """ 学员:增删改查 """ - perms_map = ( - {'*': 'admin'}, {'*': 'consumer_all'}, {'get': 'consumer_list'}, {'post': 'consumer_create'}, - {'put': 'consumer_update'}, {'delete': 'consumer_delete'}) + perms_map = [ + {'get': 'consumer_list'}, {'post': 'consumer_create'}, + {'put': 'consumer_update'}, {'delete': 'consumer_delete'}] queryset = Consumer.objects.filter(is_delete=0).all() serializer_class = ConsumerSerializer pagination_class = CommonPagination @@ -132,8 +108,8 @@ class ConsumerViewSet(ModelViewSet): PaySubject.objects.get_or_create(consumer = instance, subject__id=i, defaults={'consumer':instance,'subject':Questioncat.objects.get(id=i)}) return Response(serializer.data) - @action(methods=['get'], detail=False, permission_classes=[IsConsumerAuthenticated], authentication_classes=[ConsumerTokenAuthentication], - url_path='subjectpaid', url_name='subject_paid') + @action(methods=['get'], detail=False, + url_path='subjectpaid', url_name='subject_paid',perms_map=[{'get':'my_paid'}]) def has_paid(self, request): """ 当前登陆消费者已付费的学科 @@ -142,8 +118,8 @@ class ConsumerViewSet(ModelViewSet): data = queryset.values_list('subject__id',flat=True) return Response(data) - @action(methods=['get'], detail=False, permission_classes=[], authentication_classes=[], - url_path='sendcode', url_name='code_send') + @action(methods=['get'], detail=False, + url_path='sendcode', url_name='code_send',authentication_classes=[],permission_classes=[]) def sendcode(self, request): ''' 发送验证码 @@ -159,8 +135,8 @@ class ConsumerViewSet(ModelViewSet): else: return Response({'error':result['data']}) - @action(methods=['post','delete','get'], detail=False, permission_classes=[IsConsumerAuthenticated], authentication_classes=[ConsumerTokenAuthentication], - url_path='collects', url_name='create_collects') + @action(methods=['post','delete','get'], detail=False, + url_path='collects', url_name='create_collects', perms_map=[{'get':'my_collects'}]) def collects(self, request): ''' 个人收藏集 @@ -186,7 +162,7 @@ class ConsumerViewSet(ModelViewSet): return Response({'error':'delete参数错误'}) - @action(methods=['post'], detail=False, permission_classes=[IsAuthenticated], + @action(methods=['post'], detail=False, url_path='import', url_name='import_consumer') def import_consumer(self, request): """ @@ -284,7 +260,7 @@ class ConsumerRegister(APIView): ''' 验证码登陆和注册 ''' - authentication_classes = [ConsumerTokenAuthentication] + authentication_classes = [] permission_classes = [] def post(self, request, *args, **kwargs): data = request.data @@ -320,4 +296,4 @@ class ConsumerRegister(APIView): else: return Response({'error':'认证错误!'}) else: - return Response({'error':'信息不全!'}) \ No newline at end of file + return Response({'error':'信息不全!'}) diff --git a/test_server/examtest/models.py b/test_server/examtest/models.py index d8d71f4..460ea9e 100644 --- a/test_server/examtest/models.py +++ b/test_server/examtest/models.py @@ -8,7 +8,7 @@ from .models_paper import WorkScope, Paper class ExamTest(CommonModel): ''' - 硬删除 + 考试记录表 ''' type_choices = ( ('自助模考', '自助模考'), @@ -28,7 +28,7 @@ class ExamTest(CommonModel): detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail') is_pass = models.BooleanField(default=True, verbose_name='是否通过') class Meta: - verbose_name = '考试表' + verbose_name = '模拟考试' verbose_name_plural = verbose_name diff --git a/test_server/examtest/serializers.py b/test_server/examtest/serializers.py index 0e95e57..987e962 100644 --- a/test_server/examtest/serializers.py +++ b/test_server/examtest/serializers.py @@ -54,7 +54,7 @@ class ExamTestListSerializer(serializers.ModelSerializer): start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") workscope_name = serializers.StringRelatedField(source='workscope', read_only=True) - paper_name = serializers.StringRelatedField(source='papaer', read_only=True) + paper_name = serializers.StringRelatedField(source='paper', read_only=True) consumer_name = serializers.SerializerMethodField() class Meta: model = ExamTest @@ -89,10 +89,11 @@ class PaperQuestionsDetailSerializer(serializers.ModelSerializer): options = serializers.ReadOnlyField(source='question.options') right = serializers.ReadOnlyField(source='question.right') type = serializers.ReadOnlyField(source='question.type') + questioncat_name = serializers.ReadOnlyField(source='question.questioncat.name') level = serializers.ReadOnlyField(source='question.level') class Meta: model = PaperQuestions - fields = ('id','name','options','right','type','level','total_score') + fields = ('id','name','options','right','type','level','total_score','questioncat_name') class PaperDetailSerializer(serializers.ModelSerializer): create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) diff --git a/test_server/examtest/views.py b/test_server/examtest/views.py index cd43879..305dd22 100644 --- a/test_server/examtest/views.py +++ b/test_server/examtest/views.py @@ -1,30 +1,31 @@ -from rest_framework.filters import SearchFilter, OrderingFilter -from rest_framework.permissions import IsAuthenticated -from rest_framework.views import APIView -from rest_framework.viewsets import ModelViewSet -from rest_framework.generics import GenericAPIView -from rest_framework.response import Response -from rest_framework.decorators import action -from rest_framework import status +from datetime import datetime + +from django.db.models import Avg from django_filters.rest_framework import DjangoFilterBackend from openpyxl import Workbook, load_workbook +from rest_framework import status +from rest_framework.decorators import action +from rest_framework.filters import OrderingFilter, SearchFilter +from rest_framework.generics import GenericAPIView +from rest_framework.permissions import IsAuthenticated +from rest_framework.response import Response +from rest_framework.views import APIView +from rest_framework.viewsets import ModelViewSet from rest_framework_jwt.authentication import JSONWebTokenAuthentication -from datetime import datetime -from django.db.models import Avg -from utils.custom import CommonPagination -from rbac.permission import RbacPermission from question.models import Question from question.serializers import QuestionSerializer -from .models import ExamTest, AnswerDetail, Banner -from .models_paper import TestRule, WorkScope, Paper, PaperQuestions -from .serializers import (TestRuleSerializer, MoniTestSerializer, AnswerDetailSerializer, - ExamTestListSerializer, AnswerDetailCreateSerializer, WorkScopeSerializer, - BannerSerializer, PaperSerializer, PaperQuestionsCreateSerializer, PaperDetailSerializer) from server import settings -from crm.authentication import ConsumerTokenAuthentication from utils.custom import CommonPagination +from .models import AnswerDetail, Banner, ExamTest +from .models_paper import Paper, PaperQuestions, TestRule, WorkScope +from .serializers import ( + AnswerDetailCreateSerializer, AnswerDetailSerializer, BannerSerializer, + ExamTestListSerializer, MoniTestSerializer, PaperDetailSerializer, + PaperQuestionsCreateSerializer, PaperSerializer, TestRuleSerializer, + WorkScopeSerializer) + # Create your views here. @@ -43,9 +44,9 @@ class WorkScopeViewSet(ModelViewSet): """ 工作类别:增删改查 """ - perms_map = ( - {'*': 'admin'}, {'*': 'WorkScope_all'}, {'get': 'WorkScope_list'}, {'post': 'WorkScope_create'}, - {'put': 'WorkScope_update'}, {'delete': 'WorkScope_delete'}) + perms_map = [ + {'get': 'workscope_list'}, {'post': 'workscope_create'}, + {'put': 'workscope_update'}, {'delete': 'workscope_delete'}] pagination_class = None queryset = WorkScope.objects.filter(is_delete=0).all().order_by("id") serializer_class = WorkScopeSerializer @@ -55,18 +56,7 @@ class WorkScopeViewSet(ModelViewSet): filterset_fields = ['subject'] search_fields = ('^name',) - def get_authenticators(self): - if self.request.method == 'GET': - self.authentication_classes = [] - return [auth() for auth in self.authentication_classes] - - def get_permissions(self): - if self.request.method == 'GET': - self.permission_classes = [] - return [permission() for permission in self.permission_classes] - - @action(methods=['get'], detail=True, permission_classes=[IsAuthenticated], - url_path='monitest', url_name='gen_monitest') + @action(methods=['get'], detail=True,url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}]) def monitest(self, request, pk=None): ''' 生成自助模拟考试 @@ -113,8 +103,8 @@ class BannerViewSet(ModelViewSet): 轮播图:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'Banner_all'}, {'get': 'Banner_list'}, {'post': 'Banner_create'}, - {'put': 'Banner_update'}, {'delete': 'Banner_delete'}) + {'get': 'banner_list'}, {'post': 'banner_create'}, + {'put': 'banner_update'}, {'delete': 'banner_delete'}) pagination_class = None queryset = Banner.objects.filter(is_delete=0).all().order_by("sort") serializer_class = BannerSerializer @@ -136,8 +126,8 @@ class TestRuleViewSet(ModelViewSet): 模考规则:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'TestRule_all'}, {'get': 'TestRule_list'}, {'post': 'TestRule_create'}, - {'put': 'TestRule_update'}, {'delete': 'TestRule_delete'}) + {'get': 'testrule_list'}, {'post': 'testrule_create'}, + {'put': 'testrule_update'}, {'delete': 'testrule_delete'}) pagination_class = None queryset = TestRule.objects.filter(is_delete=0).all().order_by("id") serializer_class = TestRuleSerializer @@ -159,8 +149,7 @@ class ExamTestViewSet(ModelViewSet): """ 考试记录列表和详情 """ - perms_map = ( - {'*': 'admin'}, {'*': 'ExamTest_all'}, {'get': 'ExamTest_list'}) + perms_map = [{'get': 'examtest_list'},{'post': 'examtest_create'}] pagination_class = CommonPagination queryset = ExamTest.objects.filter(is_delete=0).all() serializer_class = ExamTestListSerializer @@ -170,18 +159,7 @@ class ExamTestViewSet(ModelViewSet): filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ['type','is_pass'] - def get_authenticators(self): - if self.request.method == 'POST': - self.authentication_classes = [ConsumerTokenAuthentication] - return [auth() for auth in self.authentication_classes] - - def get_permissions(self): - if self.request.method == 'POST': - self.permission_classes = [] - return [permission() for permission in self.permission_classes] - - @action(methods=['get'], detail=False, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[], - url_path='self', url_name='selftest') + @action(methods=['get'], detail=False,url_path='self', url_name='selftest', perms_map = [{'get':'examtest_selftest'}]) def selftest(self, request, pk=None): ''' 个人考试记录 @@ -192,8 +170,7 @@ class ExamTestViewSet(ModelViewSet): serializer = ExamTestListSerializer(instance=p,many=True) return pg.get_paginated_response(serializer.data) - @action(methods=['get'], detail=False, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[], - url_path='fx', url_name='selffx') + @action(methods=['get'], detail=False,url_path='fx', url_name='selffx', perms_map = [{'get':'examtest_selffx'}]) def selffx(self, request, pk=None): ''' 个人考试分析 @@ -237,9 +214,9 @@ class PaperViewSet(ModelViewSet): """ 押题卷增删改查 """ - perms_map = ( - {'*': 'admin'}, {'*': 'Paper_all'}, {'get': 'Paper_list'}, {'post': 'Paper_create'}, - {'put': 'Paper_update'}, {'delete': 'Paper_delete'}) + perms_map = [ + {'get': 'paper_list'}, {'post': 'paper_create'}, + {'put': 'paper_update'}, {'delete': 'paper_delete'}] queryset = Paper.objects.filter(is_delete=0).all().order_by("id") pagination_class = CommonPagination serializer_class = PaperSerializer @@ -248,16 +225,6 @@ class PaperViewSet(ModelViewSet): filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ['workscope'] search_fields = ('^name',) - - def get_authenticators(self): - if self.request.method == 'GET': - self.authentication_classes = [] - return [auth() for auth in self.authentication_classes] - - def get_permissions(self): - if self.request.method == 'GET': - self.permission_classes = [] - return [permission() for permission in self.permission_classes] def get_serializer_class(self): if self.action=='list': @@ -313,8 +280,7 @@ class PaperViewSet(ModelViewSet): else: return Response({'error':'不存在题库'}) - @action(methods=['get'], detail=True, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[], - url_path='monitest', url_name='gen_monitest') + @action(methods=['get'], detail=True, url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}]) def monitest(self, request, pk=None): ''' 生成押卷模拟考试 @@ -327,5 +293,3 @@ class PaperViewSet(ModelViewSet): ret['type'] = '押卷模考' ret['paper'] = paper.id return Response(ret) - - \ No newline at end of file diff --git a/test_server/question/views.py b/test_server/question/views.py index 4e77ecb..9727fe3 100644 --- a/test_server/question/views.py +++ b/test_server/question/views.py @@ -12,11 +12,9 @@ from rest_framework_jwt.authentication import JSONWebTokenAuthentication import json from utils.custom import CommonPagination -from rbac.permission import RbacPermission from .models import Questioncat, Question from .serializers import QuestioncatSerializer, QuestionSerializer, SubjectSerializer from server import settings -from crm.authentication import ConsumerTokenAuthentication from crm.models import PaySubject from examtest.models import WorkScope @@ -26,8 +24,8 @@ class SubjectViewSet(ModelViewSet): 学科分类:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'Subject_all'}, {'get': 'Subject_list'}, {'post': 'Subject_create'}, - {'put': 'Subject_update'}, {'delete': 'Subject_delete'}) + {'get': 'subject_list'}, {'post': 'subject_create'}, + {'put': 'subject_update'}, {'delete': 'subject_delete'}) queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id") serializer_class = SubjectSerializer pagination_class = None @@ -36,36 +34,12 @@ class SubjectViewSet(ModelViewSet): search_fields = ('^name',) - def destroy(self, request, *args, **kwargs): #逻辑删除 - instance = self.get_object() - instance.is_delete = True - instance.save() - return Response(status=status.HTTP_204_NO_CONTENT) - - def get_authenticators(self): - """ - GET请求不做登陆验证 - """ - if self.request.method == 'GET': - self.authentication_classes = [] - return [auth() for auth in self.authentication_classes] - - def get_permissions(self): - """ - GET请求不做权限验证 - """ - if self.request.method == 'GET': - self.permission_classes = [] - return [permission() for permission in self.permission_classes] - - - class QuestioncatViewSet(ModelViewSet): """ 题库分类:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'questioncat_all'}, {'get': 'questioncat_list'}, {'post': 'questioncat_create'}, + {'get': 'questioncat_list'}, {'post': 'questioncat_create'}, {'put': 'questioncat_update'}, {'delete': 'questioncat_delete'}) queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all() serializer_class = QuestioncatSerializer @@ -75,15 +49,9 @@ class QuestioncatViewSet(ModelViewSet): filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ['pid'] search_fields = ['^name'] - - def destroy(self, request, *args, **kwargs): #逻辑删除 - instance = self.get_object() - instance.is_delete = True - instance.save() - return Response(status=status.HTTP_204_NO_CONTENT) - @action(methods=['get'], detail=False, permission_classes=[IsAuthenticated], + @action(methods=['get'], detail=False, url_path='all', url_name='all_questioncat') def all(self, request): """ @@ -95,7 +63,7 @@ class QuestioncatViewSet(ModelViewSet): serializer = QuestioncatSerializer(instance=queryset,many=True) return Response(serializer.data) - @action(methods=['get'], detail=False, authentication_classes=[], permission_classes=[], + @action(methods=['get'], detail=False, url_path='subject', url_name='questioncat_subject', pagination_class = None) def subject(self, request): """ @@ -105,7 +73,7 @@ class QuestioncatViewSet(ModelViewSet): serializer = QuestioncatSerializer(instance=queryset,many=True) return Response(serializer.data) - @action(methods=['get'], detail=False, authentication_classes=[], permission_classes=[], + @action(methods=['get'], detail=False, url_path='workscope', url_name='questioncat_workscope', pagination_class = None) def workscope(self, request): """ @@ -121,7 +89,7 @@ class QuestionViewSet(ModelViewSet): 题目:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'question_all'}, {'get': 'question_list'}, {'post': 'question_create'}, + {'get': 'question_list'}, {'post': 'question_create'}, {'put': 'question_update'}, {'delete': 'question_delete'}) queryset = Question.objects.filter(is_delete=0).all() serializer_class = QuestionSerializer @@ -131,16 +99,8 @@ class QuestionViewSet(ModelViewSet): filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ['questioncat','level', 'type'] search_fields = ['^name'] - - def destroy(self, request, *args, **kwargs): #逻辑删除 - instance = self.get_object() - # self.perform_destroy(instance) - instance.is_delete = True - instance.save() - return Response(status=status.HTTP_204_NO_CONTENT) - - @action(methods=['post'], detail=False, permission_classes=[], + @action(methods=['post'], detail=False, url_path='count', url_name='question_count') def count(self, request): ret = {'danxuan':0,'duoxuan':0,'panduan':0} @@ -154,7 +114,7 @@ class QuestionViewSet(ModelViewSet): @action(methods=['post'], detail=False, - url_path='import', url_name='import_question') + url_path='import', url_name='import_question',perms_map=[{'post':'question_import'}]) def import_question(self, request): """ 导入题目 @@ -265,7 +225,7 @@ class QuestionViewSet(ModelViewSet): return Response(status=status.HTTP_200_OK) class ExerciseView(APIView): - authentication_classes = [ConsumerTokenAuthentication] + authentication_classes = [] permission_classes = [] def post(self, request): questioncat = request.data['questioncat'] diff --git a/test_server/rbac/migrations/0002_auto_20200402_1137.py b/test_server/rbac/migrations/0002_auto_20200402_1137.py new file mode 100644 index 0000000..80e2eba --- /dev/null +++ b/test_server/rbac/migrations/0002_auto_20200402_1137.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2020-04-02 03:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='userprofile', + name='mobile', + field=models.CharField(blank=True, max_length=11, null=True, unique=True, verbose_name='手机号码'), + ), + migrations.AlterField( + model_name='userprofile', + name='name', + field=models.CharField(max_length=20, verbose_name='姓名'), + ), + ] diff --git a/test_server/rbac/migrations/0003_auto_20200402_1157.py b/test_server/rbac/migrations/0003_auto_20200402_1157.py new file mode 100644 index 0000000..f6ba92a --- /dev/null +++ b/test_server/rbac/migrations/0003_auto_20200402_1157.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2020-04-02 03:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rbac', '0002_auto_20200402_1137'), + ] + + operations = [ + migrations.AlterField( + model_name='userprofile', + name='name', + field=models.CharField(blank=True, max_length=20, null=True, verbose_name='姓名'), + ), + ] diff --git a/test_server/rbac/models.py b/test_server/rbac/models.py index 91217a3..e7bdc50 100644 --- a/test_server/rbac/models.py +++ b/test_server/rbac/models.py @@ -138,8 +138,8 @@ class UserProfile(AbstractUser): """ 用户 """ - name = models.CharField(max_length=20, default="", verbose_name="姓名") - mobile = models.CharField(max_length=11, default="", verbose_name="手机号码", null=True, blank=True, unique=True) + name = models.CharField(max_length=20, verbose_name="姓名", null=True, blank=True) + mobile = models.CharField(max_length=11, verbose_name="手机号码", null=True, blank=True, unique=True) email = models.EmailField(max_length=50, verbose_name="邮箱", null=True, blank=True, unique=True) avatar = models.CharField(default="/media/default/avatar.png",max_length=1000, null=True, blank=True) department = models.ForeignKey("Organization", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="部门") diff --git a/test_server/rbac/views/menu.py b/test_server/rbac/views/menu.py index 4135579..f48e3dc 100644 --- a/test_server/rbac/views/menu.py +++ b/test_server/rbac/views/menu.py @@ -13,7 +13,7 @@ class MenuViewSet(ModelViewSet): 菜单管理:增删改查 """ - perms_map = ({'*': 'admin'}, {'*': 'menu_all'}, {'get': 'menu_list'}, {'post': 'menu_create'}, {'put': 'menu_update'}, + perms_map = ({'get': 'menu_list'}, {'post': 'menu_create'}, {'put': 'menu_update'}, {'delete': 'menu_delete'}) queryset = Menu.objects.all() serializer_class = MenuSerializer diff --git a/test_server/rbac/views/organization.py b/test_server/rbac/views/organization.py index b21377b..6a04c4b 100644 --- a/test_server/rbac/views/organization.py +++ b/test_server/rbac/views/organization.py @@ -16,7 +16,7 @@ class OrganizationViewSet(ModelViewSet): 组织机构:增删改查 """ perms_map = ( - {'*': 'admin'}, {'*': 'organization_all'}, {'get': 'organization_list'}, {'post': 'organization_create'}, + {'get': 'organization_list'}, {'post': 'organization_create'}, {'put': 'organization_update'}, {'delete': 'organization_delete'}) queryset = Organization.objects.filter(is_delete=0).all() serializer_class = OrganizationSerializer diff --git a/test_server/rbac/views/role.py b/test_server/rbac/views/role.py index 9d10f85..a7895b1 100644 --- a/test_server/rbac/views/role.py +++ b/test_server/rbac/views/role.py @@ -12,7 +12,7 @@ class RoleViewSet(ModelViewSet): """ 角色管理:增删改查 """ - perms_map = ({'*': 'admin'}, {'*': 'role_all'}, {'get': 'role_list'}, {'post': 'role_create'}, {'put': 'role_update'}, + perms_map = ({'get': 'role_list'}, {'post': 'role_create'}, {'put': 'role_update'}, {'delete': 'role_delete'}) queryset = Role.objects.filter(is_delete=0).all().order_by('-id') serializer_class = RoleListSerializer diff --git a/test_server/rbac/views/user.py b/test_server/rbac/views/user.py index e17dad4..afc334b 100644 --- a/test_server/rbac/views/user.py +++ b/test_server/rbac/views/user.py @@ -63,7 +63,7 @@ class UserViewSet(ModelViewSet): """ 用户管理:增删改查 """ - perms_map = ({'*': 'admin'}, {'*': 'user_all'}, {'get': 'user_list'}, {'post': 'user_create'}, {'put': 'user_update'}, + perms_map = ({'get': 'user_list'}, {'post': 'user_create'}, {'put': 'user_update'}, {'delete': 'user_delete'}) queryset = UserProfile.objects.filter(is_delete=0).all().order_by('-id') serializer_class = UserListSerializer @@ -107,7 +107,7 @@ class UserViewSet(ModelViewSet): if password: request.data['password'] = make_password(password) else: - request.data['password'] = make_password('Aq123456') + request.data['password'] = make_password('0000') serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) diff --git a/test_server/server/settings.py b/test_server/server/settings.py index e8c9430..c71794c 100644 --- a/test_server/server/settings.py +++ b/test_server/server/settings.py @@ -140,12 +140,10 @@ STATIC_ROOT = os.path.join(BASE_DIR,'static') REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ - 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', - 'rest_framework.authentication.BasicAuthentication', + 'crm.authentication.MyTokenAuthentication' ], 'DEFAULT_PERMISSION_CLASSES':[ - 'rest_framework.permissions.IsAuthenticated', - 'rbac.permission.RbacPermission' + 'crm.permission.MyPermission' ], 'DEFAULT_RENDERER_CLASSES': ('utils.response.FitJSONRenderer',), 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],