@@ -13,6 +13,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do
1313
1414 alias Ecto.Multi
1515
16+ @ type t_user_list :: [ % { login: String . t ( ) } ]
17+ @ type t_mention_status :: % { user_list: t_user_list , user_count: Integer . t ( ) }
18+
1619 @ max_latest_emotion_users_count ArticleComment . max_latest_emotion_users_count ( )
1720
1821 @ doc "make emotion to a comment"
@@ -35,46 +38,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do
3538 ArticleCommentUserEmotion |> ORM . create ( args )
3639 end )
3740 |> Multi . run ( :query_emotion_status , fn _ , _ ->
38- # 每次被 emotion 动作触发后重新查询,主要原因
39- # 1.并发下保证数据准确,类似 views 阅读数的统计
40- # 2. 前端使用 nickname 而非 login 展示,如果用户改了 nickname, 可以"自动纠正"
41- query =
42- from ( a in ArticleCommentUserEmotion ,
43- join: user in User ,
44- on: a . user_id == user . id ,
45- where: a . article_comment_id == ^ comment . id ,
46- where: field ( a , ^ emotion ) == true ,
47- select: % { login: user . login , nickname: user . nickname }
48- )
49-
50- emotioned_user_info_list = Repo . all ( query ) |> Enum . uniq ( )
51- emotioned_user_count = length ( emotioned_user_info_list )
52-
53- { :ok , % { user_list: emotioned_user_info_list , user_count: emotioned_user_count } }
41+ query_emotion_status ( comment , emotion )
5442 end )
5543 |> Multi . run ( :update_comment_emotion , fn _ , % { query_emotion_status: status } ->
56- % { user_count: user_count , user_list: user_list } = status
57-
58- updated_emotions =
59- % { }
60- |> Map . put ( :"#{ emotion } _count" , user_count )
61- |> Map . put ( :"#{ emotion } _user_logins" , user_list |> Enum . map ( & & 1 . login ) )
62- |> Map . put (
63- :"latest_#{ emotion } _users" ,
64- Enum . slice ( user_list , 0 , @ max_latest_emotion_users_count )
65- )
66-
67- viewer_has_emotioned = user . login in Map . get ( updated_emotions , :"#{ emotion } _user_logins" )
68-
69- updated_emotions =
70- updated_emotions |> Map . put ( :"viewer_has_#{ emotion } ed" , viewer_has_emotioned )
71-
72- comment
73- |> Ecto.Changeset . change ( )
74- |> Ecto.Changeset . put_embed ( :emotions , updated_emotions )
75- |> Repo . update ( )
76- # virtual field can not be updated
77- |> add_viewer_emotioned_ifneed ( updated_emotions )
44+ update_comment_emotion ( comment , emotion , status , user )
7845 end )
7946 |> Repo . transaction ( )
8047 |> upsert_comment_result
@@ -96,52 +63,61 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentEmotion do
9663 article_comment_user_emotion |> ORM . update ( args )
9764 end )
9865 |> Multi . run ( :query_emotion_status , fn _ , _ ->
99- # 每次被 emotion 动作触发后重新查询,主要原因
100- # 1.并发下保证数据准确,类似 views 阅读数的统计
101- # 2. 前端使用 nickname 而非 login 展示,如果用户改了 nickname, 可以"自动纠正"
102- query =
103- from ( a in ArticleCommentUserEmotion ,
104- join: user in User ,
105- on: a . user_id == user . id ,
106- where: a . article_comment_id == ^ comment . id ,
107- where: field ( a , ^ emotion ) == true ,
108- select: % { login: user . login , nickname: user . nickname }
109- )
110-
111- emotioned_user_info_list = Repo . all ( query ) |> Enum . uniq ( )
112- emotioned_user_count = length ( emotioned_user_info_list )
113-
114- { :ok , % { user_list: emotioned_user_info_list , user_count: emotioned_user_count } }
66+ query_emotion_status ( comment , emotion )
11567 end )
11668 |> Multi . run ( :update_comment_emotion , fn _ , % { query_emotion_status: status } ->
117- % { user_count: user_count , user_list: user_list } = status
118-
119- updated_emotions =
120- % { }
121- |> Map . put ( :"#{ emotion } _count" , user_count )
122- |> Map . put ( :"#{ emotion } _user_logins" , user_list |> Enum . map ( & & 1 . login ) )
123- |> Map . put (
124- :"latest_#{ emotion } _users" ,
125- Enum . slice ( user_list , 0 , @ max_latest_emotion_users_count )
126- )
127-
128- viewer_has_emotioned = user . login in Map . get ( updated_emotions , :"#{ emotion } _user_logins" )
129-
130- updated_emotions =
131- updated_emotions |> Map . put ( :"viewer_has_#{ emotion } ed" , viewer_has_emotioned )
132-
133- comment
134- |> Ecto.Changeset . change ( )
135- |> Ecto.Changeset . put_embed ( :emotions , updated_emotions )
136- |> Repo . update ( )
137- # virtual field can not be updated
138- |> add_viewer_emotioned_ifneed ( updated_emotions )
69+ update_comment_emotion ( comment , emotion , status , user )
13970 end )
14071 |> Repo . transaction ( )
14172 |> upsert_comment_result
14273 end
14374 end
14475
76+ @ spec query_emotion_status ( ArticleComment . t ( ) , Atom . t ( ) ) :: { :ok , t_mention_status }
77+ defp query_emotion_status ( comment , emotion ) do
78+ # 每次被 emotion 动作触发后重新查询,主要原因
79+ # 1.并发下保证数据准确,类似 views 阅读数的统计
80+ # 2. 前端使用 nickname 而非 login 展示,如果用户改了 nickname, 可以"自动纠正"
81+ query =
82+ from ( a in ArticleCommentUserEmotion ,
83+ join: user in User ,
84+ on: a . user_id == user . id ,
85+ where: a . article_comment_id == ^ comment . id ,
86+ where: field ( a , ^ emotion ) == true ,
87+ select: % { login: user . login , nickname: user . nickname }
88+ )
89+
90+ emotioned_user_info_list = Repo . all ( query ) |> Enum . uniq ( )
91+ emotioned_user_count = length ( emotioned_user_info_list )
92+
93+ { :ok , % { user_list: emotioned_user_info_list , user_count: emotioned_user_count } }
94+ end
95+
96+ @ spec update_comment_emotion ( ArticleComment . t ( ) , Atom . t ( ) , t_mention_status , User . t ( ) ) ::
97+ { :ok , ArticleComment . t ( ) } | { :error , any }
98+ defp update_comment_emotion ( comment , emotion , status , user ) do
99+ % { user_count: user_count , user_list: user_list } = status
100+
101+ emotions =
102+ % { }
103+ |> Map . put ( :"#{ emotion } _count" , user_count )
104+ |> Map . put ( :"#{ emotion } _user_logins" , user_list |> Enum . map ( & & 1 . login ) )
105+ |> Map . put (
106+ :"latest_#{ emotion } _users" ,
107+ Enum . slice ( user_list , 0 , @ max_latest_emotion_users_count )
108+ )
109+
110+ viewer_has_emotioned = user . login in Map . get ( emotions , :"#{ emotion } _user_logins" )
111+ emotions = emotions |> Map . put ( :"viewer_has_#{ emotion } ed" , viewer_has_emotioned )
112+
113+ comment
114+ |> Ecto.Changeset . change ( )
115+ |> Ecto.Changeset . put_embed ( :emotions , emotions )
116+ |> Repo . update ( )
117+ # virtual field can not be updated
118+ |> add_viewer_emotioned_ifneed ( emotions )
119+ end
120+
145121 defp add_viewer_emotioned_ifneed ( { :error , error } , _ ) , do: { :error , error }
146122
147123 defp add_viewer_emotioned_ifneed ( { :ok , comment } , emotions ) do
0 commit comments