import logging from django.utils.translation import gettext as _ from django.db import models from rest_framework.response import Response from rest_framework.exceptions import ParseError from collections import defaultdict from pingcap_sso.api.base import AdminEndpoint from pingcap_sso.api.permissions import AskTUGModeratorOrStaffWithMethodPermission from pingcap_sso.models import ( User, UserProfileCollections, UserTiDBUsage ) from pingcap_sso.discourse.models import ( DiscourseSingleSignOnRecord, DiscourseTopic, DiscoursePost ) from pingcap_sso.utils import time as ptime logger = logging.getLogger(__name__) class AnalyticsEndpoint(AdminEndpoint): permission_classes = (AskTUGModeratorOrStaffWithMethodPermission, ) perms_map = { 'GET': ['pingcap_sso.view_company_analytics'] } def get(self, request): """audit_log: 使用了公司洞察""" company_name = request.GET.get('company_name') if not company_name: raise ParseError profile_qs = UserProfileCollections.objects.filter( models.Q(company__icontains=company_name) | models.Q(email__icontains=company_name) ) user_qs = User.objects.select_related('point_stat').filter( models.Q(id__in=profile_qs.values('user_id')) ) profile_users = UserProfileCollections.objects.filter( is_primary=True, user_id__in=user_qs.values('id') ).values('user_id', 'name', 'company', 'phone', 'email') user_profile_map = {p_u['user_id']: p_u for p_u in profile_users} user_count = user_qs.count() top10_exp_users = user_qs.annotate( exps=models.F('point_stat__experience') ).values( 'id', 'username', 'exps', 'pass_pcta', 'pass_pctp' ).order_by( '-exps' )[:10] for u in top10_exp_users: u['company_name'] = user_profile_map.get(u['id']).get('company') u['email'] = user_profile_map.get(u['id']).get('email') tidb_usage = UserTiDBUsage.objects.filter( user_id__in=user_qs.values('id'), deleted_at__isnull=True ).values('version').annotate( num=models.Count('id') ).order_by('-version') tidb_usage_detail_qs = UserTiDBUsage.objects.filter( user_id__in=user_qs.values('id'), deleted_at__isnull=True ).values('id', 'version', 'created_at', 'asktug_topic_id').order_by('-created_at') tidb_usage_detail_map = defaultdict(list) for tud in tidb_usage_detail_qs: tud['created_at'] = ptime.local_time_format(tud['created_at']) tidb_usage_detail_map[tud['version']].append(tud) for u in tidb_usage: u['detail'] = tidb_usage_detail_map.get(u['version'], []) pass_pcta_count = user_qs.filter(pass_pcta=True).count() pass_pctp_count = user_qs.filter(pass_pctp=True).count() openids = list(user_qs.values_list('openid', flat=True)) discourse_user_ids = DiscourseSingleSignOnRecord.objects.filter(external_id__in=openids).values('user_id') topics_count = DiscourseTopic.objects.filter( user_id__in=discourse_user_ids, deleted_at__isnull=True, archetype='regular', visible=True ).count() posts_count = DiscoursePost.objects.filter( topic__deleted_at__isnull=True, topic__visible=True, topic__archetype='regular', deleted_at__isnull=True, hidden=False, post_type=1, user_id__in=discourse_user_ids, ).count() return Response({ 'detail': _('success'), 'data': { 'user_count': user_count, 'top10_exp_users': top10_exp_users, 'tidb_usage': tidb_usage, 'topics_count': topics_count, 'posts_count': posts_count, 'pass_pcta_count': pass_pcta_count, 'pass_pctp_count': pass_pctp_count, } })