@@ -7,7 +7,15 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
77 import GroupherServer.CMS.Helper.Matcher
88
99 import Helper.Utils ,
10- only: [ done: 1 , pick_by: 2 , integerfy: 1 , strip_struct: 1 , module_to_thread: 1 ]
10+ only: [
11+ done: 1 ,
12+ pick_by: 2 ,
13+ integerfy: 1 ,
14+ strip_struct: 1 ,
15+ module_to_thread: 1 ,
16+ get_config: 2 ,
17+ ensure: 2
18+ ]
1119
1220 import GroupherServer.CMS.Delegate.Helper , only: [ mark_viewer_emotion_states: 2 ]
1321 import Helper.ErrorCode
@@ -23,6 +31,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
2331
2432 alias Ecto.Multi
2533
34+ @ active_period get_config ( :article , :active_period_days )
2635 @ default_emotions Embeds.ArticleEmotion . default_emotions ( )
2736 @ default_article_meta Embeds.ArticleMeta . default_meta ( )
2837
@@ -31,7 +40,16 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
3140 """
3241 def read_article ( thread , id ) do
3342 with { :ok , info } <- match ( thread ) do
34- ORM . read ( info . model , id , inc: :views )
43+ Multi . new ( )
44+ |> Multi . run ( :inc_views , fn _ , _ -> ORM . read ( info . model , id , inc: :views ) end )
45+ |> Multi . run ( :update_article_meta , fn _ , % { inc_views: article } ->
46+ article_meta = ensure ( article . meta , @ default_article_meta )
47+ meta = Map . merge ( article_meta , % { can_undo_sink: in_active_period? ( thread , article ) } )
48+
49+ ORM . update_meta ( article , meta )
50+ end )
51+ |> Repo . transaction ( )
52+ |> result ( )
3553 end
3654 end
3755
@@ -41,8 +59,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
4159 def read_article ( thread , id , % User { id: user_id } ) do
4260 with { :ok , info } <- match ( thread ) do
4361 Multi . new ( )
44- |> Multi . run ( :inc_views , fn _ , _ ->
45- ORM . read ( info . model , id , inc: :views )
62+ |> Multi . run ( :inc_views , fn _ , _ -> ORM . read ( info . model , id , inc: :views ) end )
63+ |> Multi . run ( :update_article_meta , fn _ , % { inc_views: article } ->
64+ article_meta = ensure ( article . meta , @ default_article_meta )
65+ meta = Map . merge ( article_meta , % { can_undo_sink: in_active_period? ( thread , article ) } )
66+
67+ ORM . update_meta ( article , meta )
4668 end )
4769 |> Multi . run ( :add_viewed_user , fn _ , % { inc_views: article } ->
4870 update_viewed_user_list ( article , user_id )
@@ -142,6 +164,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
142164 |> Multi . run ( :set_article_tags , fn _ , % { create_article: article } ->
143165 ArticleTag . set_article_tags ( community , thread , article , attrs )
144166 end )
167+ |> Multi . run ( :set_active_at_timestamp , fn _ , % { create_article: article } ->
168+ ORM . update ( article , % { active_at: article . inserted_at } )
169+ end )
145170 |> Multi . run ( :update_community_article_count , fn _ , _ ->
146171 CommunityCURD . update_community_count_field ( community , thread )
147172 end )
@@ -156,7 +181,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
156181 Statistics . log_publish_action ( % User { id: uid } )
157182 end )
158183 |> Repo . transaction ( )
159- |> create_article_result ( )
184+ |> result ( )
160185 end
161186 end
162187
@@ -199,6 +224,55 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
199224 |> result ( )
200225 end
201226
227+ @ doc """
228+ update active at timestamp of an article
229+ """
230+ def update_active_timestamp ( thread , article ) do
231+ # @article_active_period
232+ # 1. 超过时限不更新
233+ # 2. 已经沉默的不更新, is_sinked
234+ with true <- in_active_period? ( thread , article ) do
235+ ORM . update ( article , % { active_at: DateTime . utc_now ( ) } )
236+ else
237+ _ -> { :ok , :pass }
238+ end
239+ end
240+
241+ @ doc """
242+ sink article
243+ """
244+ def sink_article ( thread , id ) do
245+ with { :ok , info } <- match ( thread ) ,
246+ { :ok , article } <- ORM . find ( info . model , id ) do
247+ meta = Map . merge ( article . meta , % { is_sinked: true , last_active_at: article . active_at } )
248+ ORM . update_meta ( article , meta , changes: % { active_at: article . inserted_at } )
249+ end
250+ end
251+
252+ @ doc """
253+ undo sink article
254+ """
255+ def undo_sink_article ( thread , id ) do
256+ with { :ok , info } <- match ( thread ) ,
257+ { :ok , article } <- ORM . find ( info . model , id ) ,
258+ true <- in_active_period? ( thread , article ) do
259+ meta = Map . merge ( article . meta , % { is_sinked: false } )
260+ ORM . update_meta ( article , meta , changes: % { active_at: meta . last_active_at } )
261+ else
262+ false -> raise_error ( :undo_sink_old_article , "can not undo sink old article" )
263+ end
264+ end
265+
266+ # check is an article's active_at is in active period
267+ defp in_active_period? ( thread , article ) do
268+ active_period_days = Map . get ( @ active_period , thread )
269+
270+ inserted_at = article . inserted_at
271+ active_threshold = Timex . shift ( Timex . now ( ) , days: - active_period_days )
272+
273+ :gt == DateTime . compare ( inserted_at , active_threshold )
274+ end
275+
202276 @ doc """
203277 mark delete falst for an anticle
204278 """
@@ -300,7 +374,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
300374 defp add_pin_articles_ifneed ( articles , _querable , _filter ) , do: articles
301375
302376 # if filter contains like: tags, sort.., then don't add pin article
303- defp should_add_pin? ( % { page: 1 , sort: :desc_inserted } = filter ) do
377+ defp should_add_pin? ( % { page: 1 , sort: :desc_active } = filter ) do
304378 skip_pinned_fields = [ :article_tag , :article_tags ]
305379
306380 not Enum . any? ( Map . keys ( filter ) , & ( & 1 in skip_pinned_fields ) )
@@ -331,35 +405,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
331405 |> Map . put ( :total_count , normal_count )
332406 end
333407
334- defp create_article_result ( { :ok , % { create_article: result } } ) do
335- Later . exec ( { __MODULE__ , :notify_admin_new_article , [ result ] } )
336- { :ok , result }
337- end
338-
339- defp create_article_result ( { :error , :create_article , % Ecto.Changeset { } = result , _steps } ) do
340- { :error , result }
341- end
342-
343- defp create_article_result ( { :error , :create_article , _result , _steps } ) do
344- { :error , [ message: "create cms article author" , code: ecode ( :create_fails ) ] }
345- end
346-
347- defp create_article_result ( { :error , :mirror_article , _result , _steps } ) do
348- { :error , [ message: "set community" , code: ecode ( :create_fails ) ] }
349- end
350-
351- defp create_article_result ( { :error , :set_community_flag , _result , _steps } ) do
352- { :error , [ message: "set community flag" , code: ecode ( :create_fails ) ] }
353- end
354-
355- defp create_article_result ( { :error , :set_article_tags , result , _steps } ) do
356- { :error , result }
357- end
358-
359- defp create_article_result ( { :error , :log_action , _result , _steps } ) do
360- { :error , [ message: "log action" , code: ecode ( :create_fails ) ] }
361- end
362-
363408 # for create artilce step in Multi.new
364409 defp do_create_article ( target , attrs , % Author { id: aid } , % Community { id: cid } ) do
365410 target
@@ -396,9 +441,32 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
396441 end
397442 end
398443
444+ # create done
445+ defp result ( { :ok , % { set_active_at_timestamp: result } } ) do
446+ Later . exec ( { __MODULE__ , :notify_admin_new_article , [ result ] } )
447+ { :ok , result }
448+ end
449+
399450 defp result ( { :ok , % { update_edit_status: result } } ) , do: { :ok , result }
400451 defp result ( { :ok , % { update_article: result } } ) , do: { :ok , result }
401452 defp result ( { :ok , % { set_viewer_has_states: result } } ) , do: result |> done ( )
453+ defp result ( { :ok , % { update_article_meta: result } } ) , do: { :ok , result }
454+
455+ defp result ( { :error , :create_article , _result , _steps } ) do
456+ { :error , [ message: "create cms article author" , code: ecode ( :create_fails ) ] }
457+ end
458+
459+ defp result ( { :error , :mirror_article , _result , _steps } ) do
460+ { :error , [ message: "set community" , code: ecode ( :create_fails ) ] }
461+ end
462+
463+ defp result ( { :error , :set_community_flag , _result , _steps } ) do
464+ { :error , [ message: "set community flag" , code: ecode ( :create_fails ) ] }
465+ end
466+
467+ defp result ( { :error , :log_action , _result , _steps } ) do
468+ { :error , [ message: "log action" , code: ecode ( :create_fails ) ] }
469+ end
402470
403471 defp result ( { :error , _ , result , _steps } ) , do: { :error , result }
404472end
0 commit comments