@@ -18,12 +18,14 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
18
18
19
19
alias Accounts.Model.User
20
20
alias CMS.Model . { Author , Community , PinnedArticle , Embeds }
21
+ alias CMS.Model.Repo , as: CMSRepo
21
22
22
23
alias CMS.Delegate . {
23
24
ArticleCommunity ,
24
25
CommentCurd ,
25
26
ArticleTag ,
26
27
CommunityCURD ,
28
+ Document ,
27
29
Hooks
28
30
}
29
31
@@ -32,6 +34,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
32
34
@ active_period get_config ( :article , :active_period_days )
33
35
@ default_emotions Embeds.ArticleEmotion . default_emotions ( )
34
36
@ default_article_meta Embeds.ArticleMeta . default_meta ( )
37
+ @ remove_article_hint "The content does not comply with the community norms"
35
38
36
39
@ doc """
37
40
read articles for un-logined user
@@ -40,7 +43,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
40
43
with { :ok , info } <- match ( thread ) do
41
44
Multi . new ( )
42
45
|> Multi . run ( :inc_views , fn _ , _ -> ORM . read ( info . model , id , inc: :views ) end )
43
- |> Multi . run ( :update_article_meta , fn _ , % { inc_views: article } ->
46
+ |> Multi . run ( :load_html , fn _ , % { inc_views: article } ->
47
+ article |> Repo . preload ( :document ) |> done
48
+ end )
49
+ |> Multi . run ( :update_article_meta , fn _ , % { load_html: article } ->
44
50
article_meta = ensure ( article . meta , @ default_article_meta )
45
51
meta = Map . merge ( article_meta , % { can_undo_sink: in_active_period? ( thread , article ) } )
46
52
@@ -57,17 +63,11 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
57
63
def read_article ( thread , id , % User { id: user_id } ) do
58
64
with { :ok , info } <- match ( thread ) do
59
65
Multi . new ( )
60
- |> Multi . run ( :inc_views , fn _ , _ -> ORM . read ( info . model , id , inc: :views ) end )
61
- |> Multi . run ( :update_article_meta , fn _ , % { inc_views: article } ->
62
- article_meta = ensure ( article . meta , @ default_article_meta )
63
- meta = Map . merge ( article_meta , % { can_undo_sink: in_active_period? ( thread , article ) } )
64
-
65
- ORM . update_meta ( article , meta )
66
- end )
67
- |> Multi . run ( :add_viewed_user , fn _ , % { inc_views: article } ->
66
+ |> Multi . run ( :normal_read , fn _ , _ -> read_article ( thread , id ) end )
67
+ |> Multi . run ( :add_viewed_user , fn _ , % { normal_read: article } ->
68
68
update_viewed_user_list ( article , user_id )
69
69
end )
70
- |> Multi . run ( :set_viewer_has_states , fn _ , % { inc_views : article } ->
70
+ |> Multi . run ( :set_viewer_has_states , fn _ , % { normal_read : article } ->
71
71
article_meta = if is_nil ( article . meta ) , do: @ default_article_meta , else: article . meta
72
72
73
73
viewer_has_states = % {
@@ -76,7 +76,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
76
76
viewer_has_reported: user_id in article_meta . reported_user_ids
77
77
}
78
78
79
- { :ok , Map . merge ( article , viewer_has_states ) }
79
+ article |> Map . merge ( viewer_has_states ) |> done
80
80
end )
81
81
|> Repo . transaction ( )
82
82
|> result ( )
@@ -156,6 +156,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
156
156
|> Multi . run ( :create_article , fn _ , _ ->
157
157
do_create_article ( info . model , attrs , author , community )
158
158
end )
159
+ |> Multi . run ( :create_document , fn _ , % { create_article: article } ->
160
+ Document . create ( article , attrs )
161
+ end )
159
162
|> Multi . run ( :mirror_article , fn _ , % { create_article: article } ->
160
163
ArticleCommunity . mirror_article ( thread , article . id , community . id )
161
164
end )
@@ -211,14 +214,17 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
211
214
@ doc """
212
215
update a article(post/job ...)
213
216
"""
214
- def update_article ( article , args ) do
217
+ def update_article ( article , attrs ) do
215
218
Multi . new ( )
216
219
|> Multi . run ( :update_article , fn _ , _ ->
217
- do_update_article ( article , args )
220
+ do_update_article ( article , attrs )
221
+ end )
222
+ |> Multi . run ( :update_document , fn _ , % { update_article: update_article } ->
223
+ Document . update ( update_article , attrs )
218
224
end )
219
225
|> Multi . run ( :update_comment_question_flag_if_need , fn _ , % { update_article: update_article } ->
220
226
# 如果帖子的类型变了,那么 update 所有的 flag
221
- case Map . has_key? ( args , :is_question ) do
227
+ case Map . has_key? ( attrs , :is_question ) do
222
228
true -> CommentCurd . batch_update_question_flag ( update_article )
223
229
false -> { :ok , :pass }
224
230
end
@@ -319,6 +325,31 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
319
325
end
320
326
end
321
327
328
+ @ doc """
329
+ remove article forever
330
+ """
331
+ def remove_article ( thread , id , reason \\ @ remove_article_hint ) do
332
+ with { :ok , info } <- match ( thread ) ,
333
+ { :ok , article } <- ORM . find ( info . model , id , preload: [ :communities , [ author: :user ] ] ) do
334
+ Multi . new ( )
335
+ |> Multi . run ( :remove_article , fn _ , _ ->
336
+ article |> ORM . delete ( )
337
+ end )
338
+ |> Multi . run ( :update_community_article_count , fn _ , _ ->
339
+ CommunityCURD . update_community_count_field ( article . communities , thread )
340
+ end )
341
+ |> Multi . run ( :update_user_published_meta , fn _ , _ ->
342
+ Accounts . update_published_states ( article . author . user . id , thread )
343
+ end )
344
+ |> Multi . run ( :delete_document , fn _ , _ ->
345
+ Document . remove ( thread , id )
346
+ end )
347
+ # TODO: notify author
348
+ |> Repo . transaction ( )
349
+ |> result ( )
350
+ end
351
+ end
352
+
322
353
@ spec ensure_author_exists ( User . t ( ) ) :: { :ok , User . t ( ) }
323
354
def ensure_author_exists ( % User { } = user ) do
324
355
# unique_constraint: avoid race conditions, make sure user_id unique
@@ -392,13 +423,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
392
423
end
393
424
394
425
# for create artilce step in Multi.new
395
- defp do_create_article ( model , attrs , % Author { id: author_id } , % Community { id: community_id } ) do
396
- # special article like Repo do not have :body, assign it with default-empty rich text
397
- body = Map . get ( attrs , :body , Converter.Article . default_rich_text ( ) )
426
+ defp do_create_article ( model , % { body: _body } = attrs , % Author { id: author_id } , % Community {
427
+ id: community_id
428
+ } ) do
398
429
meta = @ default_article_meta |> Map . merge ( % { thread: module_to_upcase ( model ) } )
399
- attrs = attrs |> Map . merge ( % { body: body } )
400
430
401
- with { :ok , attrs } <- add_rich_text_attrs ( attrs ) do
431
+ with { :ok , attrs } <- add_digest_attrs ( attrs ) do
402
432
model . __struct__
403
433
|> model . changeset ( attrs )
404
434
|> Ecto.Changeset . put_change ( :emotions , @ default_emotions )
@@ -409,26 +439,35 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
409
439
end
410
440
end
411
441
442
+ # Github Repo 没有传统的 body, 需要特殊处理
443
+ # 赋值一个空的 body, 后续在 document 中处理
444
+ # 注意:digest 那里也要特殊处理
445
+ defp do_create_article ( CMSRepo , attrs , author , community ) do
446
+ body = Map . get ( attrs , :body , Converter.Article . default_rich_text ( ) )
447
+ attrs = Map . put ( attrs , :body , body )
448
+
449
+ do_create_article ( CMSRepo , attrs , author , community )
450
+ end
451
+
412
452
defp do_update_article ( article , % { body: _ } = attrs ) do
413
- with { :ok , attrs } <- add_rich_text_attrs ( attrs ) do
453
+ with { :ok , attrs } <- add_digest_attrs ( attrs ) do
414
454
ORM . update ( article , attrs )
415
455
end
416
456
end
417
457
418
458
defp do_update_article ( article , attrs ) , do: ORM . update ( article , attrs )
419
459
420
460
# is update or create article with body field, parsed and extand it into attrs
421
- defp add_rich_text_attrs ( % { body: body } = attrs ) when not is_nil ( body ) do
461
+ defp add_digest_attrs ( % { body: body } = attrs ) when not is_nil ( body ) do
422
462
with { :ok , parsed } <- Converter.Article . parse_body ( body ) ,
423
463
{ :ok , digest } <- Converter.Article . parse_digest ( parsed . body_map ) do
424
464
attrs
425
- |> Map . merge ( Map . take ( parsed , [ :body , :body_html ] ) )
426
465
|> Map . merge ( % { digest: digest } )
427
466
|> done
428
467
end
429
468
end
430
469
431
- defp add_rich_text_attrs ( attrs ) , do: attrs
470
+ defp add_digest_attrs ( attrs ) , do: attrs
432
471
433
472
defp update_viewed_user_list ( % { meta: nil } = article , user_id ) do
434
473
new_ids = Enum . uniq ( [ user_id ] ++ @ default_article_meta . viewed_user_ids )
@@ -458,6 +497,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
458
497
459
498
defp result ( { :ok , % { update_edit_status: result } } ) , do: { :ok , result }
460
499
defp result ( { :ok , % { update_article: result } } ) , do: { :ok , result }
500
+ defp result ( { :ok , % { remove_article: result } } ) , do: { :ok , result }
461
501
# NOTE: for read article, order is import
462
502
defp result ( { :ok , % { set_viewer_has_states: result } } ) , do: result |> done ( )
463
503
defp result ( { :ok , % { update_article_meta: result } } ) , do: { :ok , result }
0 commit comments