|
| 1 | +# coding=utf-8 |
| 2 | +""" |
| 3 | + @project: MaxKB |
| 4 | + @Author:虎虎 |
| 5 | + @file: application_stats.py |
| 6 | + @date:2025/6/9 20:34 |
| 7 | + @desc: |
| 8 | +""" |
| 9 | +import datetime |
| 10 | +import os |
| 11 | +from typing import Dict, List |
| 12 | + |
| 13 | +from django.db import models |
| 14 | +from django.db.models import QuerySet |
| 15 | +from django.utils.translation import gettext_lazy as _ |
| 16 | +from rest_framework import serializers |
| 17 | + |
| 18 | +from application.models import ApplicationChatUserStats |
| 19 | +from common.db.search import native_search, get_dynamics_model |
| 20 | +from common.utils.common import get_file_content |
| 21 | +from maxkb.conf import PROJECT_DIR |
| 22 | + |
| 23 | + |
| 24 | +class ApplicationStatsSerializer(serializers.Serializer): |
| 25 | + chat_record_count = serializers.IntegerField(required=True, label=_("Number of conversations")) |
| 26 | + customer_added_count = serializers.IntegerField(required=True, label=_("Number of new users")) |
| 27 | + customer_num = serializers.IntegerField(required=True, label=_("Total number of users")) |
| 28 | + day = serializers.CharField(required=True, label=_("date")) |
| 29 | + star_num = serializers.IntegerField(required=True, label=_("Number of Likes")) |
| 30 | + tokens_num = serializers.IntegerField(required=True, label=_("Tokens consumption")) |
| 31 | + trample_num = serializers.IntegerField(required=True, label=_("Number of thumbs-downs")) |
| 32 | + |
| 33 | + |
| 34 | +class ApplicationStatisticsSerializer(serializers.Serializer): |
| 35 | + application_id = serializers.UUIDField(required=True, label=_("Application ID")) |
| 36 | + start_time = serializers.DateField(format='%Y-%m-%d', label=_("Start time")) |
| 37 | + end_time = serializers.DateField(format='%Y-%m-%d', label=_("End time")) |
| 38 | + |
| 39 | + def get_end_time(self): |
| 40 | + return datetime.datetime.combine( |
| 41 | + datetime.datetime.strptime(self.data.get('end_time'), '%Y-%m-%d'), |
| 42 | + datetime.datetime.max.time()) |
| 43 | + |
| 44 | + def get_start_time(self): |
| 45 | + return self.data.get('start_time') |
| 46 | + |
| 47 | + def get_customer_count_trend(self, with_valid=True): |
| 48 | + if with_valid: |
| 49 | + self.is_valid(raise_exception=True) |
| 50 | + start_time = self.get_start_time() |
| 51 | + end_time = self.get_end_time() |
| 52 | + return native_search( |
| 53 | + {'default_sql': QuerySet(ApplicationChatUserStats).filter( |
| 54 | + application_id=self.data.get('application_id'), |
| 55 | + create_time__gte=start_time, |
| 56 | + create_time__lte=end_time)}, |
| 57 | + select_string=get_file_content( |
| 58 | + os.path.join(PROJECT_DIR, "apps", "application", 'sql', 'customer_count_trend.sql'))) |
| 59 | + |
| 60 | + def get_chat_record_aggregate_trend(self, with_valid=True): |
| 61 | + if with_valid: |
| 62 | + self.is_valid(raise_exception=True) |
| 63 | + start_time = self.get_start_time() |
| 64 | + end_time = self.get_end_time() |
| 65 | + chat_record_aggregate_trend = native_search( |
| 66 | + {'default_sql': QuerySet(model=get_dynamics_model( |
| 67 | + {'application_chat.application_id': models.UUIDField(), |
| 68 | + 'application_chat_record.create_time': models.DateTimeField()})).filter( |
| 69 | + **{'application_chat.application_id': self.data.get('application_id'), |
| 70 | + 'application_chat_record.create_time__gte': start_time, |
| 71 | + 'application_chat_record.create_time__lte': end_time} |
| 72 | + )}, |
| 73 | + select_string=get_file_content( |
| 74 | + os.path.join(PROJECT_DIR, "apps", "application", 'sql', 'chat_record_count_trend.sql'))) |
| 75 | + customer_count_trend = self.get_customer_count_trend(with_valid=False) |
| 76 | + return self.merge_customer_chat_record(chat_record_aggregate_trend, customer_count_trend) |
| 77 | + |
| 78 | + def merge_customer_chat_record(self, chat_record_aggregate_trend: List[Dict], customer_count_trend: List[Dict]): |
| 79 | + |
| 80 | + return [{**self.find(chat_record_aggregate_trend, lambda c: c.get('day').strftime('%Y-%m-%d') == day, |
| 81 | + {'star_num': 0, 'trample_num': 0, 'tokens_num': 0, 'chat_record_count': 0, |
| 82 | + 'customer_num': 0, |
| 83 | + 'day': day}), |
| 84 | + **self.find(customer_count_trend, lambda c: c.get('day').strftime('%Y-%m-%d') == day, |
| 85 | + {'customer_added_count': 0})} |
| 86 | + for |
| 87 | + day in |
| 88 | + self.get_days_between_dates(self.data.get('start_time'), self.data.get('end_time'))] |
| 89 | + |
| 90 | + @staticmethod |
| 91 | + def find(source_list, condition, default): |
| 92 | + value_list = [row for row in source_list if condition(row)] |
| 93 | + if len(value_list) > 0: |
| 94 | + return value_list[0] |
| 95 | + return default |
| 96 | + |
| 97 | + @staticmethod |
| 98 | + def get_days_between_dates(start_date, end_date): |
| 99 | + start_date = datetime.datetime.strptime(start_date, '%Y-%m-%d') |
| 100 | + end_date = datetime.datetime.strptime(end_date, '%Y-%m-%d') |
| 101 | + days = [] |
| 102 | + current_date = start_date |
| 103 | + while current_date <= end_date: |
| 104 | + days.append(current_date.strftime('%Y-%m-%d')) |
| 105 | + current_date += datetime.timedelta(days=1) |
| 106 | + return days |
0 commit comments