Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

feat(comments): pined comments#322

Merged
mydearxym merged 3 commits intodevfrompined-comments
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
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
9 changes: 8 additions & 1 deletionlib/groupher_server/cms/article_comment.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,7 +20,7 @@ defmodule GroupherServer.CMS.ArticleComment do

@required_fields ~w(body_html author_id)a
@optional_fields ~w(post_id job_id reply_to_id replies_count is_folded is_reported is_deleted floor is_article_author)a
@updatable_fields ~w(is_folded is_reported is_deleted floor upvotes_count)a
@updatable_fields ~w(is_folded is_reported is_deleted floor upvotes_count is_pined)a

@max_participator_count 5
@max_parent_replies_count 3
Expand All@@ -32,6 +32,9 @@ defmodule GroupherServer.CMS.ArticleComment do
# 举报超过此数评论会被自动折叠
@report_threshold_for_fold 5

# 每篇文章最多含有置顶评论的条数
@pined_comment_limit 10

@doc "latest participators stores in article comment_participators field"
def max_participator_count(), do: @max_participator_count
@doc "latest replies stores in article_comment replies field, used for frontend display"
Expand All@@ -44,6 +47,7 @@ defmodule GroupherServer.CMS.ArticleComment do
def delete_hint(), do: @delete_hint

def report_threshold_for_fold, do: @report_threshold_for_fold
def pined_comment_limit, do: @pined_comment_limit

@type t :: %ArticleComment{}
schema "articles_comments" do
Expand All@@ -63,6 +67,9 @@ defmodule GroupherServer.CMS.ArticleComment do
field(:is_article_author, :boolean, default: false)
field(:upvotes_count, :integer, default: 0)

# 是否置顶
field(:is_pined, :boolean, default: false)

belongs_to(:author, Accounts.User, foreign_key: :author_id)
belongs_to(:post, Post, foreign_key: :post_id)
belongs_to(:job, Job, foreign_key: :job_id)
Expand Down
44 changes: 44 additions & 0 deletionslib/groupher_server/cms/article_pined_comment.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
defmodule GroupherServer.CMS.ArticlePinedComment do
@moduledoc false
alias __MODULE__

use Ecto.Schema
use Accessible

import Ecto.Changeset

alias GroupherServer.CMS

alias CMS.{
Post,
Job,
ArticleComment
}

# alias Helper.HTML

@required_fields ~w(article_comment_id)a
@optional_fields ~w(post_id job_id)a

@type t :: %ArticlePinedComment{}
schema "articles_pined_comments" do
belongs_to(:article_comment, ArticleComment, foreign_key: :article_comment_id)
belongs_to(:post, Post, foreign_key: :post_id)
belongs_to(:job, Job, foreign_key: :job_id)

timestamps(type: :utc_datetime)
end

@doc false
def changeset(%ArticlePinedComment{} = article_pined_comment, attrs) do
article_pined_comment
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
end

# @doc false
def update_changeset(%ArticlePinedComment{} = article_pined_comment, attrs) do
article_pined_comment
|> cast(attrs, @required_fields ++ @updatable_fields)
end
end
3 changes: 3 additions & 0 deletionslib/groupher_server/cms/cms.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -129,6 +129,9 @@ defmodule GroupherServer.CMS do
defdelegate delete_article_comment(comment_id, user), to: ArticleComment
defdelegate reply_article_comment(comment_id, args, user), to: ArticleComment

defdelegate pin_article_comment(comment_id), to: ArticleComment
defdelegate undo_pin_article_comment(comment_id), to: ArticleComment

defdelegate make_emotion(comment_id, args, user), to: ArticleComment
defdelegate fold_article_comment(comment_id, user), to: ArticleComment
defdelegate unfold_article_comment(comment_id, user), to: ArticleComment
Expand Down
97 changes: 92 additions & 5 deletionslib/groupher_server/cms/delegates/article_comment.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,6 +16,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do

alias CMS.{
ArticleComment,
ArticlePinedComment,
ArticleCommentUpvote,
ArticleCommentReply,
ArticleCommentUserEmotion,
Expand All@@ -35,6 +36,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
@report_threshold_for_fold ArticleComment.report_threshold_for_fold()

@default_comment_meta Embeds.ArticleCommentMeta.default_meta()
@pined_comment_limit ArticleComment.pined_comment_limit()

@doc """
list paged article comments
Expand All@@ -43,9 +45,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
with {:ok, thread_query} <- match(thread, :query, article_id) do
ArticleComment
|> where(^thread_query)
|> where([c], c.is_folded == false and c.is_reported == false)
|> where([c], c.is_folded == false and c.is_reported == false and c.is_pined == false)
|> QueryBuilder.filter_pack(filters)
|> ORM.paginater(~m(page size)a)
|> add_pined_comments_ifneed(thread, article_id, filters)
|> done()
end
end
Expand All@@ -59,19 +62,53 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
with {:ok, thread_query} <- match(thread, :query, article_id) do
ArticleComment
|> where(^thread_query)
|> where([c], c.is_folded == false and c.is_reported == false)
|> where([c], c.is_folded == false and c.is_reported == false and c.is_pined == false)
|> QueryBuilder.filter_pack(filters)
|> ORM.paginater(~m(page size)a)
|> check_viewer_has_emotioned(user)
|> add_pined_comments_ifneed(thread, article_id, filters)
|> done()
end
end

# TODO: @pined_comment_limit 10
defp add_pined_comments_ifneed(%{entries: entries} = paged_comments, thread, article_id, %{
page: 1
}) do
with {:ok, info} <- match(thread),
query <-
from(p in ArticlePinedComment,
join: c in ArticleComment,
on: p.article_comment_id == c.id,
where: field(p, ^info.foreign_key) == ^article_id,
select: c
),
{:ok, pined_comments} <- query |> Repo.all() |> done() do
case pined_comments do
[] ->
paged_comments

_ ->
updated_entries =
Enum.concat(Enum.slice(pined_comments, 0, @pined_comment_limit), entries)

pined_comment_count = length(pined_comments)

Map.merge(paged_comments, %{
entries: updated_entries,
total_count: paged_comments.total_count + pined_comment_count
})
end
end
end

defp add_pined_comments_ifneed(paged_comments, _thread, _article_id, _), do: paged_comments

def list_folded_article_comments(thread, article_id, %{page: page, size: size} = filters) do
with {:ok, thread_query} <- match(thread, :query, article_id) do
ArticleComment
|> where(^thread_query)
|> where([c], c.is_folded == true and c.is_reported == false)
|> where([c], c.is_folded == true and c.is_reported == false and c.is_pined == false)
|> QueryBuilder.filter_pack(filters)
|> ORM.paginater(~m(page size)a)
|> done()
Expand All@@ -87,7 +124,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
with {:ok, thread_query} <- match(thread, :query, article_id) do
ArticleComment
|> where(^thread_query)
|> where([c], c.is_folded == true and c.is_reported == false)
|> where([c], c.is_folded == true and c.is_reported == false and c.is_pined == false)
|> QueryBuilder.filter_pack(filters)
|> ORM.paginater(~m(page size)a)
|> check_viewer_has_emotioned(user)
Expand DownExpand Up@@ -136,6 +173,55 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
|> done()
end

@doc "pin a comment"
def pin_article_comment(comment_id) do
with {:ok, comment} <- ORM.find(ArticleComment, comment_id),
{:ok, full_comment} <- get_full_comment(comment.id),
{:ok, info} <- match(full_comment.thread) do
Multi.new()
|> Multi.run(:checked_pined_comments_count, fn _, _ ->
count_query =
from(p in ArticlePinedComment,
where: field(p, ^info.foreign_key) == ^full_comment.article.id
)

pined_comments_count = Repo.aggregate(count_query, :count)

case pined_comments_count >= @pined_comment_limit do
true -> {:error, "only support #{@pined_comment_limit} pined comment for each article"}
false -> {:ok, :pass}
end
end)
|> Multi.run(:update_comment_flag, fn _, _ ->
ORM.update(comment, %{is_pined: true})
end)
|> Multi.run(:add_pined_comment, fn _, _ ->
ArticlePinedComment
|> ORM.create(
%{article_comment_id: comment.id}
|> Map.put(info.foreign_key, full_comment.article.id)
)
end)
|> Repo.transaction()
|> upsert_comment_result()
end
end

def undo_pin_article_comment(comment_id) do
with {:ok, comment} <- ORM.find(ArticleComment, comment_id) do
Multi.new()
|> Multi.run(:update_comment_flag, fn _, _ ->
ORM.update(comment, %{is_pined: false})
end)
|> Multi.run(:remove_pined_comment, fn _, _ ->
ORM.findby_delete(ArticlePinedComment, %{article_comment_id: comment.id})
end)
|> Repo.transaction()
|> upsert_comment_result()
end
end

# TODO: remove pined record if need
def delete_article_comment(comment_id, %User{} = _user) do
with {:ok, comment} <-
ORM.find(ArticleComment, comment_id) do
Expand DownExpand Up@@ -514,7 +600,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
with {:ok, article_with_author} <- Repo.preload(article, author: :user) |> done(),
article_author <- get_in(article_with_author, [:author, :user]) do
#
article_info = %{title: article.title}
article_info = %{title: article.title, id: article.id}

author_info = %{
id: article_author.id,
Expand All@@ -531,6 +617,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
defp upsert_comment_result({:ok, %{check_article_author_upvoted: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{update_report_flag: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{update_comment_emotion: result}}), do: {:ok, result}
defp upsert_comment_result({:ok, %{update_comment_flag: result}}), do: {:ok, result}

defp upsert_comment_result({:error, :create_comment, result, _steps}) do
{:error, result}
Expand Down
2 changes: 2 additions & 0 deletionslib/groupher_server/cms/post.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,7 @@ defmodule GroupherServer.CMS.Post do
Embeds,
Author,
ArticleComment,
ArticlePinedComment,
Community,
PostComment,
PostCommunityFlag,
Expand DownExpand Up@@ -58,6 +59,7 @@ defmodule GroupherServer.CMS.Post do
has_many(:comments, {"posts_comments", PostComment})

has_many(:article_comments, {"articles_comments", ArticleComment})
has_many(:article_pined_comments, {"articles_pined_comments", ArticlePinedComment})

has_many(:favorites, {"posts_favorites", PostFavorite})
has_many(:stars, {"posts_stars", PostStar})
Expand Down
3 changes: 3 additions & 0 deletionslib/helper/types.ex
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -29,6 +29,9 @@ defmodule Helper.Types do
}

@type article_thread :: :post | :job
@type article_common :: %{
title: String.t()
}
@type article_info :: %{
thread: article_thread,
article: %{
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
defmodule GroupherServer.Repo.Migrations.AddPinToArticleComments do
use Ecto.Migration

def change do
alter table(:articles_comments) do
add(:is_pined, :boolean, default: false)
end

create table(:articles_pined_comments) do
add(:post_id, references(:cms_posts, on_delete: :delete_all))
add(:job_id, references(:cms_jobs, on_delete: :delete_all))

add(:article_comment_id, references(:articles_comments, on_delete: :delete_all), null: false)

timestamps()
end

create(index(:articles_pined_comments, [:post_id]))
create(index(:articles_pined_comments, [:job_id]))
create(index(:articles_pined_comments, [:article_comment_id]))

create(unique_index(:articles_pined_comments, [:post_id, :job_id, :article_comment_id]))
end
end
Loading

[8]ページ先頭

©2009-2025 Movatter.jp