This commit is contained in:
2026-04-21 11:54:13 +03:00
parent ee8928fa5f
commit fc6ef8de7e
12 changed files with 1469 additions and 1 deletions
+85
View File
@@ -0,0 +1,85 @@
-module(core_banned_word).
-include("records.hrl").
-export([add/1, remove/1, list_all/0, is_banned/1]).
-export([check_text/1, filter_text/1]).
%% Добавить слово в бан-лист
add(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
case is_banned(WordLower) of
true -> {error, already_exists};
false ->
BannedWord = #banned_word{
id = generate_id(),
word = WordLower
},
F = fun() ->
mnesia:write(BannedWord),
{ok, BannedWord}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end
end.
%% Удалить слово из бан-листа
remove(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
Match = #banned_word{word = WordLower, _ = '_'},
case mnesia:dirty_match_object(Match) of
[] -> {error, not_found};
[BannedWord] ->
F = fun() ->
mnesia:delete_object(BannedWord),
{ok, removed}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end
end.
%% Список всех запрещённых слов
list_all() ->
Match = #banned_word{_ = '_'},
Words = mnesia:dirty_match_object(Match),
{ok, [W#banned_word.word || W <- Words]}.
%% Проверить, является ли слово запрещённым
is_banned(Word) when is_binary(Word) ->
WordLower = string:lowercase(Word),
Match = #banned_word{word = WordLower, _ = '_'},
case mnesia:dirty_match_object(Match) of
[] -> false;
_ -> true
end.
%% Проверить текст на наличие запрещённых слов
check_text(Text) when is_binary(Text) ->
TextLower = string:lowercase(Text),
Words = string:split(TextLower, " ", all),
{ok, BannedWords} = list_all(),
lists:any(fun(W) -> lists:member(W, BannedWords) end, Words).
%% Отфильтровать запрещённые слова (заменить на ***)
filter_text(Text) when is_binary(Text) ->
{ok, BannedWords} = list_all(),
Words = binary:split(Text, <<" ">>, [global]),
Filtered = lists:map(fun(W) ->
case lists:member(string:lowercase(W), BannedWords) of
true -> <<"***">>;
false -> W
end
end, Words),
iolist_to_binary(join_binary(Filtered, <<" ">>)).
join_binary([], _) -> [];
join_binary([H], _) -> [H];
join_binary([H|T], Sep) ->
[H, Sep | join_binary(T, Sep)].
%% Внутренние функции
generate_id() ->
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).
+88
View File
@@ -0,0 +1,88 @@
-module(core_report).
-include("records.hrl").
-export([create/4, get_by_id/1, list_by_target/2, list_by_reporter/1, list_all/0]).
-export([update_status/3, get_count_by_target/2]).
-export([generate_id/0]).
%% Создание жалобы
create(ReporterId, TargetType, TargetId, Reason) ->
Id = generate_id(),
Report = #report{
id = Id,
reporter_id = ReporterId,
target_type = TargetType,
target_id = TargetId,
reason = Reason,
status = pending,
created_at = calendar:universal_time(),
resolved_at = undefined,
resolved_by = undefined
},
F = fun() ->
mnesia:write(Report),
{ok, Report}
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end.
%% Получение жалобы по ID
get_by_id(Id) ->
case mnesia:dirty_read(report, Id) of
[] -> {error, not_found};
[Report] -> {ok, Report}
end.
%% Список жалоб на цель
list_by_target(TargetType, TargetId) ->
Match = #report{target_type = TargetType, target_id = TargetId, _ = '_'},
Reports = mnesia:dirty_match_object(Match),
{ok, Reports}.
%% Список жалоб от пользователя
list_by_reporter(ReporterId) ->
Match = #report{reporter_id = ReporterId, _ = '_'},
Reports = mnesia:dirty_match_object(Match),
{ok, Reports}.
%% Список всех жалоб (для админов)
list_all() ->
Match = #report{_ = '_'},
Reports = mnesia:dirty_match_object(Match),
{ok, Reports}.
%% Обновление статуса жалобы
update_status(Id, Status, ResolvedBy) when Status =:= reviewed; Status =:= dismissed ->
F = fun() ->
case mnesia:read(report, Id) of
[] ->
{error, not_found};
[Report] ->
Updated = Report#report{
status = Status,
resolved_at = calendar:universal_time(),
resolved_by = ResolvedBy
},
mnesia:write(Updated),
{ok, Updated}
end
end,
case mnesia:transaction(F) of
{atomic, Result} -> Result;
{aborted, Reason} -> {error, Reason}
end.
%% Получить количество жалоб на цель
get_count_by_target(TargetType, TargetId) ->
Match = #report{target_type = TargetType, target_id = TargetId, status = pending, _ = '_'},
Reports = mnesia:dirty_match_object(Match),
length(Reports).
%% Внутренние функции
generate_id() ->
base64:encode(crypto:strong_rand_bytes(16), #{mode => urlsafe, padding => false}).