Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion lib/groupher_server/accounts/accounts.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ defmodule GroupherServer.Accounts do
# defdelegate paged_editable_communities(filter), to: Achievements

# publish
defdelegate published_contents(user, thread, filter), to: Publish
defdelegate paged_published_articles(user, thread, filter), to: Publish
defdelegate published_comments(user, thread, filter), to: Publish
defdelegate paged_published_article_comments(user, thread, filter), to: Publish
defdelegate paged_published_article_comments(user, thread), to: Publish
defdelegate update_published_states(user, thread), to: Publish

# fans
defdelegate follow(user, follower), to: Fans
Expand Down
81 changes: 70 additions & 11 deletions lib/groupher_server/accounts/delegates/publish.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,89 @@ defmodule GroupherServer.Accounts.Delegate.Publish do
user followers / following related
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [done: 1]
import Helper.Utils, only: [done: 1, ensure: 2]
# import Helper.ErrorCode
import ShortMaps

import GroupherServer.CMS.Helper.Matcher
import GroupherServer.CMS.Helper.MatcherOld

alias GroupherServer.Accounts.{Embeds, User}
alias GroupherServer.CMS.ArticleComment
alias Helper.{ORM, QueryBuilder}
# alias GroupherServer.{Accounts, Repo}

alias GroupherServer.Accounts.User
# alias GroupherServer.CMS
@default_meta Embeds.UserMeta.default_meta()

@doc """
get paged published contets of a user
"""
def published_contents(%User{id: user_id}, thread, %{page: page, size: size} = filter) do
with {:ok, user} <- ORM.find(User, user_id),
{:ok, content} <- match_action(thread, :self) do
content.target
|> join(:inner, [content], author in assoc(content, :author))
|> where([content, author], author.user_id == ^user.id)
|> select([content, author], content)
def paged_published_articles(%User{id: user_id}, thread, filter) do
with {:ok, info} <- match(thread),
{:ok, user} <- ORM.find(User, user_id) do
do_paged_published_articles(info.model, user, filter)
end
end

@doc """
update published articles count in user meta
"""
def update_published_states(user_id, thread) do
filter = %{page: 1, size: 1}

with {:ok, info} <- match(thread),
{:ok, user} <- ORM.find(User, user_id),
{:ok, paged_published_articles} <- do_paged_published_articles(info.model, user, filter) do
articles_count = paged_published_articles.total_count

meta =
ensure(user.meta, @default_meta) |> Map.put(:"published_#{thread}s_count", articles_count)

ORM.update_meta(user, meta)
end
end

defp do_paged_published_articles(queryable, %User{} = user, %{page: page, size: size} = filter) do
queryable
|> join(:inner, [article], author in assoc(article, :author))
|> where([article, author], author.user_id == ^user.id)
|> select([article, author], article)
|> QueryBuilder.filter_pack(filter)
|> ORM.paginater(~m(page size)a)
|> done()
end

def paged_published_article_comments(%User{id: user_id}, %{page: page, size: size} = filter) do
with {:ok, user} <- ORM.find(User, user_id) do
ArticleComment
|> join(:inner, [comment], author in assoc(comment, :author))
|> where([comment, author], author.id == ^user.id)
|> QueryBuilder.filter_pack(filter)
|> ORM.paginater(~m(page size)a)
|> ORM.extract_and_assign_article()
|> done()
end
end

def paged_published_article_comments(
%User{id: user_id},
thread,
%{page: page, size: size} = filter
) do
with {:ok, user} <- ORM.find(User, user_id) do
thread = thread |> to_string |> String.upcase()
thread_atom = thread |> String.downcase() |> String.to_atom()

# article_preload = Keyword.new([{thread_atom, :author}])
# query = from(comment in ArticleComment, preload: ^article_preload)
query = from(comment in ArticleComment, preload: ^thread_atom)

query
|> join(:inner, [comment], author in assoc(comment, :author))
|> where([comment, author], author.id == ^user.id)
|> where([comment, author], comment.thread == ^thread)
|> QueryBuilder.filter_pack(filter)
|> ORM.paginater(~m(page size)a)
|> ORM.extract_and_assign_article()
|> done()
end
end
Expand Down
44 changes: 37 additions & 7 deletions lib/groupher_server/accounts/embeds/user_meta.ex
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
defmodule GroupherServer.Accounts.Embeds.UserMeta.Macro do
@moduledoc false

import Helper.Utils, only: [get_config: 2]

@article_threads get_config(:article, :article_threads)

defmacro published_article_count_fields() do
@article_threads
|> Enum.map(fn thread ->
quote do
field(unquote(:"published_#{thread}s_count"), :integer, default: 0)
end
end)
end
end

defmodule GroupherServer.Accounts.Embeds.UserMeta do
@moduledoc """
general article meta info for article-like content, like post, job, works ...
general article meta info for articles
"""
use Ecto.Schema
use Accessible

import Ecto.Changeset
import GroupherServer.Accounts.Embeds.UserMeta.Macro
import Helper.Utils, only: [get_config: 2]

@optional_fields ~w(reported_count follower_user_ids following_user_ids)a
@article_threads get_config(:article, :article_threads)

@default_meta %{
@general_options %{
reported_count: 0,
reported_user_ids: [],
follower_user_ids: [],
following_user_ids: []
}

@doc "for test usage"
def default_meta(), do: @default_meta
@optional_fields Map.keys(@general_options) ++
Enum.map(@article_threads, &:"published_#{&1}s_count")

def default_meta() do
published_article_counts =
@article_threads
|> Enum.reduce([], &(&2 ++ ["published_#{&1}s_count": 0]))
|> Enum.into(%{})

@general_options |> Map.merge(published_article_counts)
end

embedded_schema do
field(:reported_count, :integer, default: 0)
Expand All @@ -25,10 +54,11 @@ defmodule GroupherServer.Accounts.Embeds.UserMeta do
# TODO: 怎样处理历史数据 ?
field(:follower_user_ids, {:array, :integer}, default: [])
field(:following_user_ids, {:array, :integer}, default: [])

published_article_count_fields()
end

def changeset(struct, params) do
struct
|> cast(params, @optional_fields)
struct |> cast(params, @optional_fields)
end
end
5 changes: 2 additions & 3 deletions lib/groupher_server/cms/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ defmodule GroupherServer.CMS.ArticleComment do
@article_threads get_config(:article, :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)a
@optional_fields ~w(reply_to_id replies_count is_folded is_deleted floor is_article_author thread)a
@updatable_fields ~w(is_folded is_deleted floor upvotes_count is_pinned)a

@article_fields @article_threads |> Enum.map(&:"#{&1}_id")
Expand All @@ -41,8 +41,6 @@ defmodule GroupherServer.CMS.ArticleComment do

@doc "操作某 emotion 的最近用户"
def max_latest_emotion_users_count(), do: @max_latest_emotion_users_count

def supported_emotions(), do: @supported_emotions
def delete_hint(), do: @delete_hint

def report_threshold_for_fold, do: @report_threshold_for_fold
Expand All @@ -52,6 +50,7 @@ defmodule GroupherServer.CMS.ArticleComment do
schema "articles_comments" do
belongs_to(:author, Accounts.User, foreign_key: :author_id)

field(:thread, :string)
field(:body_html, :string)
# 是否被折叠
field(:is_folded, :boolean, default: false)
Expand Down
2 changes: 0 additions & 2 deletions lib/groupher_server/cms/article_user_emotion.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
defmodule GroupherServer.CMS.ArticleUserEmotion.Macros do
import Helper.Utils, only: [get_config: 2]

alias GroupherServer.CMS

@supported_emotions get_config(:article, :supported_emotions)

defmacro emotion_fields() do
Expand Down
3 changes: 3 additions & 0 deletions lib/groupher_server/cms/delegates/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
# 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

Expand All @@ -187,6 +189,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
emotions: @default_emotions,
floor: floor,
is_article_author: user_id == article.author.user.id,
thread: thread,
meta: @default_comment_meta
},
foreign_key,
Expand Down
6 changes: 2 additions & 4 deletions lib/groupher_server/cms/delegates/article_comment_action.ex
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
|> Multi.run(:create_reply_comment, fn _, _ ->
do_create_comment(content, info.foreign_key, article, user)
end)
|> Multi.run(:update_article_comments_count, fn _,
%{create_reply_comment: replyed_comment} ->
|> Multi.run(:update_comments_count, fn _, %{create_reply_comment: replyed_comment} ->
update_article_comments_count(replyed_comment, :inc)
end)
|> Multi.run(:create_article_comment_reply, fn _,
%{create_reply_comment: replyed_comment} ->
|> Multi.run(:create_comment_reply, fn _, %{create_reply_comment: replyed_comment} ->
ArticleCommentReply
|> ORM.create(%{article_comment_id: replyed_comment.id, reply_to_id: replying_comment.id})
end)
Expand Down
15 changes: 6 additions & 9 deletions lib/groupher_server/cms/delegates/article_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -121,16 +121,12 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
end

@doc """
Creates a article(post/job ...), and set community.
Creates a article

## Examples

iex> create_post(%{field: value})
iex> create_article(community, :post, %{title: ...}, user)
{:ok, %Post{}}

iex> create_post(%{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def create_article(%Community{id: cid}, thread, attrs, %User{id: uid}) do
with {:ok, author} <- ensure_author_exists(%User{id: uid}),
Expand All @@ -149,6 +145,9 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> Multi.run(:update_community_article_count, fn _, _ ->
CommunityCURD.update_community_count_field(community, thread)
end)
|> Multi.run(:update_user_published_meta, fn _, _ ->
Accounts.update_published_states(uid, thread)
end)
|> Multi.run(:mention_users, fn _, %{create_article: article} ->
Delivery.mention_from_content(community.raw, thread, article, attrs, %User{id: uid})
{:ok, :pass}
Expand Down Expand Up @@ -448,7 +447,5 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
defp result({:ok, %{update_article: result}}), do: {:ok, result}
defp result({:ok, %{set_viewer_has_states: result}}), do: result |> done()

defp result({:error, _, result, _steps}) do
{:error, result}
end
defp result({:error, _, result, _steps}), do: {:error, result}
end
28 changes: 24 additions & 4 deletions lib/groupher_server_web/resolvers/accounts_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,32 @@ defmodule GroupherServerWeb.Resolvers.Accounts do
end

# published contents
def published_contents(_root, ~m(user_id filter thread)a, _info) do
Accounts.published_contents(%User{id: user_id}, thread, filter)
def paged_published_articles(_root, ~m(login filter thread)a, _info) do
with {:ok, user_id} <- Accounts.get_userid_and_cache(login) do
Accounts.paged_published_articles(%User{id: user_id}, thread, filter)
else
_ -> raise_error(:not_exsit, "#{login} not found")
end
end

def paged_published_articles(_root, ~m(filter thread)a, %{context: %{cur_user: cur_user}}) do
Accounts.paged_published_articles(cur_user, thread, filter)
end

def paged_published_article_comments(_root, ~m(login filter thread)a, _info) do
with {:ok, user_id} <- Accounts.get_userid_and_cache(login) do
Accounts.paged_published_article_comments(%User{id: user_id}, thread, filter)
else
_ -> raise_error(:not_exsit, "#{login} not found")
end
end

def published_contents(_root, ~m(filter thread)a, %{context: %{cur_user: cur_user}}) do
Accounts.published_contents(cur_user, thread, filter)
def paged_published_article_comments(_root, ~m(login filter)a, _info) do
with {:ok, user_id} <- Accounts.get_userid_and_cache(login) do
Accounts.paged_published_article_comments(%User{id: user_id}, filter)
else
_ -> raise_error(:not_exsit, "#{login} not found")
end
end

# published comments
Expand Down
18 changes: 18 additions & 0 deletions lib/groupher_server_web/schema/Helper/queries.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ defmodule GroupherServerWeb.Schema.Helper.Queries do

@article_threads get_config(:article, :article_threads)

# user published articles
defmacro published_article_queries() do
@article_threads
|> Enum.map(fn thread ->
quote do
@desc unquote("paged published #{thread}s")
field unquote(:"paged_published_#{thread}s"), unquote(:"paged_#{thread}s") do
arg(:login, non_null(:string))
arg(:filter, non_null(:paged_filter))
arg(:thread, :thread, default_value: unquote(thread))

middleware(M.PageSizeProof)
resolve(&R.Accounts.paged_published_articles/3)
end
end
end)
end

defmacro article_search_queries() do
@article_threads
|> Enum.map(fn thread ->
Expand Down
Loading