Рефакторинг админских обработчиков - пагинация, сортировка, фильтрация. Часть 1

This commit is contained in:
2026-05-26 13:04:31 +03:00
parent 01dbc6d6cb
commit ed5b275efb
24 changed files with 1009 additions and 1126 deletions
+22 -33
View File
@@ -6,7 +6,6 @@
%%%-------------------------------------------------------------------
-module(admin_handler_stats).
-behaviour(cowboy_handler).
-export([init/2]).
-export([trails/0]).
@@ -17,7 +16,7 @@
init(Req, _Opts) ->
case cowboy_req:method(Req) of
<<"GET">> -> get_stats(Req);
_ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>)
_ -> handler_utils:send_error(Req, 405, <<"Method not allowed">>)
end.
%%% Swagger metadata
@@ -25,19 +24,19 @@ init(Req, _Opts) ->
trails() ->
[
#{
path => <<"/v1/admin/stats">>,
method => <<"GET">>,
path => <<"/v1/admin/stats">>,
method => <<"GET">>,
description => <<"Get admin dashboard statistics">>,
tags => [<<"Statistics">>],
parameters => [
tags => [<<"Statistics">>],
parameters => [
#{name => <<"from">>, in => <<"query">>, schema => #{type => string, format => <<"date-time">>}, description => <<"Start date (ISO8601)">>},
#{name => <<"to">>, in => <<"query">>, schema => #{type => string, format => <<"date-time">>}, description => <<"End date (ISO8601)">>}
#{name => <<"to">>, in => <<"query">>, schema => #{type => string, format => <<"date-time">>}, description => <<"End date (ISO8601)">>}
],
responses => #{
200 => #{
description => <<"Statistics object">>,
content => #{<<"application/json">> => #{schema => #{
type => object,
type => object,
properties => stats_schema()
}}}
},
@@ -48,13 +47,13 @@ trails() ->
stats_schema() ->
#{
<<"users">> => #{type => integer, description => <<"Total number of users">>},
<<"events">> => #{type => integer},
<<"reviews">> => #{type => integer},
<<"calendars">> => #{type => integer},
<<"reports">> => #{type => integer},
<<"tickets">> => #{type => integer},
<<"subscriptions">> => #{type => integer},
<<"users">> => #{type => integer, description => <<"Total number of users">>},
<<"events">> => #{type => integer},
<<"reviews">> => #{type => integer},
<<"calendars">> => #{type => integer},
<<"reports">> => #{type => integer},
<<"tickets">> => #{type => integer},
<<"subscriptions">> => #{type => integer},
<<"active_subscriptions">> => #{type => integer}
}.
@@ -68,8 +67,10 @@ get_stats(Req) ->
{ok, Admin} = core_admin:get_by_id(AdminId),
Role = Admin#admin.role,
Stats = case parse_date_range(Req1) of
{ok, From, To} -> logic_stats:get_stats(Role, AdminId, From, To);
_ -> logic_stats:get_stats(Role, AdminId)
{ok, From, To} ->
logic_stats:get_stats(Role, AdminId, From, To);
_ ->
logic_stats:get_stats(Role, AdminId)
end,
handler_utils:send_json(Req1, 200, Stats);
{error, Code, Message, Req1} ->
@@ -81,22 +82,10 @@ get_stats(Req) ->
-spec parse_date_range(cowboy_req:req()) -> {ok, calendar:datetime(), calendar:datetime()} | error.
parse_date_range(Req) ->
Qs = cowboy_req:parse_qs(Req),
From = proplists:get_value(<<"from">>, Qs),
To = proplists:get_value(<<"to">>, Qs),
From = handler_utils:parse_datetime_qs(proplists:get_value(<<"from">>, Qs)),
To = handler_utils:parse_datetime_qs(proplists:get_value(<<"to">>, Qs)),
case {From, To} of
{undefined, _} -> error;
{_, undefined} -> error;
{F, T} -> try FromDT = iso8601_to_datetime(F),
ToDT = iso8601_to_datetime(T),
{ok, FromDT, ToDT}
catch _:_ -> error
end
end.
%% @private Преобразует бинарную строку ISO8601 в кортеж datetime().
-spec iso8601_to_datetime(binary()) -> calendar:datetime().
iso8601_to_datetime(Str) ->
[Date, Time] = binary:split(Str, <<"T">>),
[Y, M, D] = [binary_to_integer(X) || X <- binary:split(Date, <<"-">>, [global])],
[H, Min, S] = [binary_to_integer(X) || X <- binary:split(Time, <<":">>, [global])],
{{Y, M, D}, {H, Min, S}}.
{F, T} -> {ok, F, T}
end.