Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit 7091f23

Browse files
committed
refactor: extract helper to share upvote && collect logic
1 parent 798f034 commit 7091f23

File tree

5 files changed

+189
-243
lines changed

5 files changed

+189
-243
lines changed

lib/groupher_server/cms/cms.ex

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ defmodule GroupherServer.CMS do
1212
ArticleCURD,
1313
ArticleOperation,
1414
ArticleEmotion,
15-
ArticleReaction,
1615
ArticleComment,
1716
ArticleCollect,
17+
ArticleUpvote,
1818
ArticleCommentAction,
1919
ArticleCommentEmotion,
2020
CommentCURD,
@@ -82,11 +82,10 @@ defmodule GroupherServer.CMS do
8282
defdelegate create_content(community, thread, attrs, user), to: ArticleCURD
8383
defdelegate update_content(content, attrs), to: ArticleCURD
8484

85-
# ArticleReaction
86-
defdelegate upvote_article(thread, article_id, user), to: ArticleReaction
87-
defdelegate undo_upvote_article(thread, article_id, user), to: ArticleReaction
85+
defdelegate upvote_article(thread, article_id, user), to: ArticleUpvote
86+
defdelegate undo_upvote_article(thread, article_id, user), to: ArticleUpvote
8887

89-
defdelegate upvoted_users(thread, article_id, filter), to: ArticleReaction
88+
defdelegate upvoted_users(thread, article_id, filter), to: ArticleUpvote
9089

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

lib/groupher_server/cms/delegates/article_collect.ex

Lines changed: 14 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@ defmodule GroupherServer.CMS.Delegate.ArticleCollect do
44
"""
55
import GroupherServer.CMS.Helper.Matcher2
66
import Ecto.Query, warn: false
7-
import Helper.Utils, only: [done: 1, strip_struct: 1]
8-
# import Helper.ErrorCode
9-
import ShortMaps
7+
import Helper.Utils, only: [done: 1]
8+
9+
import GroupherServer.CMS.Delegate.Helper,
10+
only: [
11+
load_reaction_users: 4,
12+
update_article_reactions_count: 4,
13+
update_article_reaction_user_list: 4
14+
]
1015

11-
alias Helper.{ORM, QueryBuilder}
16+
# import Helper.ErrorCode
17+
alias Helper.{ORM}
1218
alias GroupherServer.{Accounts, CMS, Repo}
1319

1420
alias Accounts.User
15-
alias CMS.{ArticleUpvote, ArticleCollect, Embeds}
21+
alias CMS.ArticleCollect
1622

1723
alias Ecto.Multi
1824

19-
@default_article_meta Embeds.ArticleMeta.default_meta()
20-
2125
@doc """
2226
get paged collected users
2327
"""
@@ -36,7 +40,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCollect do
3640
Accounts.achieve(article.author.user, :inc, :collect)
3741
end)
3842
|> Multi.run(:inc_article_collects_count, fn _, _ ->
39-
update_article_upvotes_count(info, article, :collects_count, :inc)
43+
update_article_reactions_count(info, article, :collect, :inc)
4044
end)
4145
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
4246
update_article_reaction_user_list(:collect, article, user_id, :add)
@@ -75,7 +79,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCollect do
7579
Accounts.achieve(article.author.user, :dec, :collect)
7680
end)
7781
|> Multi.run(:inc_article_collects_count, fn _, _ ->
78-
update_article_upvotes_count(info, article, :collects_count, :dec)
82+
update_article_reactions_count(info, article, :collect, :dec)
7983
end)
8084
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
8185
update_article_reaction_user_list(:collect, article, user_id, :remove)
@@ -133,84 +137,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCollect do
133137
end
134138

135139
#############
136-
#############
137-
#############
138-
139-
# TODO: put in header, it's for upvotes and collect users
140-
defp load_reaction_users(schema, thread, article_id, %{page: page, size: size} = filter) do
141-
with {:ok, info} <- match(thread) do
142-
schema
143-
|> where([u], field(u, ^info.foreign_key) == ^article_id)
144-
|> QueryBuilder.load_inner_users(filter)
145-
|> ORM.paginater(~m(page size)a)
146-
|> done()
147-
end
148-
end
149-
150-
# TODO: put in header, it's for upvotes and collect users
151-
defp update_article_upvotes_count(info, article, field, opt) do
152-
schema =
153-
case field do
154-
:upvotes_count -> ArticleUpvote
155-
:collects_count -> ArticleCollect
156-
end
157-
158-
count_query = from(u in schema, where: field(u, ^info.foreign_key) == ^article.id)
159-
cur_count = Repo.aggregate(count_query, :count)
160-
161-
case opt do
162-
:inc ->
163-
new_count = Enum.max([0, cur_count])
164-
ORM.update(article, Map.put(%{}, field, new_count + 1))
165-
166-
:dec ->
167-
new_count = Enum.max([1, cur_count])
168-
ORM.update(article, Map.put(%{}, field, new_count - 1))
169-
end
170-
end
171-
172-
# TODO: put in header, it's for upvotes and collect users
173-
@doc """
174-
add or remove artilce's reaction users is list history
175-
e.g:
176-
add/remove user_id to upvoted_user_ids in article meta
177-
"""
178-
@spec update_article_reaction_user_list(
179-
:upvot | :collect,
180-
T.article_common(),
181-
String.t(),
182-
:add | :remove
183-
) :: T.article_common()
184-
defp update_article_reaction_user_list(action, %{meta: nil} = article, user_id, opt) do
185-
cur_user_ids = []
186-
187-
updated_user_ids =
188-
case opt do
189-
:add -> [user_id] ++ cur_user_ids
190-
:remove -> cur_user_ids -- [user_id]
191-
end
192-
193-
meta = @default_article_meta |> Map.merge(%{"#{action}ed_user_ids": updated_user_ids})
194-
ORM.update_meta(article, meta)
195-
end
196-
197-
defp update_article_reaction_user_list(action, article, user_id, opt) do
198-
cur_user_ids = get_in(article, [:meta, :"#{action}ed_user_ids"])
199-
200-
updated_user_ids =
201-
case opt do
202-
:add -> [user_id] ++ cur_user_ids
203-
:remove -> cur_user_ids -- [user_id]
204-
end
205-
206-
meta = article.meta |> Map.merge(%{"#{action}ed_user_ids": updated_user_ids}) |> strip_struct
207-
ORM.update_meta(article, meta)
208-
end
209-
210140
defp result({:ok, %{create_collect: result}}), do: result |> done()
211141
defp result({:ok, %{undo_collect: result}}), do: result |> done()
212-
213-
defp result({:error, _, result, _steps}) do
214-
{:error, result}
215-
end
142+
defp result({:error, _, result, _steps}), do: {:error, result}
216143
end

lib/groupher_server/cms/delegates/article_reaction.ex

Lines changed: 0 additions & 149 deletions
This file was deleted.
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
defmodule GroupherServer.CMS.Delegate.ArticleUpvote do
2+
@moduledoc """
3+
reaction[upvote, collect, watch ...] on article [post, job...]
4+
"""
5+
import GroupherServer.CMS.Helper.Matcher2
6+
import Ecto.Query, warn: false
7+
import Helper.Utils, only: [done: 1]
8+
9+
import GroupherServer.CMS.Delegate.Helper,
10+
only: [
11+
load_reaction_users: 4,
12+
update_article_reactions_count: 4,
13+
update_article_reaction_user_list: 4
14+
]
15+
16+
# import Helper.ErrorCode
17+
18+
alias Helper.ORM
19+
alias GroupherServer.{Accounts, CMS, Repo}
20+
21+
alias Accounts.User
22+
alias CMS.ArticleUpvote
23+
24+
alias Ecto.Multi
25+
26+
def upvoted_users(thread, article_id, filter) do
27+
load_reaction_users(ArticleUpvote, thread, article_id, filter)
28+
end
29+
30+
@doc "upvote to a article-like content"
31+
def upvote_article(thread, article_id, %User{id: user_id}) do
32+
with {:ok, info} <- match(thread),
33+
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]) do
34+
Multi.new()
35+
|> Multi.run(:inc_article_upvotes_count, fn _, _ ->
36+
update_article_reactions_count(info, article, :upvote, :inc)
37+
end)
38+
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
39+
update_article_reaction_user_list(:upvot, article, user_id, :add)
40+
end)
41+
|> Multi.run(:add_achievement, fn _, _ ->
42+
achiever_id = article.author.user_id
43+
Accounts.achieve(%User{id: achiever_id}, :inc, :upvote)
44+
end)
45+
|> Multi.run(:create_upvote, fn _, _ ->
46+
thread_upcase = thread |> to_string |> String.upcase()
47+
args = Map.put(%{user_id: user_id, thread: thread_upcase}, info.foreign_key, article.id)
48+
49+
with {:ok, _} <- ORM.create(ArticleUpvote, args) do
50+
ORM.find(info.model, article.id)
51+
end
52+
end)
53+
|> Repo.transaction()
54+
|> result()
55+
end
56+
end
57+
58+
@doc "upvote to a article-like content"
59+
def undo_upvote_article(thread, article_id, %User{id: user_id}) do
60+
with {:ok, info} <- match(thread),
61+
{:ok, article} <- ORM.find(info.model, article_id) do
62+
Multi.new()
63+
|> Multi.run(:inc_article_upvotes_count, fn _, _ ->
64+
update_article_reactions_count(info, article, :upvote, :dec)
65+
end)
66+
|> Multi.run(:update_article_reaction_user_list, fn _, _ ->
67+
update_article_reaction_user_list(:upvot, article, user_id, :remove)
68+
end)
69+
|> Multi.run(:undo_upvote, fn _, _ ->
70+
args = Map.put(%{user_id: user_id}, info.foreign_key, article.id)
71+
72+
ORM.findby_delete(ArticleUpvote, args)
73+
ORM.find(info.model, article.id)
74+
end)
75+
|> Repo.transaction()
76+
|> result()
77+
end
78+
end
79+
80+
defp result({:ok, %{create_upvote: result}}), do: result |> done()
81+
defp result({:ok, %{undo_upvote: result}}), do: result |> done()
82+
defp result({:error, _, result, _steps}), do: {:error, result}
83+
end

0 commit comments

Comments
 (0)