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.serializers import jwt_encode_handler import json import random from rest_framework_jwt.settings import api_settings from calendar import timegm from datetime import datetime import warnings from utils.custom import CommonPagination from rbac.permission import RbacPermission from crm.authentication import ConsumerTokenAuthentication from .models import Company, Consumer, PaySubject, SendCode from .serializers import CompanySerializer, ConsumerSerializer from question.serializers import QuestionSerializer from server import settings from question.models import Questioncat from crm.zhenzismsclient import ZhenziSmsClient 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, '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 = ( {'*': 'admin'}, {'*': 'company_all'}, {'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'] 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'}) queryset = Consumer.objects.filter(is_delete=0).all() serializer_class = ConsumerSerializer pagination_class = CommonPagination ordering_fields = ('id',) ordering = ['company'] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ('company',) search_fields = ('^name',) @action(methods=['get'], detail=False, permission_classes=[], authentication_classes=[ConsumerTokenAuthentication], url_path='subjectpaid', url_name='subject_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, permission_classes=[], authentication_classes=[], url_path='sendcode', url_name='code_send') 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, permission_classes=[], authentication_classes=[ConsumerTokenAuthentication], url_path='collects', url_name='create_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, permission_classes=[IsAuthenticated], 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":"付费学科列错误!"}) companydict = {} consumerdict = {} companys = Company.objects.filter(is_delete=0) for i in companys: companydict[i.name] = i.id i = 3 while sheet['B'+str(i)].value: name = sheet['A'+str(i)].value if name: name = name.replace(' ', '') username = sheet['B'+str(i)].value if username: username = str(username).replace(' ', '') companyname = sheet['C'+str(i)].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(i)].value if Consumer.objects.filter(username = username).exists(): consumerdict[username]=i else: obj = Consumer() obj.name = name obj.username = username obj.company = companyobj 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) i = i + 1 if consumerdict: return {"code":206,"data":consumerdict,"msg":"导入部分成功"} else: 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 = [ConsumerTokenAuthentication] 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':'认证错误!'})