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

Commit 9f99109

Browse files
committed
feat(post-qa): only allows one best solution
1 parent 711fe57 commit 9f99109

File tree

6 files changed

+67
-20
lines changed

6 files changed

+67
-20
lines changed

lib/groupher_server/cms/article_comment.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ defmodule GroupherServer.CMS.ArticleComment do
1717
@article_threads get_config(:article, :threads)
1818

1919
@required_fields ~w(body_html author_id)a
20-
@optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question)a
21-
@updatable_fields ~w(is_folded is_deleted floor upvotes_count is_pinned is_for_question)a
20+
@optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author thread is_for_question is_solution)a
21+
@updatable_fields ~w(is_folded is_deleted floor upvotes_count is_pinned is_for_question is_solution)a
2222

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

@@ -58,7 +58,9 @@ defmodule GroupherServer.CMS.ArticleComment do
5858
field(:is_deleted, :boolean, default: false)
5959
# 楼层
6060
field(:floor, :integer, default: 0)
61+
6162
field(:is_for_question, :boolean, default: false)
63+
field(:is_solution, :boolean, default: false)
6264

6365
# 是否是评论文章的作者
6466
field(:is_article_author, :boolean, default: false)

lib/groupher_server/cms/delegates/article_comment.ex

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,27 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
140140
end
141141

142142
def mark_comment_solution(article_comment_id, user) do
143-
do_mark_comment_solution(article_comment_id, user, true)
143+
with {:ok, article_comment} <- ORM.find(ArticleComment, article_comment_id),
144+
{:ok, post} <- ORM.find(CMS.Post, article_comment.post_id, preload: [author: :user]) do
145+
# 确保只有一个最佳答案
146+
batch_update_solution_flag(post, false)
147+
do_mark_comment_solution(post, article_comment, user, true)
148+
end
144149
end
145150

146151
def undo_mark_comment_solution(article_comment_id, user) do
147-
do_mark_comment_solution(article_comment_id, user, false)
152+
with {:ok, article_comment} <- ORM.find(ArticleComment, article_comment_id),
153+
{:ok, post} <- ORM.find(CMS.Post, article_comment.post_id, preload: [author: :user]) do
154+
do_mark_comment_solution(post, article_comment, user, false)
155+
end
148156
end
149157

150-
defp do_mark_comment_solution(article_comment_id, user, is_solution) do
151-
with {:ok, article_comment} <- ORM.find(ArticleComment, article_comment_id),
152-
{:ok, post} <- ORM.find(CMS.Post, article_comment.post_id, preload: [author: :user]),
153-
# check if user is questioner
154-
true <- user.id == post.author.user.id do
158+
defp do_mark_comment_solution(post, %ArticleComment{} = article_comment, user, is_solution) do
159+
# check if user is questioner
160+
with true <- user.id == post.author.user.id do
155161
Multi.new()
156162
|> Multi.run(:mark_solution, fn _, _ ->
157-
meta = article_comment.meta |> Map.merge(%{is_solution: is_solution})
158-
ORM.update_meta(article_comment, meta)
163+
ORM.update(article_comment, %{is_solution: is_solution})
159164
end)
160165
|> Multi.run(:update_post_state, fn _, _ ->
161166
ORM.update(post, %{is_solved: is_solution, solution_digest: article_comment.body_html})
@@ -348,6 +353,17 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
348353

349354
defp set_question_flag_ifneed(_, comment), do: ORM.update(comment, %{is_for_question: false})
350355

356+
# batch update is_solution flag for artilce comment
357+
defp batch_update_solution_flag(%CMS.Post{} = post, is_question) do
358+
from(c in ArticleComment,
359+
where: c.post_id == ^post.id,
360+
update: [set: [is_solution: ^is_question]]
361+
)
362+
|> Repo.update_all([])
363+
364+
{:ok, :pass}
365+
end
366+
351367
defp result({:ok, %{set_question_flag_ifneed: result}}), do: {:ok, result}
352368
defp result({:ok, %{delete_article_comment: result}}), do: {:ok, result}
353369
defp result({:ok, %{mark_solution: result}}), do: {:ok, result}

lib/groupher_server/cms/embeds/article_comment_meta.ex

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule GroupherServer.CMS.Embeds.ArticleCommentMeta do
77

88
import Ecto.Changeset
99

10-
@optional_fields ~w(is_article_author_upvoted report_count is_reply_to_others reported_count reported_user_ids is_solution)a
10+
@optional_fields ~w(is_article_author_upvoted report_count is_reply_to_others reported_count reported_user_ids)a
1111

1212
@doc "for test usage"
1313
def default_meta() do
@@ -17,8 +17,7 @@ defmodule GroupherServer.CMS.Embeds.ArticleCommentMeta do
1717
report_count: 0,
1818
upvoted_user_ids: [],
1919
reported_user_ids: [],
20-
reported_count: 0,
21-
is_solution: false
20+
reported_count: 0
2221
}
2322
end
2423

@@ -32,8 +31,6 @@ defmodule GroupherServer.CMS.Embeds.ArticleCommentMeta do
3231
field(:upvoted_user_ids, {:array, :integer}, default: [])
3332
field(:reported_user_ids, {:array, :integer}, default: [])
3433
field(:reported_count, :integer, default: 0)
35-
36-
field(:is_solution, :boolean, default: false)
3734
end
3835

3936
def changeset(struct, params) do

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(:already_solved), do: @article_base + 10
5455

5556
def ecode, do: @default_base
5657
# def ecode(_), do: @default_base
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
defmodule GroupherServer.Repo.Migrations.AddSolutionDigestToComment do
2+
use Ecto.Migration
3+
4+
def change do
5+
alter table(:articles_comments) do
6+
add(:is_solution, :boolean, default: false)
7+
end
8+
end
9+
end

test/groupher_server/cms/comments/post_comment_test.exs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do
55
import Helper.Utils, only: [get_config: 2]
66

77
alias Helper.ORM
8-
alias GroupherServer.{Accounts, CMS}
8+
alias GroupherServer.{Accounts, CMS, Repo}
99

1010
alias CMS.{ArticleComment, ArticlePinnedComment, Embeds, Post}
1111

@@ -677,7 +677,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do
677677
{:ok, post_comment} = CMS.create_article_comment(:post, post.id, "comment", user)
678678

679679
assert not post_comment.is_for_question
680-
assert not post_comment.meta.is_solution
680+
assert not post_comment.is_solution
681681
end
682682

683683
@tag :wip2
@@ -725,7 +725,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do
725725
{:ok, comment} = CMS.create_article_comment(:post, post.id, "comment", post_author)
726726
{:ok, comment} = CMS.mark_comment_solution(comment.id, post_author)
727727

728-
assert comment.meta.is_solution
728+
assert comment.is_solution
729729

730730
{:ok, post} = ORM.find(Post, post.id)
731731
assert post.is_solved
@@ -759,7 +759,7 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do
759759

760760
{:ok, comment} = CMS.undo_mark_comment_solution(comment.id, post_author)
761761

762-
assert not comment.meta.is_solution
762+
assert not comment.is_solution
763763

764764
{:ok, post} = ORM.find(Post, post.id)
765765
assert not post.is_solved
@@ -779,5 +779,27 @@ defmodule GroupherServer.Test.CMS.Comments.PostComment do
779779

780780
reason |> is_error?(:require_questioner)
781781
end
782+
783+
@tag :wip
784+
test "can only mark one best comment as solution", ~m(user community)a do
785+
post_attrs = mock_attrs(:post, %{community_id: community.id, is_question: true})
786+
{:ok, post} = CMS.create_article(community, :post, post_attrs, user)
787+
788+
{:ok, post} = ORM.find(Post, post.id, preload: [author: :user])
789+
post_author = post.author.user
790+
791+
{:ok, comment1} = CMS.create_article_comment(:post, post.id, "comment", post_author)
792+
{:ok, comment2} = CMS.create_article_comment(:post, post.id, "comment", post_author)
793+
794+
{:ok, _comment} = CMS.mark_comment_solution(comment1.id, post_author)
795+
{:ok, comment2} = CMS.mark_comment_solution(comment2.id, post_author)
796+
797+
answers =
798+
from(c in ArticleComment, where: c.post_id == ^post.id and c.is_solution == true)
799+
|> Repo.all()
800+
801+
assert answers |> length == 1
802+
assert answers |> List.first() |> Map.get(:id) == comment2.id
803+
end
782804
end
783805
end

0 commit comments

Comments
 (0)