test complete 0402

This commit is contained in:
caoqianming 2020-04-02 18:25:06 +08:00
parent ffa8f775c3
commit 57b34c7197
19 changed files with 364 additions and 229 deletions

View File

@ -216,23 +216,11 @@ export const asyncRoutes = [
meta: { title: '轮播图', icon: '', perms: ['banner_manage'] } meta: { title: '轮播图', icon: '', perms: ['banner_manage'] }
}, },
{ {
path: 'user', path: 'admin',
name: 'User', name: 'Admin',
component: () => import('@/views/system/user.vue'), component: () => import('@/views/system/admin.vue'),
meta: { title: '用户管理', icon: '', perms: ['user_manage'] } 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 !!! // 404 page must be placed at the end !!!

View File

@ -0,0 +1,161 @@
<template>
<div class="app-container">
<el-button type="primary" @click="handleAddUser" icon="el-icon-plus">新增</el-button>
<el-table
:data="userList"
style="width: 100%;margin-top:10px;"
border
fit
v-loading="listLoading"
highlight-current-row
max-height="600"
>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column align="header-center" label="账户">
<template slot-scope="scope">{{ scope.row.username }}</template>
</el-table-column>
<el-table-column label="创建日期">
<template slot-scope="scope">
<span>{{ scope.row.date_joined }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<el-button
type="danger"
size="small"
@click="handleDelete(scope)"
icon="el-icon-delete"
:disabled="!checkPermission(['user_delete'])"
></el-button>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total>0"
:total="total"
:page.sync="listQuery.page"
:limit.sync="listQuery.limit"
@pagination="getList"
/>
<el-dialog :visible.sync="dialogVisible" title="新增管理员">
<el-form
:model="user"
label-width="80px"
label-position="right"
:rules="rule1"
ref="userForm"
>
<el-form-item label="账户" prop="username">
<el-input v-model="user.username" placeholder="账户" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="user.password" placeholder="密码" />
</el-form-item>
</el-form>
<div style="text-align:right;">
<el-button type="danger" @click="dialogVisible=false">取消</el-button>
<el-button type="primary" @click="confirmUser('userForm')">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getUserList, createUser, deleteUser} from "@/api/user";
import checkPermission from "@/utils/permission";
import Pagination from "@/components/Pagination"; // secondary package based on el-pagination
const defaultUser = {
id: "",
username: "",
password: "",
is_superuser:true
};
export default {
components: { Pagination },
data() {
return {
user: defaultUser,
userList: [],
total: 0,
listLoading: true,
listQuery: {
page: 1,
limit: 20
},
dialogVisible: false,
rule1: {
username: [{ required: true, message: "请输入账号", trigger: "change" }],
password: [
{ required: true, message: "请输入密码", trigger: "change" }
],
},
filterOrgText: "",
treeLoding: false,
orgData: []
};
},
computed: {},
created() {
this.getList();
},
methods: {
checkPermission,
getList() {
this.listLoading = true;
getUserList(this.listQuery).then(response => {
this.userList = response.data.results;
this.total = response.data.count;
this.listLoading = false;
});
},
handleAddUser() {
this.user = Object.assign({}, defaultUser);
this.dialogVisible = true;
this.$nextTick(() => {
this.$refs["userForm"].clearValidate();
});
},
handleDelete(scope) {
this.$confirm("确认删除?", "警告", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "error"
})
.then(async () => {
await deleteUser(scope.row.id);
this.userList.splice(scope.row.index, 1);
this.$message({
type: "success",
message: "成功删除!"
});
})
.catch(err => {
console.error(err);
});
},
async confirmUser(form) {
this.$refs[form].validate(valid => {
if (valid) {
createUser(this.user).then(res => {
// this.user = res.data
// this.userList.unshift(this.user)
this.getList();
this.dialogVisible = false;
this.$notify({
title: "成功",
message: "新增成功",
type: "success",
duration: 2000
});
});
} else {
return false;
}
});
}
}
};
</script>

View File

@ -48,9 +48,9 @@ App({
globalData: { globalData: {
userInfo: null, userInfo: null,
userinfo: null, // 服务器传回的消费者信息 userinfo: null, // 服务器传回的消费者信息
host: 'https://apitest.ctcshe.com', // host: 'https://apitest.ctcshe.com',
mediahost: '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', // mediahost: 'http://127.0.0.1:8000',
token : '', token : '',
subject:null, subject:null,

View File

@ -92,6 +92,7 @@ Page({
that.data.form.nickname = e.detail.userInfo.nickName that.data.form.nickname = e.detail.userInfo.nickName
that.data.form.avatar = e.detail.userInfo.avatarUrl that.data.form.avatar = e.detail.userInfo.avatarUrl
} }
if(that.isPhone(that.data.form.phone)){ if(that.isPhone(that.data.form.phone)){
that.denglu(that.data.form) that.denglu(that.data.form)
}else{ }else{
@ -107,7 +108,7 @@ Page({
}) })
}, },
denglu: function (data) { denglu: function (data) {
api.request('crm/consumer/register/', 'POST', data).then(res => { api.request('/crm/consumer/register/', 'POST', data).then(res => {
getApp().onLaunch() getApp().onLaunch()
wx.switchTab({ wx.switchTab({
url: '/pages/main/main', url: '/pages/main/main',

View File

@ -4,23 +4,27 @@ from rest_framework import exceptions
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from crm.models import Consumer from crm.models import Consumer
from rbac.models import UserProfile
class ConsumerTokenAuthentication(JSONWebTokenAuthentication):
class MyTokenAuthentication(JSONWebTokenAuthentication):
def authenticate_credentials(self, payload): def authenticate_credentials(self, payload):
""" """
返回登陆消费者 返回登陆人员(学员或管理员)
""" """
id = payload['user_id'] id = payload['user_id']
if not id: if not id:
msg = _('签名有误.') msg = _('签名有误.')
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)
if 'type' in payload and payload['type'] == 'consumer':
try: try:
consumer = Consumer.objects.get(id=id) user = Consumer.objects.get(id=id)
except Consumer.DoesNotExist: except Consumer.DoesNotExist:
msg = _('消费者不存在') msg = _('消费者不存在')
raise exceptions.AuthenticationFailed(msg) raise exceptions.AuthenticationFailed(msg)
else:
try:
return consumer user = UserProfile.objects.get(id=id)
except UserProfile.DoesNotExist:
msg = _('管理员不存在')
raise exceptions.AuthenticationFailed(msg)
return user

View File

@ -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 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): def has_permission(self, request, view):
return bool(request.user) """
权限校验逻辑
: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

View File

@ -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 json
import random import random
from rest_framework_jwt.settings import api_settings import warnings
from calendar import timegm from calendar import timegm
from datetime import datetime 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 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 .models import Company, Consumer, PaySubject, SendCode
from .serializers import CompanySerializer, ConsumerSerializer 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' appid = 'wxf1e9471c93f05ad6'
secret = '4bf7f9bd6c52634586bbe792a1f0a834' secret = '4bf7f9bd6c52634586bbe792a1f0a834'
@ -41,6 +37,7 @@ sms_url = 'https://sms_developer.zhenzikj.com'
def jwt_payload_handler(user): def jwt_payload_handler(user):
payload = { payload = {
'user_id': user.pk, 'user_id': user.pk,
'type':'consumer',
'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA 'exp': datetime.utcnow() + api_settings.JWT_EXPIRATION_DELTA
} }
if api_settings.JWT_ALLOW_REFRESH: if api_settings.JWT_ALLOW_REFRESH:
@ -60,9 +57,9 @@ class CompanyViewSet(ModelViewSet):
""" """
客户企业增删改查 客户企业增删改查
""" """
perms_map = ( perms_map = [
{'*': 'admin'}, {'*': 'company_all'}, {'get': 'company_list'}, {'post': 'company_create'}, {'get': 'company_list'}, {'post': 'company_create'},
{'put': 'company_update'}, {'delete': 'company_delete'}) {'put': 'company_update'}, {'delete': 'company_delete'}]
queryset = Company.objects.filter(is_delete=0).all() queryset = Company.objects.filter(is_delete=0).all()
serializer_class = CompanySerializer serializer_class = CompanySerializer
pagination_class = None #不分页 pagination_class = None #不分页
@ -70,35 +67,14 @@ class CompanyViewSet(ModelViewSet):
search_fields = ('^name',) search_fields = ('^name',)
ordering_fields = ('id',) ordering_fields = ('id',)
ordering = ['-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): class ConsumerViewSet(ModelViewSet):
""" """
学员增删改查 学员增删改查
""" """
perms_map = ( perms_map = [
{'*': 'admin'}, {'*': 'consumer_all'}, {'get': 'consumer_list'}, {'post': 'consumer_create'}, {'get': 'consumer_list'}, {'post': 'consumer_create'},
{'put': 'consumer_update'}, {'delete': 'consumer_delete'}) {'put': 'consumer_update'}, {'delete': 'consumer_delete'}]
queryset = Consumer.objects.filter(is_delete=0).all() queryset = Consumer.objects.filter(is_delete=0).all()
serializer_class = ConsumerSerializer serializer_class = ConsumerSerializer
pagination_class = CommonPagination 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)}) PaySubject.objects.get_or_create(consumer = instance, subject__id=i, defaults={'consumer':instance,'subject':Questioncat.objects.get(id=i)})
return Response(serializer.data) return Response(serializer.data)
@action(methods=['get'], detail=False, permission_classes=[IsConsumerAuthenticated], authentication_classes=[ConsumerTokenAuthentication], @action(methods=['get'], detail=False,
url_path='subjectpaid', url_name='subject_paid') url_path='subjectpaid', url_name='subject_paid',perms_map=[{'get':'my_paid'}])
def has_paid(self, request): def has_paid(self, request):
""" """
当前登陆消费者已付费的学科 当前登陆消费者已付费的学科
@ -142,8 +118,8 @@ class ConsumerViewSet(ModelViewSet):
data = queryset.values_list('subject__id',flat=True) data = queryset.values_list('subject__id',flat=True)
return Response(data) return Response(data)
@action(methods=['get'], detail=False, permission_classes=[], authentication_classes=[], @action(methods=['get'], detail=False,
url_path='sendcode', url_name='code_send') url_path='sendcode', url_name='code_send',authentication_classes=[],permission_classes=[])
def sendcode(self, request): def sendcode(self, request):
''' '''
发送验证码 发送验证码
@ -159,8 +135,8 @@ class ConsumerViewSet(ModelViewSet):
else: else:
return Response({'error':result['data']}) return Response({'error':result['data']})
@action(methods=['post','delete','get'], detail=False, permission_classes=[IsConsumerAuthenticated], authentication_classes=[ConsumerTokenAuthentication], @action(methods=['post','delete','get'], detail=False,
url_path='collects', url_name='create_collects') url_path='collects', url_name='create_collects', perms_map=[{'get':'my_collects'}])
def collects(self, request): def collects(self, request):
''' '''
个人收藏集 个人收藏集
@ -186,7 +162,7 @@ class ConsumerViewSet(ModelViewSet):
return Response({'error':'delete参数错误'}) return Response({'error':'delete参数错误'})
@action(methods=['post'], detail=False, permission_classes=[IsAuthenticated], @action(methods=['post'], detail=False,
url_path='import', url_name='import_consumer') url_path='import', url_name='import_consumer')
def import_consumer(self, request): def import_consumer(self, request):
""" """
@ -284,7 +260,7 @@ class ConsumerRegister(APIView):
''' '''
验证码登陆和注册 验证码登陆和注册
''' '''
authentication_classes = [ConsumerTokenAuthentication] authentication_classes = []
permission_classes = [] permission_classes = []
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
data = request.data data = request.data
@ -320,4 +296,4 @@ class ConsumerRegister(APIView):
else: else:
return Response({'error':'认证错误!'}) return Response({'error':'认证错误!'})
else: else:
return Response({'error':'信息不全!'}) return Response({'error':'信息不全!'})

View File

@ -8,7 +8,7 @@ from .models_paper import WorkScope, Paper
class ExamTest(CommonModel): class ExamTest(CommonModel):
''' '''
硬删除 考试记录表
''' '''
type_choices = ( type_choices = (
('自助模考', '自助模考'), ('自助模考', '自助模考'),
@ -28,7 +28,7 @@ class ExamTest(CommonModel):
detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail') detail = models.ManyToManyField(Question, related_name='答题记录', through='AnswerDetail')
is_pass = models.BooleanField(default=True, verbose_name='是否通过') is_pass = models.BooleanField(default=True, verbose_name='是否通过')
class Meta: class Meta:
verbose_name = '考试' verbose_name = '模拟考试'
verbose_name_plural = verbose_name verbose_name_plural = verbose_name

View File

@ -54,7 +54,7 @@ class ExamTestListSerializer(serializers.ModelSerializer):
start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S") start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
end_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) 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() consumer_name = serializers.SerializerMethodField()
class Meta: class Meta:
model = ExamTest model = ExamTest
@ -89,10 +89,11 @@ class PaperQuestionsDetailSerializer(serializers.ModelSerializer):
options = serializers.ReadOnlyField(source='question.options') options = serializers.ReadOnlyField(source='question.options')
right = serializers.ReadOnlyField(source='question.right') right = serializers.ReadOnlyField(source='question.right')
type = serializers.ReadOnlyField(source='question.type') type = serializers.ReadOnlyField(source='question.type')
questioncat_name = serializers.ReadOnlyField(source='question.questioncat.name')
level = serializers.ReadOnlyField(source='question.level') level = serializers.ReadOnlyField(source='question.level')
class Meta: class Meta:
model = PaperQuestions 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): class PaperDetailSerializer(serializers.ModelSerializer):
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)

View File

@ -1,30 +1,31 @@
from rest_framework.filters import SearchFilter, OrderingFilter from datetime import datetime
from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView from django.db.models import Avg
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 django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from openpyxl import Workbook, load_workbook 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 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.models import Question
from question.serializers import QuestionSerializer 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 server import settings
from crm.authentication import ConsumerTokenAuthentication
from utils.custom import CommonPagination 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. # Create your views here.
@ -43,9 +44,9 @@ class WorkScopeViewSet(ModelViewSet):
""" """
工作类别增删改查 工作类别增删改查
""" """
perms_map = ( perms_map = [
{'*': 'admin'}, {'*': 'WorkScope_all'}, {'get': 'WorkScope_list'}, {'post': 'WorkScope_create'}, {'get': 'workscope_list'}, {'post': 'workscope_create'},
{'put': 'WorkScope_update'}, {'delete': 'WorkScope_delete'}) {'put': 'workscope_update'}, {'delete': 'workscope_delete'}]
pagination_class = None pagination_class = None
queryset = WorkScope.objects.filter(is_delete=0).all().order_by("id") queryset = WorkScope.objects.filter(is_delete=0).all().order_by("id")
serializer_class = WorkScopeSerializer serializer_class = WorkScopeSerializer
@ -55,18 +56,7 @@ class WorkScopeViewSet(ModelViewSet):
filterset_fields = ['subject'] filterset_fields = ['subject']
search_fields = ('^name',) search_fields = ('^name',)
def get_authenticators(self): @action(methods=['get'], detail=True,url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}])
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')
def monitest(self, request, pk=None): def monitest(self, request, pk=None):
''' '''
生成自助模拟考试 生成自助模拟考试
@ -113,8 +103,8 @@ class BannerViewSet(ModelViewSet):
轮播图增删改查 轮播图增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'Banner_all'}, {'get': 'Banner_list'}, {'post': 'Banner_create'}, {'get': 'banner_list'}, {'post': 'banner_create'},
{'put': 'Banner_update'}, {'delete': 'Banner_delete'}) {'put': 'banner_update'}, {'delete': 'banner_delete'})
pagination_class = None pagination_class = None
queryset = Banner.objects.filter(is_delete=0).all().order_by("sort") queryset = Banner.objects.filter(is_delete=0).all().order_by("sort")
serializer_class = BannerSerializer serializer_class = BannerSerializer
@ -136,8 +126,8 @@ class TestRuleViewSet(ModelViewSet):
模考规则增删改查 模考规则增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'TestRule_all'}, {'get': 'TestRule_list'}, {'post': 'TestRule_create'}, {'get': 'testrule_list'}, {'post': 'testrule_create'},
{'put': 'TestRule_update'}, {'delete': 'TestRule_delete'}) {'put': 'testrule_update'}, {'delete': 'testrule_delete'})
pagination_class = None pagination_class = None
queryset = TestRule.objects.filter(is_delete=0).all().order_by("id") queryset = TestRule.objects.filter(is_delete=0).all().order_by("id")
serializer_class = TestRuleSerializer serializer_class = TestRuleSerializer
@ -159,8 +149,7 @@ class ExamTestViewSet(ModelViewSet):
""" """
考试记录列表和详情 考试记录列表和详情
""" """
perms_map = ( perms_map = [{'get': 'examtest_list'},{'post': 'examtest_create'}]
{'*': 'admin'}, {'*': 'ExamTest_all'}, {'get': 'ExamTest_list'})
pagination_class = CommonPagination pagination_class = CommonPagination
queryset = ExamTest.objects.filter(is_delete=0).all() queryset = ExamTest.objects.filter(is_delete=0).all()
serializer_class = ExamTestListSerializer serializer_class = ExamTestListSerializer
@ -170,18 +159,7 @@ class ExamTestViewSet(ModelViewSet):
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['type','is_pass'] filterset_fields = ['type','is_pass']
def get_authenticators(self): @action(methods=['get'], detail=False,url_path='self', url_name='selftest', perms_map = [{'get':'examtest_selftest'}])
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')
def selftest(self, request, pk=None): def selftest(self, request, pk=None):
''' '''
个人考试记录 个人考试记录
@ -192,8 +170,7 @@ class ExamTestViewSet(ModelViewSet):
serializer = ExamTestListSerializer(instance=p,many=True) serializer = ExamTestListSerializer(instance=p,many=True)
return pg.get_paginated_response(serializer.data) return pg.get_paginated_response(serializer.data)
@action(methods=['get'], detail=False, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[], @action(methods=['get'], detail=False,url_path='fx', url_name='selffx', perms_map = [{'get':'examtest_selffx'}])
url_path='fx', url_name='selffx')
def selffx(self, request, pk=None): def selffx(self, request, pk=None):
''' '''
个人考试分析 个人考试分析
@ -237,9 +214,9 @@ class PaperViewSet(ModelViewSet):
""" """
押题卷增删改查 押题卷增删改查
""" """
perms_map = ( perms_map = [
{'*': 'admin'}, {'*': 'Paper_all'}, {'get': 'Paper_list'}, {'post': 'Paper_create'}, {'get': 'paper_list'}, {'post': 'paper_create'},
{'put': 'Paper_update'}, {'delete': 'Paper_delete'}) {'put': 'paper_update'}, {'delete': 'paper_delete'}]
queryset = Paper.objects.filter(is_delete=0).all().order_by("id") queryset = Paper.objects.filter(is_delete=0).all().order_by("id")
pagination_class = CommonPagination pagination_class = CommonPagination
serializer_class = PaperSerializer serializer_class = PaperSerializer
@ -248,16 +225,6 @@ class PaperViewSet(ModelViewSet):
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['workscope'] filterset_fields = ['workscope']
search_fields = ('^name',) 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): def get_serializer_class(self):
if self.action=='list': if self.action=='list':
@ -313,8 +280,7 @@ class PaperViewSet(ModelViewSet):
else: else:
return Response({'error':'不存在题库'}) return Response({'error':'不存在题库'})
@action(methods=['get'], detail=True, authentication_classes=[ConsumerTokenAuthentication], permission_classes=[], @action(methods=['get'], detail=True, url_path='monitest', url_name='gen_monitest', perms_map=[{'get':'gen_monitest'}])
url_path='monitest', url_name='gen_monitest')
def monitest(self, request, pk=None): def monitest(self, request, pk=None):
''' '''
生成押卷模拟考试 生成押卷模拟考试
@ -327,5 +293,3 @@ class PaperViewSet(ModelViewSet):
ret['type'] = '押卷模考' ret['type'] = '押卷模考'
ret['paper'] = paper.id ret['paper'] = paper.id
return Response(ret) return Response(ret)

View File

@ -12,11 +12,9 @@ from rest_framework_jwt.authentication import JSONWebTokenAuthentication
import json import json
from utils.custom import CommonPagination from utils.custom import CommonPagination
from rbac.permission import RbacPermission
from .models import Questioncat, Question from .models import Questioncat, Question
from .serializers import QuestioncatSerializer, QuestionSerializer, SubjectSerializer from .serializers import QuestioncatSerializer, QuestionSerializer, SubjectSerializer
from server import settings from server import settings
from crm.authentication import ConsumerTokenAuthentication
from crm.models import PaySubject from crm.models import PaySubject
from examtest.models import WorkScope from examtest.models import WorkScope
@ -26,8 +24,8 @@ class SubjectViewSet(ModelViewSet):
学科分类增删改查 学科分类增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'Subject_all'}, {'get': 'Subject_list'}, {'post': 'Subject_create'}, {'get': 'subject_list'}, {'post': 'subject_create'},
{'put': 'Subject_update'}, {'delete': 'Subject_delete'}) {'put': 'subject_update'}, {'delete': 'subject_delete'})
queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id") queryset = Questioncat.objects.filter(is_subject=True,is_delete=0).all().order_by("id")
serializer_class = SubjectSerializer serializer_class = SubjectSerializer
pagination_class = None pagination_class = None
@ -36,36 +34,12 @@ class SubjectViewSet(ModelViewSet):
search_fields = ('^name',) 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): class QuestioncatViewSet(ModelViewSet):
""" """
题库分类增删改查 题库分类增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'questioncat_all'}, {'get': 'questioncat_list'}, {'post': 'questioncat_create'}, {'get': 'questioncat_list'}, {'post': 'questioncat_create'},
{'put': 'questioncat_update'}, {'delete': 'questioncat_delete'}) {'put': 'questioncat_update'}, {'delete': 'questioncat_delete'})
queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all() queryset = Questioncat.objects.filter(is_delete=0,is_subject=False).all()
serializer_class = QuestioncatSerializer serializer_class = QuestioncatSerializer
@ -75,15 +49,9 @@ class QuestioncatViewSet(ModelViewSet):
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['pid'] filterset_fields = ['pid']
search_fields = ['^name'] 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') url_path='all', url_name='all_questioncat')
def all(self, request): def all(self, request):
""" """
@ -95,7 +63,7 @@ class QuestioncatViewSet(ModelViewSet):
serializer = QuestioncatSerializer(instance=queryset,many=True) serializer = QuestioncatSerializer(instance=queryset,many=True)
return Response(serializer.data) 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) url_path='subject', url_name='questioncat_subject', pagination_class = None)
def subject(self, request): def subject(self, request):
""" """
@ -105,7 +73,7 @@ class QuestioncatViewSet(ModelViewSet):
serializer = QuestioncatSerializer(instance=queryset,many=True) serializer = QuestioncatSerializer(instance=queryset,many=True)
return Response(serializer.data) 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) url_path='workscope', url_name='questioncat_workscope', pagination_class = None)
def workscope(self, request): def workscope(self, request):
""" """
@ -121,7 +89,7 @@ class QuestionViewSet(ModelViewSet):
题目增删改查 题目增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'question_all'}, {'get': 'question_list'}, {'post': 'question_create'}, {'get': 'question_list'}, {'post': 'question_create'},
{'put': 'question_update'}, {'delete': 'question_delete'}) {'put': 'question_update'}, {'delete': 'question_delete'})
queryset = Question.objects.filter(is_delete=0).all() queryset = Question.objects.filter(is_delete=0).all()
serializer_class = QuestionSerializer serializer_class = QuestionSerializer
@ -131,16 +99,8 @@ class QuestionViewSet(ModelViewSet):
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['questioncat','level', 'type'] filterset_fields = ['questioncat','level', 'type']
search_fields = ['^name'] search_fields = ['^name']
def destroy(self, request, *args, **kwargs): #逻辑删除 @action(methods=['post'], detail=False,
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=[],
url_path='count', url_name='question_count') url_path='count', url_name='question_count')
def count(self, request): def count(self, request):
ret = {'danxuan':0,'duoxuan':0,'panduan':0} ret = {'danxuan':0,'duoxuan':0,'panduan':0}
@ -154,7 +114,7 @@ class QuestionViewSet(ModelViewSet):
@action(methods=['post'], detail=False, @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): def import_question(self, request):
""" """
导入题目 导入题目
@ -265,7 +225,7 @@ class QuestionViewSet(ModelViewSet):
return Response(status=status.HTTP_200_OK) return Response(status=status.HTTP_200_OK)
class ExerciseView(APIView): class ExerciseView(APIView):
authentication_classes = [ConsumerTokenAuthentication] authentication_classes = []
permission_classes = [] permission_classes = []
def post(self, request): def post(self, request):
questioncat = request.data['questioncat'] questioncat = request.data['questioncat']

View File

@ -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='姓名'),
),
]

View File

@ -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='姓名'),
),
]

View File

@ -138,8 +138,8 @@ class UserProfile(AbstractUser):
""" """
用户 用户
""" """
name = models.CharField(max_length=20, default="", verbose_name="姓名") name = models.CharField(max_length=20, verbose_name="姓名", null=True, blank=True)
mobile = models.CharField(max_length=11, default="", verbose_name="手机号码", null=True, blank=True, unique=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) 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) 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="部门") department = models.ForeignKey("Organization", null=True, blank=True, on_delete=models.SET_NULL, verbose_name="部门")

View File

@ -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'}) {'delete': 'menu_delete'})
queryset = Menu.objects.all() queryset = Menu.objects.all()
serializer_class = MenuSerializer serializer_class = MenuSerializer

View File

@ -16,7 +16,7 @@ class OrganizationViewSet(ModelViewSet):
组织机构增删改查 组织机构增删改查
""" """
perms_map = ( perms_map = (
{'*': 'admin'}, {'*': 'organization_all'}, {'get': 'organization_list'}, {'post': 'organization_create'}, {'get': 'organization_list'}, {'post': 'organization_create'},
{'put': 'organization_update'}, {'delete': 'organization_delete'}) {'put': 'organization_update'}, {'delete': 'organization_delete'})
queryset = Organization.objects.filter(is_delete=0).all() queryset = Organization.objects.filter(is_delete=0).all()
serializer_class = OrganizationSerializer serializer_class = OrganizationSerializer

View File

@ -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'}) {'delete': 'role_delete'})
queryset = Role.objects.filter(is_delete=0).all().order_by('-id') queryset = Role.objects.filter(is_delete=0).all().order_by('-id')
serializer_class = RoleListSerializer serializer_class = RoleListSerializer

View File

@ -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'}) {'delete': 'user_delete'})
queryset = UserProfile.objects.filter(is_delete=0).all().order_by('-id') queryset = UserProfile.objects.filter(is_delete=0).all().order_by('-id')
serializer_class = UserListSerializer serializer_class = UserListSerializer
@ -107,7 +107,7 @@ class UserViewSet(ModelViewSet):
if password: if password:
request.data['password'] = make_password(password) request.data['password'] = make_password(password)
else: else:
request.data['password'] = make_password('Aq123456') request.data['password'] = make_password('0000')
serializer = self.get_serializer(data=request.data) serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
self.perform_create(serializer) self.perform_create(serializer)

View File

@ -140,12 +140,10 @@ STATIC_ROOT = os.path.join(BASE_DIR,'static')
REST_FRAMEWORK = { REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [ 'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_jwt.authentication.JSONWebTokenAuthentication', 'crm.authentication.MyTokenAuthentication'
'rest_framework.authentication.BasicAuthentication',
], ],
'DEFAULT_PERMISSION_CLASSES':[ 'DEFAULT_PERMISSION_CLASSES':[
'rest_framework.permissions.IsAuthenticated', 'crm.permission.MyPermission'
'rbac.permission.RbacPermission'
], ],
'DEFAULT_RENDERER_CLASSES': ('utils.response.FitJSONRenderer',), 'DEFAULT_RENDERER_CLASSES': ('utils.response.FitJSONRenderer',),
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],