import json import random import warnings from calendar import timegm from datetime import datetime import requests from django.db.models import Q 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 .filters import ConsumerFilter from .exports import export_consumer from .models import Company, Consumer, PaySubject, SendCode, ConsumerPerm, ConsumerRole from .serializers import CompanySerializer, ConsumerSerializer, ConsumerPermSerializer, ConsumerRoleSerializer, ConsumerDetailSerializer appid = 'wxf1e9471c93f05ad6' secret = '4bf7f9bd6c52634586bbe792a1f0a834' sms_appid = '100172' sms_appsecret = '00b8681c-0ce6-41c8-a867-904c1891c78a' sms_url = 'https://sms.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: payload['orig_iat'] = timegm( datetime.utcnow().utctimetuple() ) if api_settings.JWT_AUDIENCE is not None: payload['aud'] = api_settings.JWT_AUDIENCE if api_settings.JWT_ISSUER is not None: payload['iss'] = api_settings.JWT_ISSUER return payload class ConsumerRoleViewSet(ModelViewSet): """ 客户角色:增删改查 """ perms_map = [ {'get': 'consumerrole_view'}, {'post': 'consumerrole_create'}, {'put': 'consumerrole_update'}, {'delete': 'consumerrole_delete'}] queryset = ConsumerRole.objects.filter(is_delete=0) serializer_class = ConsumerRoleSerializer pagination_class = None filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter] search_fields = ['name','description'] ordering_fields = ['create_time'] ordering = ['-create_time'] class ConsumerPermViewSet(ModelViewSet): """ 客户权限:增删改查 """ perms_map = [ {'get': 'consumerperm_view'}, {'post': 'consumerperm_create'}, {'put': 'consumerperm_update'}, {'delete': 'consumerperm_delete'}] queryset = ConsumerPerm.objects.filter(is_delete=0) serializer_class = ConsumerPermSerializer pagination_class = None filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter] search_fields = ['name','code'] ordering_fields = ['create_time'] ordering = ['-create_time'] class CompanyViewSet(ModelViewSet): """ 客户企业:增删改查 """ 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 = CommonPagination filter_backends = [DjangoFilterBackend,SearchFilter, OrderingFilter] search_fields = ('name',) ordering_fields = ('id',) ordering = ['-id'] class ConsumerViewSet(ModelViewSet): """ 学员:增删改查 """ perms_map = [ {'get': 'consumer_list'}, {'post': 'consumer_create'}, {'put': 'consumer_update'}, {'delete': 'consumer_delete'}] queryset = Consumer.objects.all() serializer_class = ConsumerSerializer pagination_class = CommonPagination ordering_fields = ('id','company','create_time', 'username', 'workscope') ordering = ['-create_time'] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_class = ConsumerFilter search_fields = ['name','username','company__name'] def get_queryset(self): queryset = self.queryset queryset = self.get_serializer_class().setup_eager_loading(queryset) return queryset def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) instance = serializer.save() if request.data.get('subjects', None): for i in request.data.get('subjects'): PaySubject.objects.get_or_create(consumer = instance, subject__id=i, defaults={'consumer':instance,'subject':Questioncat.objects.get(id=i)}) return Response(serializer.data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance, data=request.data) if serializer.is_valid(): instance = serializer.save() else: return Response(serializer.errors) PaySubject.objects.filter(consumer = instance).delete() if request.data.get('subjects', None): for i in request.data.get('subjects'): 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=['post'], detail=False, url_name='consumer_deletes',perms_map=[{'*':'consumer_deletes'}]) def deletes(self, request): """ 批量删除用户 """ ids = request.data.get('ids', None) if ids: Consumer.objects.filter(id__in = ids).delete() return Response(status=status.HTTP_200_OK) @action(methods=['get'], detail=False, url_path='subjectpaid', url_name='subject_paid',perms_map=[{'*':'my_subject'}]) def has_paid(self, request): """ 当前登陆消费者已付费的学科 """ queryset = PaySubject.objects.filter(consumer = request.user) data = queryset.values_list('subject__id',flat=True) return Response(data) @action(methods=['get'], detail=False, url_path='sendcode', url_name='code_send',authentication_classes=[],permission_classes=[]) def sendcode(self, request): ''' 发送验证码 ''' client = ZhenziSmsClient(sms_url, sms_appid, sms_appsecret) code = random.randint(1000,9999) phone = request.query_params.get('phone') params = {'message':'您的验证码为:' + str(code) +',5分钟内有效', 'number': phone} result = json.loads(client.send(params)) if result['code'] == 0: SendCode.objects.create(phone=phone, code=code) return Response(status=status.HTTP_200_OK) else: return Response({'error':result['data']}) @action(methods=['post','delete','get'], detail=False, url_path='collects', url_name='create_collects', perms_map=[{'*':'my_collects'}]) def collects(self, request): ''' 个人收藏集 ''' if request.method == 'POST': questionId = request.data.get('question',None) if questionId: request.user.collects.remove(questionId) request.user.collects.add(questionId) return Response(status=status.HTTP_200_OK) else: return Response({'error':'post参数错误'}) elif request.method == 'GET': queryset = request.user.collects.all().order_by('-update_time') serializer = QuestionSerializer(instance=queryset,many=True) return Response(serializer.data) elif request.method == 'DELETE': questionId = request.data.get('question',None) if questionId: request.user.collects.remove(questionId) return Response(status=status.HTTP_200_OK) else: return Response({'error':'delete参数错误'}) @action(methods=['get', 'put'], detail=False, url_path='process', url_name='exercise_process', perms_map=[{'*':'*'}]) def process(self, request): ''' 练习进度 ''' if request.method == 'GET': process = {} if hasattr(request.user, 'process'): process = request.user.process return Response({'process':process}) elif request.method == 'PUT': if hasattr(request.user, 'process'): request.user.process = request.data['process'] request.user.save() return Response(status=status.HTTP_200_OK) @action(methods=['post'], detail=False, url_path='import', url_name='import_consumer') def import_consumer(self, request): """ 导入用户 """ role1 = ConsumerRole.objects.get(name='付费学员') xlsxpath = request.data['path'] fullpath = settings.BASE_DIR + xlsxpath wb = load_workbook(fullpath) sheet = wb.worksheets[0] # 验证文件内容 if sheet['a2'].value != '姓名': return Response({"error":"姓名列错误!"}) if sheet['b2'].value != '账户(手机号)': return Response({"error":"账户列错误!"}) if sheet['c2'].value != '单位': return Response({"error":"单位列错误!"}) if sheet['d2'].value != '工作类别': return Response({"error":"工作类别列错误!"}) if sheet['e2'].value != '角色': return Response({"error":"角色列错误!"}) companydict = {} companys = Company.objects.filter(is_delete=0) for i in companys: companydict[i.name] = i.id m = 3 while sheet['B'+str(m)].value: name = sheet['A'+str(m)].value if name: name = name.replace(' ', '') username = sheet['B'+str(m)].value if username: username = str(username).replace(' ', '').replace("\n", "") companyname = sheet['C'+str(m)].value if companyname: companyname = companyname.replace(' ', '') companyobj = Company.objects.get_or_create(name=companyname)[0] workscope = sheet['d'+str(m)].value role = sheet['e'+str(m)].value if Consumer.objects.filter(username = username).exists(): obj = Consumer.objects.filter(username = username).first() else: obj = Consumer() obj.username = username obj.name = name obj.company = companyobj obj.save() if workscope: workscope = workscope.replace(' ', '') try: workscopeobj = WorkScope.objects.get(name=workscope) obj.workscope = workscopeobj PaySubject.objects.get_or_create(subject=workscopeobj.subject, consumer = obj) except: return Response({"error":"工作类别不存在!"}) obj.role = role1 if role: role = role.replace(' ', '') try: roleobj = ConsumerRole.objects.get(name=role) obj.role = roleobj except: pass obj.save() m = m + 1 return Response(status=status.HTTP_200_OK) @action(methods=['get'], detail=False, url_path='export', url_name='export_consumer', perms_map=[{'*':'export_consumer'}]) def export(self, request): queryset = self.filter_queryset(self.queryset) queryset = ConsumerSerializer.setup_eager_loading(queryset) # 性能优化 serializer = ConsumerSerializer(instance=queryset, many=True) path = export_consumer(serializer.data) return Response({'path': path}) @action(methods=['get'], detail=True, url_name='consumer_unbind', perms_map=[{'*':'consumer_unbind'}]) def unbind(self, request, *args, **kwargs): obj = self.get_object() if obj.username and obj.openid: obj.openid = None obj.nickname = None obj.avatar = None obj.save() return Response(status=status.HTTP_200_OK) else: return Response({"error":"不支持解绑!"}) @action(methods=['get'], detail=False, url_path='correctrole', url_name='correct_role', perms_map=[{'*':'correct_role'}]) def correctrole(self, request): role0 = ConsumerRole.objects.get(name='游客') role1 = ConsumerRole.objects.get(name='付费学员') role2 = ConsumerRole.objects.get(name='注册用户') for i in Consumer.objects.filter(role__isnull = True): i.role = role0 if i.workscope and i.username: i.role = role1 elif i.username and i.openid: i.role = role2 i.save() print(i.id) return Response(status=status.HTTP_200_OK) class ConsumerMPLoginView(APIView): """ 小程序登陆颁发token """ authentication_classes=[] permission_classes=[] def post(self, request, *args, **kwargs): code = request.data['code'] info = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid='+appid+'&secret='+secret+'&js_code=' + code+'&grant_type=authorization_code').content.decode('utf-8') info = json.loads(info) openid = info['openid'] session_key = info['session_key'] consumer = Consumer.objects.get_or_create(openid = openid)[0] serializer = ConsumerDetailSerializer(instance=consumer) payload = jwt_payload_handler(consumer) token = jwt_encode_handler(payload) return Response({"token":token,"session_key":session_key, "openid":openid, "userinfo":serializer.data}) class ConsumerLogoutView(APIView): authentication_classes = () permission_classes = () def get(self, request, *args, **kwargs): return Response(status=status.HTTP_200_OK) class ConsumerRegister(APIView): ''' 验证码登陆和注册 ''' def post(self, request, *args, **kwargs): data = request.data phone = data.get('phone', None) code = data.get('code', None) avatar = data.get('avatar', None) nickname = data.get('nickname', None) if phone and code: obj = SendCode.objects.filter(phone=phone).last() if obj: if code == obj.code: # 验证通过 consumer_queryset = Consumer.objects.filter(username=phone) if consumer_queryset.exists(): # 是否存在 consumer = consumer_queryset.first() if consumer.openid: return Response({'error':'该号码已使用!'}) openid = request.user.openid request.user.delete() # 删除 consumer.openid = openid if avatar and nickname: consumer.avatar = avatar consumer.nickname = nickname if consumer.role and consumer.role.name == '游客': consumer.role = ConsumerRole.objects.get(name='注册用户') consumer.save() return Response(status=status.HTTP_200_OK) else: consumer = request.user consumer.username = phone if avatar and nickname: consumer.avatar = avatar consumer.nickname = nickname if consumer.role and consumer.role.name == '游客': consumer.role = ConsumerRole.objects.get(name='注册用户') consumer.save() return Response(status=status.HTTP_200_OK) else: return Response({'error':'验证码错误!'}) else: return Response({'error':'认证错误!'}) else: return Response({'error':'信息不全!'}) class change_remain_count(APIView): perms_map=[{'*':'change_remain_count'}] def get(self, request, *args, **kwargs): # count = request.query_params.get('count', None) # if count: for i in Consumer.objects.all(): i.remain_count = i.remain_count + 2 i.save() return Response(status=status.HTTP_200_OK)