Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions lib/groupher_server/cms/cms.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ defmodule GroupherServer.CMS do
ArticleCURD,
ArticleOperation,
ArticleEmotion,
ArticleReaction,
ArticleComment,
ArticleCollect,
ArticleUpvote,
ArticleCommentAction,
ArticleCommentEmotion,
CommentCURD,
Expand Down Expand Up @@ -81,21 +82,20 @@ defmodule GroupherServer.CMS do
defdelegate create_content(community, thread, attrs, user), to: ArticleCURD
defdelegate update_content(content, attrs), to: ArticleCURD

# ArticleReaction
defdelegate upvote_article(thread, article_id, user), to: ArticleReaction
defdelegate undo_upvote_article(thread, article_id, user), to: ArticleReaction
defdelegate upvote_article(thread, article_id, user), to: ArticleUpvote
defdelegate undo_upvote_article(thread, article_id, user), to: ArticleUpvote

defdelegate upvoted_users(thread, article_id, filter), to: ArticleReaction
defdelegate upvoted_users(thread, article_id, filter), to: ArticleUpvote

defdelegate collect_article(thread, article_id, user), to: ArticleReaction
defdelegate collect_article_ifneed(thread, article_id, user), to: ArticleReaction
defdelegate collect_article(thread, article_id, user), to: ArticleCollect
defdelegate collect_article_ifneed(thread, article_id, user), to: ArticleCollect

defdelegate undo_collect_article(thread, article_id, user), to: ArticleReaction
defdelegate undo_collect_article_ifneed(thread, article_id, user), to: ArticleReaction
defdelegate collected_users(thread, article_id, filter), to: ArticleReaction
defdelegate undo_collect_article(thread, article_id, user), to: ArticleCollect
defdelegate undo_collect_article_ifneed(thread, article_id, user), to: ArticleCollect
defdelegate collected_users(thread, article_id, filter), to: ArticleCollect

defdelegate set_collect_folder(collect, folder), to: ArticleReaction
defdelegate undo_set_collect_folder(collect, folder), to: ArticleReaction
defdelegate set_collect_folder(collect, folder), to: ArticleCollect
defdelegate undo_set_collect_folder(collect, folder), to: ArticleCollect

# ArticleOperation
# >> set flag on article, like: pin / unpin article
Expand Down
143 changes: 143 additions & 0 deletions lib/groupher_server/cms/delegates/article_collect.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
defmodule GroupherServer.CMS.Delegate.ArticleCollect do
@moduledoc """
reaction[upvote, collect, watch ...] on article [post, job...]
"""
import GroupherServer.CMS.Helper.Matcher2
import Ecto.Query, warn: false
import Helper.Utils, only: [done: 1]

import GroupherServer.CMS.Delegate.Helper,
only: [
load_reaction_users: 4,
update_article_reactions_count: 4,
update_article_reaction_user_list: 4
]

# import Helper.ErrorCode
alias Helper.{ORM}
alias GroupherServer.{Accounts, CMS, Repo}

alias Accounts.User
alias CMS.ArticleCollect

alias Ecto.Multi

@doc """
get paged collected users
"""
def collected_users(thread, article_id, filter) do
load_reaction_users(ArticleCollect, thread, article_id, filter)
end

@doc """
collect an article
"""
def collect_article(thread, article_id, %User{id: user_id}) do
with {:ok, info} <- match(thread),
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]) do
Multi.new()
|> Multi.run(:inc_author_achieve, fn _, _ ->
Accounts.achieve(article.author.user, :inc, :collect)
end)
|> Multi.run(:inc_article_collects_count, fn _, _ ->
update_article_reactions_count(info, article, :collects_count, :inc)
end)
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
update_article_reaction_user_list(:collect, article, user_id, :add)
end)
|> Multi.run(:create_collect, fn _, _ ->
thread_upcase = thread |> to_string |> String.upcase()
args = Map.put(%{user_id: user_id, thread: thread_upcase}, info.foreign_key, article.id)

ORM.create(ArticleCollect, args)
end)
|> Repo.transaction()
|> result()
end
end

# 用于在收藏时,用户添加文章到不同的收藏夹中的情况
# 如果是同一篇文章,只创建一次,collect_article 不创建记录,只是后续设置不同的收藏夹即可
# 如果是第一次收藏,那么才创建文章收藏记录
# 避免因为同一篇文章在不同收藏夹内造成的统计和用户成就系统的混乱
def collect_article_ifneed(thread, article_id, %User{id: user_id} = user) do
with findby_args <- collection_findby_args(thread, article_id, user_id) do
already_collected = ORM.find_by(ArticleCollect, findby_args)

case already_collected do
{:ok, article_collect} -> {:ok, article_collect}
{:error, _} -> collect_article(thread, article_id, user)
end
end
end

def undo_collect_article(thread, article_id, %User{id: user_id}) do
with {:ok, info} <- match(thread),
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]) do
Multi.new()
|> Multi.run(:dec_author_achieve, fn _, _ ->
Accounts.achieve(article.author.user, :dec, :collect)
end)
|> Multi.run(:inc_article_collects_count, fn _, _ ->
update_article_reactions_count(info, article, :collects_count, :dec)
end)
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
update_article_reaction_user_list(:collect, article, user_id, :remove)
end)
|> Multi.run(:undo_collect, fn _, _ ->
args = Map.put(%{user_id: user_id}, info.foreign_key, article.id)

ORM.findby_delete(ArticleCollect, args)
end)
|> Repo.transaction()
|> result()
end
end

def undo_collect_article_ifneed(thread, article_id, %User{id: user_id} = user) do
with findby_args <- collection_findby_args(thread, article_id, user_id),
{:ok, article_collect} = ORM.find_by(ArticleCollect, findby_args) do
case article_collect.collect_folders |> length <= 1 do
true -> undo_collect_article(thread, article_id, user)
false -> {:ok, article_collect}
end
end
end

def set_collect_folder(%ArticleCollect{} = collect, folder) do
collect_folders = (collect.collect_folders ++ [folder]) |> Enum.uniq()

collect
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:collect_folders, collect_folders)
|> Repo.update()
end

def undo_set_collect_folder(%ArticleCollect{} = collect, folder) do
collect_folders = Enum.reject(collect.collect_folders, &(&1.id == folder.id))

case collect_folders do
# means collect already delete
[] ->
{:ok, :pass}

_ ->
collect
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_embed(:collect_folders, collect_folders)
|> Repo.update()
end
end

defp collection_findby_args(thread, article_id, user_id) do
with {:ok, info} <- match(thread) do
thread_upcase = thread |> to_string |> String.upcase()
%{thread: thread_upcase, user_id: user_id} |> Map.put(info.foreign_key, article_id)
end
end

#############
defp result({:ok, %{create_collect: result}}), do: result |> done()
defp result({:ok, %{undo_collect: result}}), do: result |> done()
defp result({:error, _, result, _steps}), do: {:error, result}
end
30 changes: 15 additions & 15 deletions lib/groupher_server/cms/delegates/article_comment_action.ex
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
)
end)
|> Repo.transaction()
|> upsert_comment_result()
|> result()
end
end

Expand All @@ -77,7 +77,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
ORM.findby_delete(ArticlePinedComment, %{article_comment_id: comment.id})
end)
|> Repo.transaction()
|> upsert_comment_result()
|> result()
end
end

Expand Down Expand Up @@ -141,7 +141,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
|> Repo.update()
end)
|> Repo.transaction()
|> upsert_comment_result()
|> result()
end
end

Expand All @@ -166,7 +166,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
update_article_author_upvoted_info(comment, user_id)
end)
|> Repo.transaction()
|> upsert_comment_result()
|> result()
end
end

Expand Down Expand Up @@ -194,7 +194,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
update_article_author_upvoted_info(updated_comment, user_id)
end)
|> Repo.transaction()
|> upsert_comment_result()
|> result()
end
end

Expand Down Expand Up @@ -324,24 +324,24 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
ORM.update_meta(comment, meta)
end

defp upsert_comment_result({:ok, %{create_article_comment: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{add_reply_to: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{check_article_author_upvoted: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{fold_comment_report_too_many: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{update_comment_flag: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{delete_article_comment: result}}), do: {:ok, result}
defp result({:ok, %{create_article_comment: result}}), do: {:ok, result}
defp result({:ok, %{add_reply_to: result}}), do: {:ok, result}
defp result({:ok, %{check_article_author_upvoted: result}}), do: {:ok, result}
defp result({:ok, %{fold_comment_report_too_many: result}}), do: {:ok, result}
defp result({:ok, %{update_comment_flag: result}}), do: {:ok, result}
defp result({:ok, %{delete_article_comment: result}}), do: {:ok, result}

defp upsert_comment_result({:error, :create_article_comment, result, _steps}) do
defp result({:error, :create_article_comment, result, _steps}) do
raise_error(:create_comment, result)
end

defp upsert_comment_result({:error, :add_participator, result, _steps}) do
defp result({:error, :add_participator, result, _steps}) do
{:error, result}
end

defp upsert_comment_result({:error, :create_abuse_report, result, _steps}) do
defp result({:error, :create_abuse_report, result, _steps}) do
{:error, result}
end

defp upsert_comment_result({:error, _, result, _steps}), do: {:error, result}
defp result({:error, _, result, _steps}), do: {:error, result}
end
Loading