From 9c7734820a90dfd4b05fabf0832983a832f41849 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Thu, 17 Nov 2022 18:17:53 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=9F=E8=AE=A1sql=20=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/apps/vod/serializers.py | 7 ++- server/apps/vod/urls.py | 2 + server/apps/vod/views.py | 21 ++++---- server/apps/vod/views2.py | 93 ++++++++++++++++++++++++++++++++++ server/utils/sql.py | 32 ++++++++++++ 5 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 server/apps/vod/views2.py create mode 100644 server/utils/sql.py diff --git a/server/apps/vod/serializers.py b/server/apps/vod/serializers.py index 6cb4156..6c03717 100644 --- a/server/apps/vod/serializers.py +++ b/server/apps/vod/serializers.py @@ -79,4 +79,9 @@ class View2Serializer(serializers.Serializer): video_ = VideoSimpleSerializer(source='video', read_only=True) class Meta: model = View2 - fields = '__all__' \ No newline at end of file + fields = '__all__' + +class DatetimeSerializer(serializers.Serializer): + start_time = serializers.DateTimeField(label="开始时间") + end_time = serializers.DateTimeField(label="结束时间") + limit = serializers.IntegerField(min_value=10, label="展示数量") \ No newline at end of file diff --git a/server/apps/vod/urls.py b/server/apps/vod/urls.py index 39769e2..59eb67e 100644 --- a/server/apps/vod/urls.py +++ b/server/apps/vod/urls.py @@ -1,6 +1,7 @@ from django.db.models import base from django.urls import path, include from .views import ClassView, PlayCodeAPIView, SignatureAPIView, ViewItemViewSet, VideoViewSet, VRecordViewSet, MyViewRecordAPIView, View2ViewSet +from .views2 import AnalyseViewSet from rest_framework import routers router = routers.DefaultRouter() @@ -8,6 +9,7 @@ router.register('video', VideoViewSet, basename="video") router.register('viewrecord', VRecordViewSet, basename='viewrecord') router.register('viewitem', ViewItemViewSet, basename='viewitem') router.register('view2', View2ViewSet, basename='view2') +router.register('analyse', AnalyseViewSet, basename='analyse') urlpatterns = [ path('', include(router.urls)), path('video//myview/', MyViewRecordAPIView.as_view()), diff --git a/server/apps/vod/views.py b/server/apps/vod/views.py index c752a52..6ea812c 100644 --- a/server/apps/vod/views.py +++ b/server/apps/vod/views.py @@ -2,7 +2,7 @@ from datetime import timedelta from time import timezone from apps.system.models import Dict from rest_framework.mixins import ListModelMixin, UpdateModelMixin -from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoListDetailSerializer, VideoSerializer, VideoUpdateSerializer, ViewItemSerializer, ViewItemUpdateSerializer, View2Serializer +from apps.vod.serializers import VRecordSerializer, VRecordUpdateSerializer, VideoListDetailSerializer, VideoSerializer, VideoUpdateSerializer, ViewItemSerializer, ViewItemUpdateSerializer, View2Serializer, DatetimeSerializer from apps.vod.models import Video, ViewRecord, ViewItem, View1, View2 from django.shortcuts import render from .vodclient import getAllClass, getPlayCode, searchMedia, getSignature @@ -18,6 +18,7 @@ from django.utils import timezone from rest_framework.exceptions import ParseError from utils.queryset import get_child_queryset2 from django.db.models import Sum +from django.db import connection # Create your views here. class ClassView(APIView): @@ -107,15 +108,15 @@ class VideoViewSet(PageOrNot, CreateUpdateModelAMixin, ModelViewSet): cal_view1(vi) return Response({"vi": vi.id}) - @action(methods=['get'], detail=False, perms_map={'get':'*'}) - def correct_cate(self, request, *args, **kwargs): - for video in Video.objects.get_queryset(all=True).all(): - cate = video.category - video.category_big = cate - if cate.pid: - video.category_big = cate.pid - video.save() - return Response() + # @action(methods=['get'], detail=False, perms_map={'get':'*'}) + # def correct_cate(self, request, *args, **kwargs): + # for video in Video.objects.get_queryset(all=True).all(): + # cate = video.category + # video.category_big = cate + # if cate.pid: + # video.category_big = cate.pid + # video.save() + # return Response() def cal_view1(vi: ViewItem): """ diff --git a/server/apps/vod/views2.py b/server/apps/vod/views2.py new file mode 100644 index 0000000..208b268 --- /dev/null +++ b/server/apps/vod/views2.py @@ -0,0 +1,93 @@ +from rest_framework.viewsets import GenericViewSet +from apps.vod.serializers import DatetimeSerializer +from rest_framework.decorators import action +from rest_framework.response import Response +from utils.sql import query_all_dict + +class AnalyseViewSet(GenericViewSet): + perms_map = {'post': '*'} + serializer_class = DatetimeSerializer + + def is_valid(self, request): + data = request.data + sr = self.get_serializer(data=data) + sr.is_valid(raise_exception=True) + vdata = sr.validated_data + return vdata + + @action(methods=['post'], detail=False) + def group_by_video_category_big(self, request): + """ + 视频大类播放量统计 + + 视频大类播放量统计 + """ + vdata = self.is_valid(request) + sql_str = """select + d.name as "视频大类", + count(v.id) as "视频数量", + count(vi.id) as "观看总次数", + count(distinct vi.create_by_id) as "观看总人数" + from vod_video v + left join system_dict d on d.id = v.category_big_id + left join vod_viewitem vi on vi.video_id = v.id + and vi.create_time >= %s + and vi.create_time <= %s + group by d.id + order by "视频数量" desc, d.sort + limit %s + """ + return Response(query_all_dict(sql_str, [vdata['start_time'], vdata['end_time'], vdata['limit']])) + + @action(methods=['post'], detail=False) + def group_by_user_view(self, request): + """ + 个人观看量统计 + + 个人观看量统计 + """ + vdata = self.is_valid(request) + sql_str = """select + u.name as "姓名", + u.username as "账号", + count(v2.is_completed is true) as "观看完成视频总数", + count(distinct vi.video_id) as "观看视频总数", + count(vi.id) as "观看总次数" , + sum(vi.total_seconds/60) as "观看总时间" + from vod_viewitem vi + left join vod_video v on v.id = vi.video_id + left join system_user u on u.id = vi.create_by_id + left join vod_view2 v2 on v2.create_by_id = vi.create_by_id and v2.video_id = vi.video_id + where vi.create_time >= %s and vi.create_time <= %s + group by u.id + order by "观看完成视频总数" desc, "账号" + limit %s + """ + return Response(query_all_dict(sql_str, [vdata['start_time'], vdata['end_time'], vdata['limit']])) + + + @action(methods=['post'], detail=False) + def group_by_org_view(self, request): + """ + 单位观看量统计 + + 单位观看量统计 + """ + vdata = self.is_valid(request) + sql_str = """select + o.name as "单位名称", + count(v2.is_completed is true) as "观看完成视频总数", + count(distinct vi.video_id) as "观看视频总数", + count(vi.id) as "观看总次数" , + sum(vi.total_seconds/60) as "观看总时间" + from vod_viewitem vi + left join vod_video v on v.id = vi.video_id + left join system_user u on u.id = vi.create_by_id + left join system_organization o on o.id = u.dept_id + left join vod_view2 v2 on v2.create_by_id = vi.create_by_id and v2.video_id = vi.video_id + where vi.create_time >= %s and vi.create_time <= %s + group by o.id + order by "观看完成视频总数" desc, o.sort + limit %s + """ + return Response(query_all_dict(sql_str, [vdata['start_time'], vdata['end_time'], vdata['limit']])) \ No newline at end of file diff --git a/server/utils/sql.py b/server/utils/sql.py new file mode 100644 index 0000000..af94efd --- /dev/null +++ b/server/utils/sql.py @@ -0,0 +1,32 @@ +from django.db import connection + +def query_all_dict(sql, params=None): + ''' + 查询所有结果返回字典类型数据 + :param sql: + :param params: + :return: + ''' + with connection.cursor() as cursor: + if params: + cursor.execute(sql, params=params) + else: + cursor.execute(sql) + columns = [desc[0] for desc in cursor.description] + return [dict(zip(columns, row)) for row in cursor.fetchall()] + +def query_one_dict(sql, params=None): + """ + 查询一个结果返回字典类型数据 + :param sql: + :param params: + :return: + """ + with connection.cursor() as cursor: + if params: + cursor.execute(sql, params=params) + else: + cursor.execute(sql) + columns = [desc[0] for desc in cursor.description] + row = cursor.fetchone() + return dict(zip(columns, row)) \ No newline at end of file