105 lines
4.3 KiB
Erlang
105 lines
4.3 KiB
Erlang
-module(logic_admin).
|
|
|
|
-export([list_admins/2, get_admin/1, update_admin/2, delete_admin/1, create_admin/3]).
|
|
|
|
-include("records.hrl").
|
|
|
|
%% @doc Создаёт нового администратора (доступно только суперадмину).
|
|
%% Роль может быть superadmin, admin, moderator или support.
|
|
-spec create_admin(binary(), binary(), atom()) ->
|
|
{ok, #admin{}} | {error, email_exists | invalid_role}.
|
|
create_admin(Email, Password, Role) when Role =:= superadmin; Role =:= admin; Role =:= moderator; Role =:= support ->
|
|
case core_admin:get_by_email(Email) of
|
|
{ok, _} -> {error, email_exists};
|
|
{error, not_found} ->
|
|
{ok, PasswordHash} = logic_auth:hash_password(Password),
|
|
core_admin:create(Email, PasswordHash, Role)
|
|
end;
|
|
create_admin(_, _, _) ->
|
|
{error, invalid_role}.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% Административный список администраторов с пагинацией
|
|
%%%-------------------------------------------------------------------
|
|
-spec list_admins(map(), #{limit => integer(), offset => integer(), sort => binary(), order => binary()}) ->
|
|
{ok, non_neg_integer(), [#admin{}]}.
|
|
list_admins(Filters, Pagination) ->
|
|
#{limit := Limit, offset := Offset, sort := Sort, order := Order} = Pagination,
|
|
AllAdmins = core_admin:list_all(),
|
|
Filtered = apply_filters(AllAdmins, Filters),
|
|
Sorted = sort_admins(Filtered, Sort, Order),
|
|
Total = length(Sorted),
|
|
Page = lists:sublist(Sorted, Offset + 1, Limit),
|
|
{ok, Total, Page}.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% Получение администратора по ID
|
|
%%%-------------------------------------------------------------------
|
|
-spec get_admin(binary()) -> {ok, #admin{}} | {error, not_found}.
|
|
get_admin(AdminId) ->
|
|
core_admin:get_by_id(AdminId).
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% Обновление администратора
|
|
%%%-------------------------------------------------------------------
|
|
-spec update_admin(binary(), proplists:proplist()) ->
|
|
{ok, #admin{}} | {error, not_found | invalid_field}.
|
|
update_admin(AdminId, Updates) ->
|
|
case core_admin:get_by_id(AdminId) of
|
|
{ok, _Admin} ->
|
|
ValidUpdates = validate_admin_updates(Updates),
|
|
core_admin:update(AdminId, ValidUpdates);
|
|
Error ->
|
|
Error
|
|
end.
|
|
|
|
%%%-------------------------------------------------------------------
|
|
%%% Удалить администратора (физическое удаление из базы)
|
|
%%%-------------------------------------------------------------------
|
|
-spec delete_admin(binary()) -> {ok, deleted} | {error, not_found}.
|
|
delete_admin(AdminId) ->
|
|
core_admin:delete(AdminId).
|
|
|
|
%%%===================================================================
|
|
%%% Внутренние функции
|
|
%%%===================================================================
|
|
|
|
apply_filters(Admins, Filters) ->
|
|
Role = maps:get(role, Filters, undefined),
|
|
Status = maps:get(status, Filters, undefined),
|
|
F1 = case Role of
|
|
undefined -> Admins;
|
|
_ -> [A || A <- Admins, A#admin.role =:= Role]
|
|
end,
|
|
case Status of
|
|
undefined -> F1;
|
|
_ -> [A || A <- F1, A#admin.status =:= Status]
|
|
end.
|
|
|
|
sort_admins(Admins, SortField, Order) ->
|
|
Field = binary_to_existing_atom(SortField, utf8),
|
|
Sorted = lists:sort(
|
|
fun(A, B) ->
|
|
ValA = admin_field(A, Field),
|
|
ValB = admin_field(B, Field),
|
|
if Order == <<"asc">> -> ValA =< ValB;
|
|
true -> ValA >= ValB
|
|
end
|
|
end, Admins),
|
|
Sorted.
|
|
|
|
admin_field(#admin{created_at = V}, created_at) -> V;
|
|
admin_field(#admin{email = V}, email) -> V;
|
|
admin_field(#admin{role = V}, role) -> V;
|
|
admin_field(_, _) -> undefined.
|
|
|
|
validate_admin_updates(Updates) ->
|
|
lists:filter(fun validate_admin_update/1, Updates).
|
|
|
|
validate_admin_update({nickname, V}) when is_binary(V); V =:= undefined -> true;
|
|
validate_admin_update({avatar_url, V}) when is_binary(V); V =:= undefined -> true;
|
|
validate_admin_update({timezone, V}) when is_binary(V); V =:= undefined -> true;
|
|
validate_admin_update({language, V}) when is_binary(V); V =:= undefined -> true;
|
|
validate_admin_update({phone, V}) when is_binary(V); V =:= undefined -> true;
|
|
validate_admin_update({preferences, V}) when is_map(V); V =:= undefined -> true;
|
|
validate_admin_update(_) -> false. |