Initial commit: Базовая структура сайта
This commit is contained in:
98
backend/app/api/v1/metrics.py
Executable file
98
backend/app/api/v1/metrics.py
Executable file
@@ -0,0 +1,98 @@
|
||||
"""
|
||||
Модуль Метрика - числовые показатели эффективности
|
||||
"""
|
||||
from fastapi import APIRouter, Depends, Query, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy import text
|
||||
from typing import Literal
|
||||
from app.core.database import get_manictime_db
|
||||
from app.core.security import get_current_user
|
||||
from app.models.service_db import AppUser
|
||||
from app.schemas.metrics import MetricsAggregateResponse, MetricsRow
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/aggregate", response_model=MetricsAggregateResponse)
|
||||
async def get_metrics_aggregate(
|
||||
period: Literal["week", "month", "quarter", "year"] = Query(..., description="Период агрегации"),
|
||||
year: int = Query(..., description="Год"),
|
||||
current_user: AppUser = Depends(get_current_user),
|
||||
manictime_db: Session = Depends(get_manictime_db)
|
||||
):
|
||||
"""
|
||||
Получение агрегированных метрик за указанный период
|
||||
"""
|
||||
try:
|
||||
if year < 2000 or year > 2100:
|
||||
raise HTTPException(status_code=400, detail="Неверный год")
|
||||
|
||||
# Определение функции агрегации в зависимости от периода
|
||||
date_trunc_func = {
|
||||
"week": "week",
|
||||
"month": "month",
|
||||
"quarter": "quarter",
|
||||
"year": "year"
|
||||
}.get(period, "quarter")
|
||||
|
||||
# SQL запрос для агрегации активного времени
|
||||
query = text(f"""
|
||||
SELECT
|
||||
u."DisplayName" AS user_name,
|
||||
DATE_TRUNC('{date_trunc_func}', a."StartLocalTime") AS period_start,
|
||||
SUM(EXTRACT(EPOCH FROM (a."EndLocalTime" - a."StartLocalTime"))) AS total_seconds
|
||||
FROM "Ar_Activity" a
|
||||
JOIN "Ar_Timeline" t ON a."ReportId" = t."ReportId"
|
||||
JOIN "Ar_User" u ON t."OwnerId" = u."UserId"
|
||||
WHERE
|
||||
t."SchemaName" = 'ManicTime/Computer usage'
|
||||
AND a."Name" = 'Active'
|
||||
AND EXTRACT(YEAR FROM a."StartLocalTime") = :year
|
||||
GROUP BY
|
||||
u."DisplayName",
|
||||
DATE_TRUNC('{date_trunc_func}', a."StartLocalTime")
|
||||
ORDER BY
|
||||
u."DisplayName",
|
||||
period_start
|
||||
""")
|
||||
|
||||
result = manictime_db.execute(query, {"year": year})
|
||||
rows = result.fetchall()
|
||||
|
||||
# Группировка данных по пользователям
|
||||
user_data = {}
|
||||
for row in rows:
|
||||
user_name = row.user_name
|
||||
if user_name not in user_data:
|
||||
user_data[user_name] = {}
|
||||
|
||||
# Формирование ключа периода
|
||||
period_start = row.period_start
|
||||
if period == "week":
|
||||
period_key = f"W{period_start.isocalendar()[1]}"
|
||||
elif period == "month":
|
||||
period_key = f"M{period_start.month}"
|
||||
elif period == "quarter":
|
||||
quarter = (period_start.month - 1) // 3 + 1
|
||||
period_key = f"Q{quarter}"
|
||||
else: # year
|
||||
period_key = "Y1"
|
||||
|
||||
# Конвертация секунд в часы
|
||||
hours = float(row.total_seconds) / 3600
|
||||
user_data[user_name][period_key] = round(hours, 2)
|
||||
|
||||
# Формирование ответа
|
||||
metrics_rows = []
|
||||
for user_name, periods in user_data.items():
|
||||
metrics_rows.append(MetricsRow(user=user_name, data=periods))
|
||||
|
||||
return MetricsAggregateResponse(
|
||||
period_type=period,
|
||||
year=year,
|
||||
data=metrics_rows
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Ошибка при получении данных: {str(e)}")
|
||||
|
||||
Reference in New Issue
Block a user