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

refactor(editor-workflow): re-org workflow with article & comment CURD & test #395

Merged
merged 31 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
b37255d
refactor(editor-workflow): editor parse wip
mydearxym Jun 8, 2021
f8936b7
refactor(editor-workflow): editor parse test fix
mydearxym Jun 9, 2021
dcead01
refactor(editor-workflow): editor parse test list case
mydearxym Jun 9, 2021
ed422a4
refactor(editor-workflow): add body_html to all articles
mydearxym Jun 9, 2021
2bb6c9e
refactor(editor-workflow): adjust body fields to article_comments
mydearxym Jun 9, 2021
c28990c
refactor(editor-workflow): fix body field when create comment
mydearxym Jun 9, 2021
afb064f
refactor(editor-workflow): fix body field when create comment wip
mydearxym Jun 9, 2021
396b251
refactor(editor-workflow): wip
mydearxym Jun 9, 2021
297aa54
refactor(editor-workflow): post digest workflow
mydearxym Jun 9, 2021
6b84dee
refactor(editor-workflow): article create workflow
mydearxym Jun 9, 2021
e3d3d8e
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
a6e21f2
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
d7be2dc
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
01a79da
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
e6b5c0e
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
6a1883d
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
66c3dd8
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
43e926a
refactor(editor-workflow): rich test for comment test wip
mydearxym Jun 9, 2021
1887db9
refactor(editor-workflow): fix comment test
mydearxym Jun 9, 2021
fa9a36c
refactor(editor-workflow): fix comment test
mydearxym Jun 9, 2021
79ad4b9
refactor(editor-workflow): fix comment test
mydearxym Jun 9, 2021
1d30730
refactor(editor-workflow): fix comment test
mydearxym Jun 9, 2021
0197eab
refactor(editor-workflow): fix comment test wip
mydearxym Jun 9, 2021
254a421
refactor(editor-workflow): fix comment test wip
mydearxym Jun 10, 2021
d6b48e5
chore: clean up
mydearxym Jun 10, 2021
a4d979d
test(comment): body refactor wip
mydearxym Jun 10, 2021
5ff746b
test(article): body parse & test adjust
mydearxym Jun 10, 2021
93c757e
test(article): body parse & test adjust
mydearxym Jun 10, 2021
95f7b87
test(article): body parse & test adjust
mydearxym Jun 10, 2021
8d4c8fd
test(article): fix test
mydearxym Jun 10, 2021
b639ecf
test(article): fix test
mydearxym Jun 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ config :groupher_server, :article,
:confused,
:pill,
:popcorn
]
],
digest_length: 120

config :groupher_server, GroupherServerWeb.Gettext, default_locale: "zh_CN", locales: ~w(en zh_CN)

Expand Down
78 changes: 42 additions & 36 deletions lib/groupher_server/cms/delegates/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
import ShortMaps

alias Helper.Types, as: T
alias Helper.{ORM, QueryBuilder}
alias Helper.{ORM, QueryBuilder, Converter}
alias GroupherServer.{Accounts, CMS, Repo}
alias CMS.Model.Post

Expand Down Expand Up @@ -92,13 +92,13 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
@doc """
creates a comment for article like psot, job ...
"""
def create_article_comment(thread, article_id, content, %User{} = user) do
def create_article_comment(thread, article_id, body, %User{} = user) do
with {:ok, info} <- match(thread),
{:ok, article} <- ORM.find(info.model, article_id, preload: [author: :user]),
true <- can_comment?(article, user) do
Multi.new()
|> Multi.run(:create_article_comment, fn _, _ ->
do_create_comment(content, info.foreign_key, article, user)
do_create_comment(body, info.foreign_key, article, user)
end)
|> Multi.run(:update_article_comments_count, fn _, %{create_article_comment: comment} ->
update_article_comments_count(comment, :inc)
Expand Down Expand Up @@ -133,15 +133,20 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
update a comment for article like psot, job ...
"""
# 如果是 solution, 那么要更新对应的 post 的 solution_digest
def update_article_comment(%ArticleComment{is_solution: true} = article_comment, content) do
with {:ok, post} <- ORM.find(Post, article_comment.post_id) do
post |> ORM.update(%{solution_digest: content})
article_comment |> ORM.update(%{body_html: content})
def update_article_comment(%ArticleComment{is_solution: true} = article_comment, body) do
with {:ok, post} <- ORM.find(Post, article_comment.post_id),
{:ok, parsed} <- Converter.Article.parse_body(body),
{:ok, digest} <- Converter.Article.parse_digest(parsed.body_map) do
%{body: body, body_html: body_html} = parsed
post |> ORM.update(%{solution_digest: digest})
article_comment |> ORM.update(%{body: body, body_html: body_html})
end
end

def update_article_comment(%ArticleComment{} = article_comment, content) do
article_comment |> ORM.update(%{body_html: content})
def update_article_comment(%ArticleComment{} = article_comment, body) do
with {:ok, %{body: body, body_html: body_html}} <- Converter.Article.parse_body(body) do
article_comment |> ORM.update(%{body: body, body_html: body_html})
end
end

@doc """
Expand Down Expand Up @@ -216,7 +221,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
|> result()
end

# add participator to article-like content (Post, Job ...) and update count
# add participator to article-like(Post, Job ...) and update count
def add_participator_to_article(
%{article_comments_participators: article_comments_participators} = article,
%User{} = user
Expand Down Expand Up @@ -255,32 +260,27 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
end
end

# creat article comment for parent or reply
# set floor
# TODO: parse editor-json
# set default emotions
def do_create_comment(content, foreign_key, article, %User{id: user_id}) do
thread = foreign_key |> to_string |> String.split("_id") |> List.first() |> String.upcase()

count_query = from(c in ArticleComment, where: field(c, ^foreign_key) == ^article.id)
floor = Repo.aggregate(count_query, :count) + 1

ArticleComment
|> ORM.create(
Map.put(
%{
author_id: user_id,
body_html: content,
emotions: @default_emotions,
floor: floor,
is_article_author: user_id == article.author.user.id,
thread: thread,
meta: @default_comment_meta
},
foreign_key,
article.id
)
)
@doc """
create article comment for parent or reply
"""
def do_create_comment(body, foreign_key, article, %User{id: user_id}) do
with {:ok, %{body: body, body_html: body_html}} <- Converter.Article.parse_body(body) do
# e.g: :post_id -> "POST", :job_id -> "JOB"
thread = foreign_key |> to_string |> String.slice(0..-4) |> String.upcase()

attrs = %{
author_id: user_id,
body: body,
body_html: body_html,
emotions: @default_emotions,
floor: get_comment_floor(article, foreign_key),
is_article_author: user_id == article.author.user.id,
thread: thread,
meta: @default_comment_meta
}

ArticleComment |> ORM.create(Map.put(attrs, foreign_key, article.id))
end
end

defp do_paged_article_comment(thread, article_id, filters, where_query, user) do
Expand Down Expand Up @@ -398,6 +398,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
{:ok, :pass}
end

# get next floor under an article's comments list
defp get_comment_floor(article, foreign_key) do
count_query = from(c in ArticleComment, where: field(c, ^foreign_key) == ^article.id)
Repo.aggregate(count_query, :count) + 1
end

defp result({:ok, %{set_question_flag_ifneed: result}}), do: {:ok, result}
defp result({:ok, %{delete_article_comment: result}}), do: {:ok, result}
defp result({:ok, %{mark_solution: result}}), do: {:ok, result}
Expand Down
72 changes: 49 additions & 23 deletions lib/groupher_server/cms/delegates/article_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,13 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do

import GroupherServer.CMS.Helper.Matcher

import Helper.Utils,
only: [
done: 1,
pick_by: 2,
integerfy: 1,
strip_struct: 1,
module_to_atom: 1,
get_config: 2,
ensure: 2
]
import Helper.Utils, only: [done: 1, pick_by: 2, module_to_atom: 1, get_config: 2, ensure: 2]

import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 2]
import Helper.ErrorCode
import ShortMaps

alias Helper.{Later, ORM, QueryBuilder}
alias Helper.{Later, ORM, QueryBuilder, Converter}
alias GroupherServer.{Accounts, CMS, Delivery, Email, Repo, Statistics}

alias Accounts.Model.User
Expand Down Expand Up @@ -172,7 +163,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> Multi.run(:update_user_published_meta, fn _, _ ->
Accounts.update_published_states(uid, thread)
end)
# TODO: run mini tasks
|> Multi.run(:mention_users, fn _, %{create_article: article} ->
# article.body |> Jason.decode!() |> 各种小 task
Delivery.mention_from_content(community.raw, thread, article, attrs, %User{id: uid})
{:ok, :pass}
end)
Expand Down Expand Up @@ -213,7 +206,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
"""
def update_article(article, args) do
Multi.new()
|> Multi.run(:update_article, fn _, _ -> ORM.update(article, args) end)
|> Multi.run(:update_article, fn _, _ ->
do_update_article(article, args)
end)
|> Multi.run(:update_comment_question_flag_if_need, fn _, %{update_article: update_article} ->
# 如果帖子的类型变了,那么 update 所有的 flag
case Map.has_key?(args, :is_question) do
Expand Down Expand Up @@ -386,17 +381,43 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
end

# for create artilce step in Multi.new
defp do_create_article(target, attrs, %Author{id: aid}, %Community{id: cid}) do
target
|> struct()
|> target.changeset(attrs)
|> Ecto.Changeset.put_change(:emotions, @default_emotions)
|> Ecto.Changeset.put_change(:author_id, aid)
|> Ecto.Changeset.put_change(:original_community_id, integerfy(cid))
|> Ecto.Changeset.put_embed(:meta, @default_article_meta)
|> Repo.insert()
defp do_create_article(model, attrs, %Author{id: author_id}, %Community{id: community_id}) do
# special article like Repo do not have :body, assign it with default-empty rich text
body = Map.get(attrs, :body, Converter.Article.default_rich_text())
attrs = attrs |> Map.merge(%{body: body})

with {:ok, attrs} <- add_rich_text_attrs(attrs) do
model.__struct__
|> model.changeset(attrs)
|> Ecto.Changeset.put_change(:emotions, @default_emotions)
|> Ecto.Changeset.put_change(:author_id, author_id)
|> Ecto.Changeset.put_change(:original_community_id, community_id)
|> Ecto.Changeset.put_embed(:meta, @default_article_meta)
|> Repo.insert()
end
end

defp do_update_article(article, %{body: _} = attrs) do
with {:ok, attrs} <- add_rich_text_attrs(attrs) do
ORM.update(article, attrs)
end
end

defp do_update_article(article, attrs), do: ORM.update(article, attrs)

# is update or create article with body field, parsed and extand it into attrs
defp add_rich_text_attrs(%{body: body} = attrs) when not is_nil(body) do
with {:ok, parsed} <- Converter.Article.parse_body(body),
{:ok, digest} <- Converter.Article.parse_digest(parsed.body_map) do
attrs
|> Map.merge(Map.take(parsed, [:body, :body_html]))
|> Map.merge(%{digest: digest})
|> done
end
end

defp add_rich_text_attrs(attrs), do: attrs

# except Job, other article will just pass, should use set_article_tags function instead
# defp exec_update_tags(_, _tags_ids), do: {:ok, :pass}

Expand All @@ -413,7 +434,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
case Enum.empty?(meta.viewed_user_ids) or user_not_viewed do
true ->
new_ids = Enum.uniq([user_id] ++ meta.viewed_user_ids)
meta = meta |> Map.merge(%{viewed_user_ids: new_ids}) |> strip_struct
meta = meta |> Map.merge(%{viewed_user_ids: new_ids})
ORM.update_meta(article, meta)

false ->
Expand All @@ -429,11 +450,16 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do

defp result({:ok, %{update_edit_status: result}}), do: {:ok, result}
defp result({:ok, %{update_article: result}}), do: {:ok, result}
# NOTE: for read article, order is import
defp result({:ok, %{set_viewer_has_states: result}}), do: result |> done()
defp result({:ok, %{update_article_meta: result}}), do: {:ok, result}

defp result({:error, :create_article, _result, _steps}) do
{:error, [message: "create cms article author", code: ecode(:create_fails)]}
{:error, [message: "create article", code: ecode(:create_fails)]}
end

defp result({:error, :update_article, _result, _steps}) do
{:error, [message: "update article", code: ecode(:update_fails)]}
end

defp result({:error, :mirror_article, _result, _steps}) do
Expand Down
2 changes: 2 additions & 0 deletions lib/groupher_server/cms/helper/macros.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ defmodule GroupherServer.CMS.Helper.Macros do
def general_article_fields(:cast) do
[
:body,
:body_html,
:digest,
:original_community_id,
:article_comments_count,
Expand Down Expand Up @@ -187,6 +188,7 @@ defmodule GroupherServer.CMS.Helper.Macros do
quote do
field(:title, :string)
field(:body, :string)
field(:body_html, :string)
field(:digest, :string)

belongs_to(:author, Author)
Expand Down
7 changes: 4 additions & 3 deletions lib/groupher_server/cms/models/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ defmodule GroupherServer.CMS.Model.ArticleComment do
# alias Helper.HTML
@article_threads get_config(:article, :threads)

@required_fields ~w(body_html author_id)a
@optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question is_solution)a
@updatable_fields ~w(is_folded is_deleted floor upvotes_count is_pinned is_for_question is_solution)a
@required_fields ~w(body author_id)a
@optional_fields ~w(body_html reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question is_solution)a
@updatable_fields ~w(body_html is_folded is_deleted floor upvotes_count is_pinned is_for_question is_solution)a

@article_fields @article_threads |> Enum.map(&:"#{&1}_id")

Expand Down Expand Up @@ -52,6 +52,7 @@ defmodule GroupherServer.CMS.Model.ArticleComment do
belongs_to(:author, User, foreign_key: :author_id)

field(:thread, :string)
field(:body, :string)
field(:body_html, :string)
# 是否被折叠
field(:is_folded, :boolean, default: false)
Expand Down
16 changes: 8 additions & 8 deletions lib/groupher_server_web/resolvers/cms_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ defmodule GroupherServerWeb.Resolvers.CMS do
CMS.create_article(%Community{id: community_id}, thread, args, user)
end

def update_article(_root, %{passport_source: content} = args, _info) do
CMS.update_article(content, args)
def update_article(_root, %{passport_source: article} = args, _info) do
CMS.update_article(article, args)
end

def delete_article(_root, %{passport_source: content}, _info), do: ORM.delete(content)
Expand Down Expand Up @@ -294,22 +294,22 @@ defmodule GroupherServerWeb.Resolvers.CMS do
CMS.paged_article_comments_participators(thread, id, filter)
end

def create_article_comment(_root, ~m(thread id content)a, %{context: %{cur_user: user}}) do
CMS.create_article_comment(thread, id, content, user)
def create_article_comment(_root, ~m(thread id body)a, %{context: %{cur_user: user}}) do
CMS.create_article_comment(thread, id, body, user)
end

def update_article_comment(_root, ~m(content passport_source)a, _info) do
def update_article_comment(_root, ~m(body passport_source)a, _info) do
comment = passport_source
CMS.update_article_comment(comment, content)
CMS.update_article_comment(comment, body)
end

def delete_article_comment(_root, ~m(passport_source)a, _info) do
comment = passport_source
CMS.delete_article_comment(comment)
end

def reply_article_comment(_root, ~m(id content)a, %{context: %{cur_user: user}}) do
CMS.reply_article_comment(id, content, user)
def reply_article_comment(_root, ~m(id body)a, %{context: %{cur_user: user}}) do
CMS.reply_article_comment(id, body, user)
end

def upvote_article_comment(_root, ~m(id)a, %{context: %{cur_user: user}}) do
Expand Down
1 change: 1 addition & 0 deletions lib/groupher_server_web/schema/Helper/fields.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ defmodule GroupherServerWeb.Schema.Helper.Fields do
field(:id, :id)
field(:title, :string)
field(:body, :string)
field(:body_html, :string)
field(:digest, :string)
field(:views, :integer)
field(:is_pinned, :boolean)
Expand Down
4 changes: 1 addition & 3 deletions lib/groupher_server_web/schema/cms/cms_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:length, :integer)
field(:link_addr, :string)
field(:copy_right, :string)
field(:body, :string)

timestamp_fields(:article)
end
Expand All @@ -78,7 +77,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:length, :integer)
field(:link_addr, :string)
field(:copy_right, :string)
field(:body, :string)

timestamp_fields(:article)
end
Expand All @@ -91,7 +89,6 @@ defmodule GroupherServerWeb.Schema.CMS.Types do

field(:length, :integer)
field(:link_addr, :string)
# field(:body, :string)

timestamp_fields(:article)
end
Expand Down Expand Up @@ -259,6 +256,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do

object :article_comment_reply do
field(:id, :id)
field(:body, :string)
field(:body_html, :string)
field(:author, :user, resolve: dataloader(CMS, :author))
field(:floor, :integer)
Expand Down
Loading