import json import random import warnings from calendar import timegm from datetime import datetime 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 .models import Company, Consumer, PaySubject, SendCode from .serializers import CompanySerializer, ConsumerSerializer appid = 'wxf1e9471c93f05ad6' secret = '4bf7f9bd6c52634586bbe792a1f0a834' sms_appid = '104951' sms_appsecret = '3d0ccaf9-f680-47e3-ad93-9e83093c5a04' 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: 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 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 = None #不分页 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.filter(is_delete=0).all() serializer_class = ConsumerSerializer pagination_class = CommonPagination ordering_fields = ('id','company','create_time') ordering = ['company','-create_time'] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ('company',) search_fields = ('^name',) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) if serializer.is_valid(): instance = serializer.save() else: return Response(serializer.errors) 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=['get'], detail=False, url_path='subjectpaid', url_name='subject_paid',perms_map=[{'get':'my_paid'}]) 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=[{'get':'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=['post'], detail=False, url_path='import', url_name='import_consumer') def import_consumer(self, request): """ 导入用户 """ 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 = {} consumerdict = {} 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(' ', '') companyname = sheet['C'+str(m)].value if companyname: companyname = companyname.replace(' ', '') if companyname not in companydict: return Response({"error":"不存在单位("+companyname+")!请先新建"}) else: companyobj = Company.objects.get(id=companydict[companyname]) subjects = sheet['d'+str(m)].value workscope = sheet['e'+str(m)].value if Consumer.objects.filter(username = username).exists(): consumerdict[username]=m else: obj = Consumer() obj.name = name obj.username = username obj.company = companyobj if workscope: workscope = workscope.replace(' ', '') try: workscopeobj = WorkScope.objects.get(name=workscope) obj.workscope = workscopeobj except: pass obj.save() if subjects: subjects_list = subjects.replace(' ','').split(',') for i in subjects_list: queryset = Questioncat.objects.filter(name=i,is_subject=True,is_delete=False) if queryset.exists(): PaySubject.objects.create(subject=queryset.first(), consumer=obj) m = m + 1 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 = ConsumerSerializer(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): ''' 验证码登陆和注册 ''' authentication_classes = [] permission_classes = [] 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() openid = request.user.openid request.user.delete(soft=False) # 彻底删除 consumer.openid = openid if avatar and nickname: consumer.avatar = avatar consumer.nickname = nickname 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 consumer.save() return Response(status=status.HTTP_200_OK) else: return Response({'error':'验证码错误!'}) else: return Response({'error':'认证错误!'}) else: return Response({'error':'信息不全!'})