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.

Commit51ebd24

Browse files
authored
refactor(user): move users query to own fields (#371)
* refactor(user): contribute field* refactor(user): default contributes* refactor(user): default contributes* fix(user): contrutess model setting* refactor(user): wip* refactor(user): basic follower status* refactor(user): wip* refactor(user): follow states for paged api* refactor(user): follow count move to table* refactor(user): follow queries use login* fix(user): login args in test* fix(user): login args in test* fix(user): login args in test* fix(user): login args in test
1 parent7de9e82 commit51ebd24

File tree

35 files changed

+633
-291
lines changed

35 files changed

+633
-291
lines changed

‎cover/excoveralls.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎lib/groupher_server/accounts/accounts.ex‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ defmodule GroupherServer.Accounts do
1515
}
1616

1717
# profile
18+
defdelegateread_user(user),to:Profile
19+
defdelegateread_user(login,user),to:Profile
20+
defdelegatepaged_users(filter),to:Profile
21+
defdelegatepaged_users(filter,user),to:Profile
22+
1823
defdelegateupdate_profile(user,attrs),to:Profile
1924
defdelegateupdate_geo(user,remote_ip),to:Profile
2025
defdelegategithub_signin(github_user),to:Profile
@@ -46,8 +51,10 @@ defmodule GroupherServer.Accounts do
4651
# fans
4752
defdelegatefollow(user,follower),to:Fans
4853
defdelegateundo_follow(user,follower),to:Fans
49-
defdelegatefetch_followers(user,filter),to:Fans
50-
defdelegatefetch_followings(user,filter),to:Fans
54+
defdelegatepaged_followers(user,filter),to:Fans
55+
defdelegatepaged_followers(user,filter,cur_user),to:Fans
56+
defdelegatepaged_followings(user,filter),to:Fans
57+
defdelegatepaged_followings(user,filter,cur_user),to:Fans
5158

5259
# upvoted articles
5360
defdelegatepaged_upvoted_articles(user_id,filter),to:UpvotedArticles

‎lib/groupher_server/accounts/delegates/fans.ex‎

Lines changed: 136 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -3,118 +3,127 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
33
user followers / following related
44
"""
55
importEcto.Query,warn:false
6-
importHelper.Utils,only:[done:1]
6+
importHelper.Utils,only:[done:1,ensure:2]
77
importHelper.ErrorCode
88
importShortMaps
99

1010
aliasHelper.{ORM,QueryBuilder,SpecType}
1111
aliasGroupherServer.{Accounts,Repo}
1212

13-
aliasGroupherServer.Accounts.{User,UserFollower,UserFollowing}
13+
aliasGroupherServer.Accounts.{User,Embeds,UserFollower,UserFollowing}
1414

1515
aliasEcto.Multi
1616

17+
@default_user_metaEmbeds.UserMeta.default_meta()
18+
1719
@doc"""
1820
follow a user
1921
"""
2022
@specfollow(User.t(),User.t())::{:ok,User.t()}|SpecType.gq_error()
2123
deffollow(%User{id:user_id},%User{id:follower_id})do
2224
withtrue<-to_string(user_id)!==to_string(follower_id),
23-
{:ok,_follow_user}<-ORM.find(User,follower_id)do
25+
{:ok,target_user}<-ORM.find(User,follower_id)do
2426
Multi.new()
2527
|>Multi.insert(
2628
:create_follower,
27-
# UserFollower.changeset(%UserFollower{}, ~m(user_id follower_id)a)
28-
UserFollower.changeset(%UserFollower{},%{user_id:follower_id,follower_id:user_id})
29+
UserFollower.changeset(%UserFollower{},%{user_id:target_user.id,follower_id:user_id})
2930
)
3031
|>Multi.insert(
3132
:create_following,
32-
UserFollowing.changeset(%UserFollowing{},%{user_id:user_id,following_id:follower_id})
33+
UserFollowing.changeset(%UserFollowing{},%{
34+
user_id:user_id,
35+
following_id:target_user.id
36+
})
3337
)
38+
|>Multi.run(:update_user_follow_info,fn_,_->
39+
update_user_follow_info(target_user,user_id,:add)
40+
end)
3441
|>Multi.run(:add_achievement,fn_,_->
35-
Accounts.achieve(%User{id:follower_id},:inc,:follow)
42+
Accounts.achieve(%User{id:target_user.id},:inc,:follow)
3643
end)
3744
|>Repo.transaction()
38-
|>follow_result()
45+
|>result()
3946
else
40-
false->
41-
{:error,[message:"can't follow yourself",code:ecode(:self_conflict)]}
42-
43-
{:error,reason}->
44-
{:error,[message:reason,code:ecode(:not_exsit)]}
47+
false->{:error,[message:"can't follow yourself",code:ecode(:self_conflict)]}
48+
{:error,reason}->{:error,[message:reason,code:ecode(:not_exsit)]}
4549
end
4650
end
4751

48-
@specfollow_result({:ok,map()})::SpecType.done()
49-
defpfollow_result({:ok,%{create_follower:user_follower}})do
50-
User|>ORM.find(user_follower.user_id)
51-
end
52-
53-
defpfollow_result({:error,:create_follower,%Ecto.Changeset{},_steps})do
54-
{:error,[message:"already followed",code:ecode(:already_did)]}
55-
end
56-
57-
defpfollow_result({:error,:create_follower,_result,_steps})do
58-
{:error,[message:"already followed",code:ecode(:already_did)]}
59-
end
60-
61-
defpfollow_result({:error,:create_following,_result,_steps})do
62-
{:error,[message:"follow fails",code:ecode(:react_fails)]}
63-
end
64-
65-
defpfollow_result({:error,:add_achievement,_result,_steps})do
66-
{:error,[message:"follow acieve fails",code:ecode(:react_fails)]}
67-
end
68-
6952
@doc"""
7053
undo a follow action to a user
7154
"""
7255
@specundo_follow(User.t(),User.t())::{:ok,User.t()}|SpecType.gq_error()
7356
defundo_follow(%User{id:user_id},%User{id:follower_id})do
7457
withtrue<-to_string(user_id)!==to_string(follower_id),
75-
{:ok,_follow_user}<-ORM.find(User,follower_id)do
58+
{:ok,target_user}<-ORM.find(User,follower_id)do
7659
Multi.new()
7760
|>Multi.run(:delete_follower,fn_,_->
78-
ORM.findby_delete!(UserFollower,%{user_id:follower_id,follower_id:user_id})
61+
ORM.findby_delete!(UserFollower,%{user_id:target_user.id,follower_id:user_id})
7962
end)
8063
|>Multi.run(:delete_following,fn_,_->
81-
ORM.findby_delete!(UserFollowing,%{user_id:user_id,following_id:follower_id})
64+
ORM.findby_delete!(UserFollowing,%{user_id:user_id,following_id:target_user.id})
65+
end)
66+
|>Multi.run(:update_user_follow_info,fn_,_->
67+
update_user_follow_info(target_user,user_id,:remove)
8268
end)
8369
|>Multi.run(:minus_achievement,fn_,_->
84-
Accounts.achieve(%User{id:follower_id},:dec,:follow)
70+
Accounts.achieve(%User{id:target_user.id},:dec,:follow)
8571
end)
8672
|>Repo.transaction()
87-
|>undo_follow_result()
73+
|>result()
8874
else
89-
false->
90-
{:error,[message:"can't undo follow yourself",code:ecode(:self_conflict)]}
91-
92-
{:error,reason}->
93-
{:error,[message:reason,code:ecode(:not_exsit)]}
75+
false->{:error,[message:"can't undo follow yourself",code:ecode(:self_conflict)]}
76+
{:error,reason}->{:error,[message:reason,code:ecode(:not_exsit)]}
9477
end
9578
end
9679

97-
defpundo_follow_result({:ok,%{delete_follower:user_follower}})do
98-
User|>ORM.find(user_follower.user_id)
99-
end
80+
# update follow in user meta
81+
defpupdate_user_follow_info(%User{}=target_user,user_id,opt)do
82+
with{:ok,user}<-ORM.find(User,user_id)do
83+
target_user_meta=ensure(target_user.meta,@default_user_meta)
84+
user_meta=ensure(user.meta,@default_user_meta)
10085

101-
defpundo_follow_result({:error,:delete_follower,_result,_steps})do
102-
{:error,[message:"already unfollowed",code:ecode(:already_did)]}
103-
end
86+
follower_user_ids=
87+
caseoptdo
88+
:add->(target_user_meta.follower_user_ids++[user_id])|>Enum.uniq()
89+
:remove->(target_user_meta.follower_user_ids--[user_id])|>Enum.uniq()
90+
end
10491

105-
defpundo_follow_result({:error,:delete_following,_result,_steps})do
106-
{:error,[message:"unfollow fails",code:ecode(:react_fails)]}
107-
end
92+
following_user_ids=
93+
caseoptdo
94+
:add->(user_meta.following_user_ids++[target_user.id])|>Enum.uniq()
95+
:remove->(user_meta.following_user_ids--[target_user.id])|>Enum.uniq()
96+
end
10897

109-
defpundo_follow_result({:error,:minus_achievement,_result,_steps})do
110-
{:error,[message:"follow acieve fails",code:ecode(:react_fails)]}
98+
Multi.new()
99+
|>Multi.run(:update_follower_meta,fn_,_->
100+
followers_count=length(follower_user_ids)
101+
meta=Map.merge(target_user_meta,%{follower_user_ids:follower_user_ids})
102+
103+
ORM.update_meta(target_user,meta,changes:%{followers_count:followers_count})
104+
end)
105+
|>Multi.run(:update_following_meta,fn_,_->
106+
followings_count=length(following_user_ids)
107+
meta=Map.merge(user_meta,%{following_user_ids:following_user_ids})
108+
109+
ORM.update_meta(user,meta,changes:%{followings_count:followings_count})
110+
end)
111+
|>Repo.transaction()
112+
|>result()
113+
end
111114
end
112115

113116
@doc"""
114117
get paged followers of a user
115118
"""
116-
@specfetch_followers(User.t(),map())::{:ok,map()}|{:error,String.t()}
117-
deffetch_followers(%User{id:user_id},filter)do
119+
defpaged_followers(%User{id:user_id},filter,%User{}=cur_user)do
120+
paged_followers(%User{id:user_id},filter)
121+
|>mark_viewer_follow_status(cur_user)
122+
|>done
123+
end
124+
125+
@specpaged_followers(User.t(),map())::{:ok,map()}|{:error,String.t()}
126+
defpaged_followers(%User{id:user_id},filter)do
118127
UserFollower
119128
|>where([uf],uf.user_id==^user_id)
120129
|>join(:inner,[uf],uinassoc(uf,:follower))
@@ -124,8 +133,14 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
124133
@doc"""
125134
get paged followings of a user
126135
"""
127-
@specfetch_followings(User.t(),map())::{:ok,map()}|{:error,String.t()}
128-
deffetch_followings(%User{id:user_id},filter)do
136+
defpaged_followings(%User{id:user_id},filter,%User{}=cur_user)do
137+
paged_followings(%User{id:user_id},filter)
138+
|>mark_viewer_follow_status(cur_user)
139+
|>done
140+
end
141+
142+
@specpaged_followings(User.t(),map())::{:ok,map()}|{:error,String.t()}
143+
defpaged_followings(%User{id:user_id},filter)do
129144
UserFollowing
130145
|>where([uf],uf.user_id==^user_id)
131146
|>join(:inner,[uf],uinassoc(uf,:following))
@@ -140,4 +155,66 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
140155
|>ORM.paginater(~m(page size)a)
141156
|>done()
142157
end
158+
159+
@doc"""
160+
mark viewer's follower/followings states
161+
"""
162+
defmark_viewer_follow_status({:ok,%{entries:entries}=paged_users},cur_user)do
163+
entries=Enum.map(entries,&Map.merge(&1,do_mark_viewer_has_states(&1.id,cur_user)))
164+
Map.merge(paged_users,%{entries:entries})
165+
end
166+
167+
defmark_viewer_follow_status({:error,reason}),do:{:error,reason}
168+
169+
defpdo_mark_viewer_has_states(user_id,%User{meta:nil})do
170+
%{viewer_been_followed:false,viewer_has_followed:false}
171+
end
172+
173+
defpdo_mark_viewer_has_states(user_id,%User{meta:meta})do
174+
%{
175+
viewer_been_followed:Enum.member?(meta.follower_user_ids,user_id),
176+
viewer_has_followed:Enum.member?(meta.following_user_ids,user_id)
177+
}
178+
end
179+
180+
@specresult({:ok,map()})::SpecType.done()
181+
defpresult({:ok,%{create_follower:user_follower}})do
182+
User|>ORM.find(user_follower.user_id)
183+
end
184+
185+
defpresult({:ok,%{delete_follower:user_follower}})do
186+
User|>ORM.find(user_follower.user_id)
187+
end
188+
189+
defpresult({:ok,%{update_follower_meta:result}})do
190+
{:ok,result}
191+
end
192+
193+
defpresult({:error,:create_follower,%Ecto.Changeset{},_steps})do
194+
{:error,[message:"already followed",code:ecode(:already_did)]}
195+
end
196+
197+
defpresult({:error,:create_follower,_result,_steps})do
198+
{:error,[message:"already followed",code:ecode(:already_did)]}
199+
end
200+
201+
defpresult({:error,:create_following,_result,_steps})do
202+
{:error,[message:"follow fails",code:ecode(:react_fails)]}
203+
end
204+
205+
defpresult({:error,:delete_follower,_result,_steps})do
206+
{:error,[message:"already unfollowed",code:ecode(:already_did)]}
207+
end
208+
209+
defpresult({:error,:delete_following,_result,_steps})do
210+
{:error,[message:"unfollow fails",code:ecode(:react_fails)]}
211+
end
212+
213+
defpresult({:error,:minus_achievement,_result,_steps})do
214+
{:error,[message:"follow acieve fails",code:ecode(:react_fails)]}
215+
end
216+
217+
defpresult({:error,:add_achievement,_result,_steps})do
218+
{:error,[message:"follow acieve fails",code:ecode(:react_fails)]}
219+
end
143220
end

‎lib/groupher_server/accounts/delegates/profile.ex‎

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,57 @@ defmodule GroupherServer.Accounts.Delegate.Profile do
66
importHelper.Utils,only:[done:1,get_config:2]
77
importShortMaps
88

9-
aliasGroupherServer.{Accounts,CMS,Email,Repo}
9+
aliasGroupherServer.{Accounts,CMS,Email,Repo,Statistics}
1010

1111
aliasAccounts.{Achievement,GithubUser,User,Social}
1212
aliasHelper.{Guardian,ORM,QueryBuilder,RadarSearch}
1313

14+
aliasGroupherServer.Accounts.Delegate.Fans
1415
aliasEcto.Multi
1516

1617
@default_subscribed_communitiesget_config(:general,:default_subscribed_communities)
1718

19+
defread_user(login)whenis_binary(login)do
20+
with{:ok,user}<-ORM.read_by(User,%{login:login},inc::views)do
21+
caseuser.contributesdo
22+
nil->assign_default_contributes(user)
23+
_->{:ok,user}
24+
end
25+
end
26+
end
27+
28+
defread_user(login,%User{meta:nil}),do:read_user(login)
29+
30+
defread_user(login,%User{}=cur_user)do
31+
with{:ok,user}<-read_user(login)do
32+
# Ta 关注了你
33+
viewer_been_followed=user.idincur_user.meta.follower_user_ids
34+
# 正在关注
35+
viewer_has_followed=user.idincur_user.meta.following_user_ids
36+
37+
user=
38+
Map.merge(user,%{
39+
viewer_been_followed:viewer_been_followed,
40+
viewer_has_followed:viewer_has_followed
41+
})
42+
43+
{:ok,user}
44+
end
45+
end
46+
47+
defpaged_users(filter,%User{}=user)do
48+
ORM.find_all(User,filter)|>Fans.mark_viewer_follow_status(user)|>done
49+
end
50+
51+
defpaged_users(filter)do
52+
ORM.find_all(User,filter)
53+
end
54+
1855
@doc"""
1956
update user's profile
2057
"""
2158
defupdate_profile(%User{}=user,attrs\\%{})do
22-
changeset=
23-
user
24-
|>Ecto.Changeset.change(attrs)
59+
changeset=user|>Ecto.Changeset.change(attrs)
2560

2661
changeset
2762
|>update_social_ifneed(user,attrs)
@@ -257,4 +292,10 @@ defmodule GroupherServer.Accounts.Delegate.Profile do
257292
changeset
258293
end
259294
end
295+
296+
# assign default contributes
297+
defpassign_default_contributes(%User{}=user)do
298+
{:ok,contributes}=Statistics.list_contributes_digest(%User{id:user.id})
299+
ORM.update_embed(user,:contributes,contributes)
300+
end
260301
end
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
defmoduleGroupherServer.Accounts.Embeds.UserContributedo
2+
@moduledoc"""
3+
user contribute
4+
"""
5+
useEcto.Schema
6+
useAccessible
7+
importEcto.Changeset
8+
9+
aliasGroupherServer.Accounts.Embeds
10+
11+
@optional_fields~w(reported_count)a
12+
13+
embedded_schemado
14+
field(:start_date,:date)
15+
field(:end_date,:date)
16+
field(:total_count,:integer,default:0)
17+
embeds_many(:records,Embeds.UserContributeRecord,on_replace::delete)
18+
end
19+
20+
defchangeset(struct,params)do
21+
struct
22+
|>cast(params,@optional_fields)
23+
|>cast_embed(:records,with:&Embeds.UserContributeRecord.changeset/2)
24+
end
25+
end

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp