diff --git a/lib/groupher_server/delivery/delegates/notification.ex b/lib/groupher_server/delivery/delegates/notification.ex index adc487223..050f8dfe2 100644 --- a/lib/groupher_server/delivery/delegates/notification.ex +++ b/lib/groupher_server/delivery/delegates/notification.ex @@ -18,6 +18,7 @@ defmodule GroupherServer.Delivery.Delegate.Notification do @notify_actions get_config(:general, :nofity_actions) @notify_group_interval_hour get_config(:general, :notify_group_interval_hour) + @cut_from_users_count 3 def handle(%{action: action, user_id: user_id} = attrs, %User{} = from_user) do with true <- action in @notify_actions, @@ -84,9 +85,21 @@ defmodule GroupherServer.Delivery.Delegate.Notification do Notification |> where([n], n.user_id == ^user.id and n.read == ^read) |> ORM.paginater(~m(page size)a) + |> cut_from_users_ifneed |> done end + # @cut_from_users_count + defp cut_from_users_ifneed(%{entries: entries} = paged_contents) do + entries = + Enum.map(entries, fn notify -> + from_users = Enum.slice(notify.from_users, 0, @cut_from_users_count) + notify |> Map.put(:from_users, from_users) + end) + + paged_contents |> Map.put(:entries, entries) + end + # 注意这里并不是准确的 count, 因为可能有短时间内 merge 到一起的通知 def unread_count(user_id) do Notification @@ -114,13 +127,18 @@ defmodule GroupherServer.Delivery.Delegate.Notification do cur_from_users = notify.from_users |> Enum.map(&strip_struct(&1)) from_users = ([from_user] ++ cur_from_users) |> Enum.uniq() - notify |> ORM.update_embed(:from_users, from_users) + notify + |> Ecto.Changeset.change(%{from_users_count: length(from_users)}) + |> Ecto.Changeset.put_embed(:from_users, from_users) + |> Repo.update() end # 创建通知 defp create_notification(attrs, from_user) do + attrs = attrs |> Map.merge(%{from_users_count: 1}) |> atom_values_to_upcase + %Notification{} - |> Ecto.Changeset.change(atom_values_to_upcase(attrs)) + |> Ecto.Changeset.change(attrs) |> Ecto.Changeset.put_embed(:from_users, [from_user]) |> Repo.insert() end diff --git a/lib/groupher_server/delivery/models/notification.ex b/lib/groupher_server/delivery/models/notification.ex index cd7386c96..4304aa29f 100644 --- a/lib/groupher_server/delivery/models/notification.ex +++ b/lib/groupher_server/delivery/models/notification.ex @@ -24,6 +24,7 @@ defmodule GroupherServer.Delivery.Model.Notification do # field(:action, :string) embeds_many(:from_users, Embeds.User, on_replace: :delete) + field(:from_users_count, :integer) field(:read, :boolean, default: false) diff --git a/lib/groupher_server_web/schema/account/account_types.ex b/lib/groupher_server_web/schema/account/account_types.ex index 268e0dbe6..a76e2f5f4 100644 --- a/lib/groupher_server_web/schema/account/account_types.ex +++ b/lib/groupher_server_web/schema/account/account_types.ex @@ -122,6 +122,7 @@ defmodule GroupherServerWeb.Schema.Account.Types do field(:read, :boolean) field(:from_users, list_of(:common_user)) + field(:from_users_count, :integer) timestamp_fields() end diff --git a/priv/repo/migrations/20210623054015_add_from_users_count_to_notification.exs b/priv/repo/migrations/20210623054015_add_from_users_count_to_notification.exs new file mode 100644 index 000000000..d424506e9 --- /dev/null +++ b/priv/repo/migrations/20210623054015_add_from_users_count_to_notification.exs @@ -0,0 +1,9 @@ +defmodule GroupherServer.Repo.Migrations.AddFromUsersCountToNotification do + use Ecto.Migration + + def change do + alter table(:notifications) do + add(:from_users_count, :integer) + end + end +end diff --git a/test/groupher_server/delivery/notification_test.exs b/test/groupher_server/delivery/notification_test.exs index 122d45b3d..43258a75c 100644 --- a/test/groupher_server/delivery/notification_test.exs +++ b/test/groupher_server/delivery/notification_test.exs @@ -137,6 +137,28 @@ defmodule GroupherServer.Test.Delivery.Notification do assert user2 |> user_exist_in?(notify2.from_users) end + test "notify's from_users_count should work", ~m(user user2 user3 user4 notify_attrs)a do + {:ok, user5} = db_insert(:user) + + {:ok, _notify} = Delivery.send(:notify, notify_attrs, user2) + {:ok, _} = Delivery.send(:notify, notify_attrs, user3) + {:ok, _} = Delivery.send(:notify, notify_attrs, user4) + {:ok, _} = Delivery.send(:notify, notify_attrs, user5) + + {:ok, paged_notifies} = Delivery.fetch(:notification, user, %{page: 1, size: 10}) + + assert paged_notifies.total_count == 1 + notify = paged_notifies.entries |> List.first() + + assert notify.from_users_count == 4 + assert length(notify.from_users) == 3 + + assert user5 |> user_exist_in?(notify.from_users) + assert user4 |> user_exist_in?(notify.from_users) + assert user3 |> user_exist_in?(notify.from_users) + assert not user_exist_in?(user2, notify.from_users) + end + test "notify myself got ignored", ~m(user notify_attrs)a do {:error, _} = Delivery.send(:notify, notify_attrs, user) end