import logging import json from django.utils.translation import gettext as _ from django.utils.decorators import method_decorator from django.db import connections, models from rest_framework.permissions import IsAdminUser from rest_framework.response import Response from pingcap_sso.api.base import AdminEndpoint from pingcap_sso.api.permissions import MethodPermission from pingcap_sso.admin_audit_log.decorators import admin_audit_log_exempt from pingcap_sso.models import ( UserInfoMisc, IPLocation, ) logger = logging.getLogger(__name__) @method_decorator(admin_audit_log_exempt, name='dispatch') class RegionListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.search_user_by_ip_region'], } def get(self, request, *args, **kwargs): country = request.GET.get('country', '') region = request.GET.get('region', '') dimension = request.GET.get('dimension', 'country') if dimension not in ('country', 'region', 'city'): return Response({ 'error': _('Invalid dimension'), }, status=400) qs = IPLocation.objects.all() if dimension == 'country': data = qs.values_list('country', flat=True).exclude(country='-').distinct() elif dimension == 'region': data = qs.filter(country=country).exclude(region='-').values_list('region', flat=True).distinct() elif dimension == 'city': data = qs.filter(country=country, region=region).exclude(city='-').values_list('city', flat=True).distinct() return Response({ 'detail': _('success'), 'data': data, }) class UserListEndpoint(AdminEndpoint): permission_classes = (IsAdminUser, MethodPermission) perms_map = { 'GET': ['pingcap_sso.search_user_by_ip_region'], } def get(self, request, *args, **kwargs): """audit_log: 根据地区(IP)查看用户列表""" cur_page = int(request.GET.get('currentPage', 1)) per_page = int(request.GET.get('perPage', 10)) country = request.GET.get('country', '') region = request.GET.get('region', '') city = request.GET.get('city', '') qs = UserInfoMisc.objects.select_related('user', 'user__point_stat').all().order_by('-user__point_stat__experience') if country: qs = qs.extra( where=["JSON_CONTAINS(JSON_EXTRACT(all_ip_top3_region, '$[0].country'), %s)"], params=[json.dumps(country)] ) if region: qs = qs.extra( where=["JSON_CONTAINS(JSON_EXTRACT(all_ip_top3_region, '$[0].region'), %s)"], params=[json.dumps(region)] ) if city: qs = qs.extra( where=["JSON_CONTAINS(JSON_EXTRACT(all_ip_top3_region, '$[0].city'), %s)"], params=[json.dumps(city)] ) total_num = qs.count() qs = qs[(cur_page - 1) * per_page:cur_page * per_page] data = list() for user_info_misc in qs: data.append({ 'id': user_info_misc.user_id, 'username': user_info_misc.user.username, 'name': user_info_misc.name, 'email': user_info_misc.email, 'company': user_info_misc.company, 'exps': user_info_misc.user.point_stat.experience, 'asktug_topic_count': user_info_misc.asktug_topic_count, 'asktug_reply_count': user_info_misc.asktug_reply_count, 'recent_half_year_ip_top3_region': user_info_misc.recent_half_year_ip_top3_region, 'all_ip_top3_region': user_info_misc.all_ip_top3_region, }) return Response({ 'detail': _('success'), 'data': data, 'total_num': total_num, 'per_page': per_page, 'cur_page': cur_page, })