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

Commit e8384e7

Browse files
committed
refactor(cited-article): wip
1 parent f173b09 commit e8384e7

File tree

4 files changed

+75
-42
lines changed

4 files changed

+75
-42
lines changed

lib/groupher_server/cms/delegates/block_tasks.ex

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -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
217230
end

lib/helper/error_code.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ defmodule Helper.ErrorCode do
5151
def ecode(:undo_sink_old_article), do: @article_base + 7
5252
def ecode(:article_comment_locked), do: @article_base + 8
5353
def ecode(:require_questioner), do: @article_base + 9
54+
def ecode(:cite_artilce), do: @article_base + 10
5455
# def ecode(:already_solved), do: @article_base + 10
5556

5657
def ecode, do: @default_base

lib/helper/orm.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,16 @@ defmodule Helper.ORM do
173173
end
174174
end
175175

176+
@doc """
177+
delete all queryable if exist
178+
"""
179+
def delete_all(queryable, :if_exist) do
180+
case Repo.exists?(query) do
181+
true -> {:ok, Repo.delete_all(query)}
182+
false -> {:ok, :pass}
183+
end
184+
end
185+
176186
def findby_or_insert(queryable, clauses, attrs) do
177187
case queryable |> find_by(clauses) do
178188
{:ok, content} ->

lib/helper/utils/utils.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ defmodule Helper.Utils do
5555
@doc """
5656
handle General {:ok, ..} or {:error, ..} return
5757
"""
58+
def done(false), do: {:error, false}
59+
def done(true), do: {:ok, true}
5860
def done(nil, :boolean), do: {:ok, false}
5961
def done(_, :boolean), do: {:ok, true}
6062
def done(nil, err_msg), do: {:error, err_msg}
@@ -208,6 +210,13 @@ defmodule Helper.Utils do
208210
end
209211
end
210212

213+
# get thread of article
214+
def thread_of_article(%{meta: %{thread: thread}}) do
215+
thread |> String.downcase() |> String.to_atom() |> done
216+
end
217+
218+
def thread_of_article(_), do: {:error, "invalid article"}
219+
211220
def uid(str_len \\ 5) do
212221
Nanoid.generate(str_len, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
213222
end

0 commit comments

Comments
 (0)