@@ -3,14 +3,16 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
33 run tasks in every article blocks if need
44 """
55 import Ecto.Query , warn: false
6- import Helper.Utils , only: [ get_config: 2 ]
6+ import Helper.Utils , only: [ get_config: 2 , thread_of_article: 1 , done: 1 ]
77 import GroupherServer.CMS.Helper.Matcher
8+ import Helper.ErrorCode
89
9- alias GroupherServer.Repo
10-
11- alias GroupherServer.CMS.Model.CitedContent
10+ alias GroupherServer . { CMS , Repo }
11+ alias CMS.Model.CitedContent
1212 alias Helper.ORM
1313
14+ alias Ecto.Multi
15+
1416 @ site_host get_config ( :general , :site_host )
1517 @ article_threads get_config ( :article , :threads )
1618 @ valid_article_prefix Enum . map ( @ article_threads , & "#{ @ site_host } /#{ & 1 } /" )
@@ -42,60 +44,64 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
4244 defp run_tasks ( :cite , article , blocks ) do
4345 article = article |> Repo . preload ( author: :user )
4446
45- blocks
46- |> Enum . reduce ( [ ] , & ( & 2 ++ get_cited_contents_per_block ( article , & 1 ) ) )
47- |> merge_same_cited_article_block
48- |> update_cited_info
47+ Multi . new ( )
48+ |> Multi . run ( :delete_all_cited_contents , fn _ , _ ->
49+ delete_all_cited_contents ( article )
50+ end )
51+ |> Multi . run ( :update_cited_info , fn _ , _ ->
52+ blocks
53+ |> Enum . reduce ( [ ] , & ( & 2 ++ parse_cited_info_per_block ( article , & 1 ) ) )
54+ |> merge_same_cited_article_block
55+ |> update_cited_info
56+ end )
57+ |> Repo . transaction ( )
58+ |> result ( )
59+ end
60+
61+ # delete all records before insert_all, this will dynamiclly update
62+ # those cited info when update article
63+ # 插入引用记录之前先全部清除,这样可以在更新文章的时候自动计算引用信息
64+ defp delete_all_cited_contents ( article ) do
65+ with { :ok , thread } <- thread_of_article ( article ) ,
66+ { :ok , info } <- match ( thread ) do
67+ query = from ( c in CitedContent , where: field ( c , ^ info . foreign_key ) == ^ article . id )
68+
69+ ORM . delete_all ( query , :if_exist )
70+ end
4971 end
5072
73+ # defp batch_done
74+
5175 defp update_cited_info ( cited_contents ) do
52- # batch update CitedContent List
53- cited_contents_fields = [ :cited_by_id , :cited_by_type , :block_linker , :user_id ]
54- clean_cited_contents = Enum . map ( cited_contents , & Map . take ( & 1 , cited_contents_fields ) )
76+ clean_cited_contents = Enum . map ( cited_contents , & Map . delete ( & 1 , :cited_article ) )
5577 IO . inspect ( clean_cited_contents , label: "clean_cited_contents" )
56- Repo . insert_all ( CitedContent , clean_cited_contents )
5778
58- # update citting count meta
59- update_citing_count ( cited_contents )
79+ with true <- { 0 , nil } !== Repo . insert_all ( CitedContent , clean_cited_contents ) do
80+ update_citing_count ( cited_contents )
81+ else
82+ _ -> { :error , "insert cited content error" }
83+ end
6084 end
6185
6286 defp update_citing_count ( cited_contents ) do
63- Enum . each ( cited_contents , fn content ->
87+ Enum . all? ( cited_contents , fn content ->
6488 count_query = from ( c in CitedContent , where: c . cited_by_id == ^ content . cited_by_id )
6589 count = Repo . aggregate ( count_query , :count )
6690
6791 cited_article = content . cited_article
6892 meta = Map . merge ( cited_article . meta , % { citing_count: count } )
69- cited_article |> ORM . update_meta ( meta )
93+
94+ case cited_article |> ORM . update_meta ( meta ) do
95+ { :ok , _ } -> true
96+ { :error , _ } -> false
97+ end
7098 end )
99+ |> done
71100 end
72101
73102 @ doc """
103+ merge same cited article in different blocks
74104 e.g:
75- [
76- %{
77- block_linker: ["block-zByQI"],
78- cited_by_id: 190058,
79- cited_by_type: "POST",
80- post_id: 190059,
81- user_id: 1413053
82- },
83- %{
84- block_linker: ["block-zByQI"],
85- cited_by_id: 190057,
86- cited_by_type: "POST",
87- post_id: 190059,
88- user_id: 1413053
89- },
90- %{
91- block_linker: ["block-ZgKJs"],
92- cited_by_id: 190057,
93- cited_by_type: "POST",
94- post_id: 190059,
95- user_id: 1413053
96- }
97- ]
98- into:
99105 [
100106 %{
101107 block_linker: ["block-zByQI"],
@@ -144,7 +150,7 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
144150 ...
145151 ]
146152 """
147- defp get_cited_contents_per_block ( article , % {
153+ defp parse_cited_info_per_block ( article , % {
148154 "id" => block_id ,
149155 "data" => % { "text" => text }
150156 } ) do
@@ -162,12 +168,13 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
162168 end
163169
164170 defp shape_cited_content ( article , cited_article , block_id ) do
165- thread = article . meta . thread |> String . downcase ( ) |> String . to_atom ( )
171+ { :ok , thread } = thread_of_article ( article )
166172 { :ok , info } = match ( thread )
167173
168174 % {
169175 cited_by_id: cited_article . id ,
170176 cited_by_type: cited_article . meta . thread ,
177+ # used for updating citing_count, avoid load again
171178 cited_article: cited_article ,
172179 block_linker: [ block_id ] ,
173180 user_id: article . author . user . id
@@ -214,4 +221,10 @@ defmodule GroupherServer.CMS.Delegate.BlockTasks do
214221 ORM . find ( info . model , article_id )
215222 end
216223 end
224+
225+ defp result ( { :ok , % { update_cited_info: result } } ) , do: { :ok , result }
226+
227+ defp result ( { :error , :update_cited_info , _result , _steps } ) do
228+ { :error , [ message: "cited article" , code: ecode ( :cite_artilce ) ] }
229+ end
217230end
0 commit comments