From e3c33bca329df296f3d36559d9ed9109e15a1856 Mon Sep 17 00:00:00 2001 From: feng <1304903146@qq.com> Date: Thu, 14 Aug 2025 11:03:32 +0800 Subject: [PATCH] perf: User report --- apps/i18n/lina/es.json | 1 - apps/i18n/lina/ja.json | 1 - apps/i18n/lina/ko.json | 1 - apps/i18n/lina/pt_br.json | 1 - apps/i18n/lina/ru.json | 1 - apps/i18n/lina/zh.json | 2 +- apps/i18n/lina/zh_hant.json | 1 - apps/reports/api/assets/base.py | 16 ++++++++++------ apps/reports/api/users/user.py | 27 ++++++++++++++------------- 9 files changed, 25 insertions(+), 26 deletions(-) diff --git a/apps/i18n/lina/es.json b/apps/i18n/lina/es.json index d6ffe0a43..1121b65c8 100644 --- a/apps/i18n/lina/es.json +++ b/apps/i18n/lina/es.json @@ -170,7 +170,6 @@ "AssetLoginACLHelpText": "Al iniciar sesión en el activo, puede auditar según la IP del usuario y el intervalo de tiempo, para determinar si se puede acceder al activo", "AssetLoginTrends": "Tendencias de inicio de sesión de activos", "AssetName": "Nombre del activo", - "AssetOverview": "Resumen de usuarios", "AssetPermission": "Autorización de activos", "AssetPermissionCreate": "Crear reglas de autorización de activos", "AssetPermissionDetail": "Detalles de autorización de activos", diff --git a/apps/i18n/lina/ja.json b/apps/i18n/lina/ja.json index 22fe46f68..b6ac5f1ec 100644 --- a/apps/i18n/lina/ja.json +++ b/apps/i18n/lina/ja.json @@ -168,7 +168,6 @@ "AssetLoginACLHelpMsg": "ユーザのログインIPと時間帯をもとに、アセットへのログインの承認可否を判断します", "AssetLoginACLHelpText": "資産にログインする際、ユーザーのログインIPと時間帯を審査し、資産にログインできるかどうかを判断します", "AssetName": "資産名称", - "AssetOverview": "ユーザー概要", "AssetPermission": "アセット権限", "AssetPermissionCreate": "資産認証ルールの作成", "AssetPermissionDetail": "資産認証の詳細", diff --git a/apps/i18n/lina/ko.json b/apps/i18n/lina/ko.json index f6e469458..b5a796c6d 100644 --- a/apps/i18n/lina/ko.json +++ b/apps/i18n/lina/ko.json @@ -170,7 +170,6 @@ "AssetLoginACLHelpText": "자산에 로그인할 때, 사용자의 로그인 IP 및 시간대를 기반으로 검토하여 자산에 로그인할 수 있는지 판단", "AssetLoginTrends": "자산 로그인 추세", "AssetName": "자산 이름", - "AssetOverview": "사용자 개요", "AssetPermission": "자산 권한 부여", "AssetPermissionCreate": "자산 권한 규칙 생성", "AssetPermissionDetail": "자산 권한 세부정보", diff --git a/apps/i18n/lina/pt_br.json b/apps/i18n/lina/pt_br.json index 6bb21a246..be9a1f5b1 100644 --- a/apps/i18n/lina/pt_br.json +++ b/apps/i18n/lina/pt_br.json @@ -170,7 +170,6 @@ "AssetLoginACLHelpText": "Ao fazer login no ativo, você pode revisar de acordo com o IP de login do usuário e o intervalo de tempo para determinar se pode fazer login no ativo.", "AssetLoginTrends": "Tendências de Login de Ativos", "AssetName": "Nome do ativo", - "AssetOverview": "Visão geral do usuário", "AssetPermission": "Ativos de autorização", "AssetPermissionCreate": "Criar regra de autorização de ativos", "AssetPermissionDetail": " Detalhes da autorização de ativos", diff --git a/apps/i18n/lina/ru.json b/apps/i18n/lina/ru.json index d98e955d8..2c8a192df 100644 --- a/apps/i18n/lina/ru.json +++ b/apps/i18n/lina/ru.json @@ -171,7 +171,6 @@ "AssetLoginACLHelpText": "Подключение к активам можно контролировать, исходя из IP-адреса пользователя и временного интервала, чтобы определить возможность подключения к активу.", "AssetLoginTrends": "Тенденция входа в активы", "AssetName": "Название актива", - "AssetOverview": "Обзор пользователей", "AssetPermission": "Доступ к активам", "AssetPermissionCreate": "Создать правило доступа к активам", "AssetPermissionDetail": "Подробности доступа к активам", diff --git a/apps/i18n/lina/zh.json b/apps/i18n/lina/zh.json index e2642de3a..ddc6b6988 100644 --- a/apps/i18n/lina/zh.json +++ b/apps/i18n/lina/zh.json @@ -170,7 +170,7 @@ "AssetLoginACLHelpText": "登录资产时,可以根据用户的登录 IP 和时间段进行审核,判断是否可以登录资产", "AssetLoginTrends": "资产登录趋势", "AssetName": "资产名称", - "AssetOverview": "用户概览", + "AssetOverview": "资产概览", "AssetPermission": "资产授权", "AssetPermissionCreate": "创建资产授权规则", "AssetPermissionDetail": "资产授权详情", diff --git a/apps/i18n/lina/zh_hant.json b/apps/i18n/lina/zh_hant.json index 605079d59..693809014 100644 --- a/apps/i18n/lina/zh_hant.json +++ b/apps/i18n/lina/zh_hant.json @@ -172,7 +172,6 @@ "AssetLoginACLHelpText": "登入資產時,可以依照使用者的登入 IP 和時間段進行審核,判斷是否可以登入資產", "AssetLoginTrends": "資產登錄趨勢", "AssetName": "資產名稱", - "AssetOverview": "用戶概覽", "AssetPermission": "資產授權", "AssetPermissionCreate": "創建資產授權規則", "AssetPermissionDetail": "資產授權詳情", diff --git a/apps/reports/api/assets/base.py b/apps/reports/api/assets/base.py index f21307e8d..277e86a82 100644 --- a/apps/reports/api/assets/base.py +++ b/apps/reports/api/assets/base.py @@ -2,13 +2,18 @@ from django.db.models import Count, F def group_stats(queryset, alias, key, label_map=None): - grouped = ( - queryset - .exclude(**{f'{key}__isnull': True}) - .values(**{alias: F(key)}) - .annotate(total=Count('id', distinct=True)) + pk_name = queryset.model._meta.pk.name + + base = ( + queryset.order_by() + .exclude(**{f"{key}__isnull": True}) + .annotate(**{alias: F(key)}) + .values(pk_name, alias) + .distinct() ) + grouped = base.values(alias).annotate(total=Count(pk_name)) + data = [ { alias: val, @@ -17,5 +22,4 @@ def group_stats(queryset, alias, key, label_map=None): } for val, cnt in grouped.values_list(alias, 'total') ] - return data diff --git a/apps/reports/api/users/user.py b/apps/reports/api/users/user.py index 823febfcb..dbe0cf455 100644 --- a/apps/reports/api/users/user.py +++ b/apps/reports/api/users/user.py @@ -4,6 +4,7 @@ from collections import defaultdict from django.db.models import Count, Q from django.http.response import JsonResponse +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from rest_framework.views import APIView @@ -55,19 +56,19 @@ class UserReportApi(DateRangeMixin, APIView): return metrics def get_user_login_time_metrics(self): - time_buckets = { - '00:00-06:00': (0, 6), - '06:00-12:00': (6, 12), - '12:00-18:00': (12, 18), - '18:00-24:00': (18, 24), - } - filtered_queryset = self.filter_by_date_range(self.user_login_log_queryset, 'datetime').all() - metrics = {bucket: 0 for bucket in time_buckets.keys()} - for date in filtered_queryset: - hour = date.datetime.hour - for bucket, (start, end) in time_buckets.items(): - if start <= hour < end: - metrics[bucket] = metrics.get(bucket, 0) + 1 + buckets = ['00:00-06:00', '06:00-12:00', '12:00-18:00', '18:00-24:00'] + metrics = {k: 0 for k in buckets} + + qs = self.filter_by_date_range(self.user_login_log_queryset, 'datetime').only('datetime') + + for obj in qs: + dt = obj.datetime + if dt is None: + continue + dt_local = timezone.localtime(dt) + hour = dt_local.hour + metrics[buckets[hour // 6]] += 1 + return metrics @lazyproperty