正在显示
16 个修改的文件
包含
512 行增加
和
19 行删除
@@ -16,7 +16,7 @@ info( | @@ -16,7 +16,7 @@ info( | ||
16 | service Core { | 16 | service Core { |
17 | @doc "用户申请加入公司" | 17 | @doc "用户申请加入公司" |
18 | @handler miniUserApplyJoinCompany | 18 | @handler miniUserApplyJoinCompany |
19 | - post /mini/user/apply-join-company(MiniUserApplyJoinCompanyRequest) returns (MiniUserApplyJoinCompanyResponse) | 19 | + post /mini/user/apply_join_company(MiniUserApplyJoinCompanyRequest) returns (MiniUserApplyJoinCompanyResponse) |
20 | @doc "用户登录" | 20 | @doc "用户登录" |
21 | @handler miniUserLogin | 21 | @handler miniUserLogin |
22 | post /mini/user/login (MiniUserLoginRequest) returns (MiniUserLoginResponse) | 22 | post /mini/user/login (MiniUserLoginRequest) returns (MiniUserLoginResponse) |
@@ -29,7 +29,7 @@ service Core { | @@ -29,7 +29,7 @@ service Core { | ||
29 | service Core { | 29 | service Core { |
30 | @doc "切换账号" | 30 | @doc "切换账号" |
31 | @handler miniUserSwitchAccount | 31 | @handler miniUserSwitchAccount |
32 | - post /mini/user/switch-account (MiniUserSwitchAccountRequest) returns (MiniUserLoginResponse) | 32 | + post /mini/user/switch_account (MiniUserSwitchAccountRequest) returns (MiniUserLoginResponse) |
33 | @doc "用户信息" | 33 | @doc "用户信息" |
34 | @handler miniUserInfo | 34 | @handler miniUserInfo |
35 | post /mini/user/info (MiniUserInfoRequest) returns (MiniUserInfoResponse) | 35 | post /mini/user/info (MiniUserInfoRequest) returns (MiniUserInfoResponse) |
@@ -38,22 +38,31 @@ service Core { | @@ -38,22 +38,31 @@ service Core { | ||
38 | post /mini/user/statistics (UserStatisticsRequest) returns (UserStatisticsResponse) | 38 | post /mini/user/statistics (UserStatisticsRequest) returns (UserStatisticsResponse) |
39 | @doc "用户审核列表" | 39 | @doc "用户审核列表" |
40 | @handler miniUserAuditList | 40 | @handler miniUserAuditList |
41 | - post /mini/user/audit-list (UserSearchRequest)returns(UserSearchResponse) | 41 | + post /mini/user/audit_list (UserSearchRequest)returns(UserSearchResponse) |
42 | @doc "用户审核" | 42 | @doc "用户审核" |
43 | @handler miniUserAudit | 43 | @handler miniUserAudit |
44 | post /mini/user/audit (MiniUserAuditRequest) | 44 | post /mini/user/audit (MiniUserAuditRequest) |
45 | @doc "部门用户列表" | 45 | @doc "部门用户列表" |
46 | @handler miniUserDepartmentUsers | 46 | @handler miniUserDepartmentUsers |
47 | - post /mini/user/department-users (MiniUserDepartmentUsersRequest) | 47 | + post /mini/user/department_users (MiniUserDepartmentUsersRequest) |
48 | @doc "用户列表" | 48 | @doc "用户列表" |
49 | @handler miniUsersList | 49 | @handler miniUsersList |
50 | - post /mini/user/user-list (MiniUsersListRequest) | 50 | + post /mini/user/user_list (MiniUsersListRequest) |
51 | + @doc "用户快讯" | ||
52 | + @handler miniUserNews | ||
53 | + post /mini/user/news (MiniUserNewsRequest)returns(MiniUserNewsResposne) | ||
51 | @doc "关注我的人" | 54 | @doc "关注我的人" |
52 | @handler miniUserFollower | 55 | @handler miniUserFollower |
53 | post /mini/user/follower (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse) | 56 | post /mini/user/follower (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse) |
54 | @doc "我关注的人" | 57 | @doc "我关注的人" |
55 | @handler miniUserFollowing | 58 | @handler miniUserFollowing |
56 | post /mini/user/following (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse) | 59 | post /mini/user/following (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse) |
60 | + @doc "我关注的人-最新未读列表(未读标红)" | ||
61 | + @handler miniUserFollowingLatestUnreadList | ||
62 | + post /mini/user/following/latest_unread_list (MiniUserFollowedSearchRequest)returns(MiniUserFollowedSearchResponse) | ||
63 | + @doc "我关注的人-标记已读" | ||
64 | + @handler miniUserFollowingMarkRead | ||
65 | + post /mini/user/following/mark_read (MiniUserFollowingMarkReadRequest) | ||
57 | @doc "关注" | 66 | @doc "关注" |
58 | @handler miniUserFollow | 67 | @handler miniUserFollow |
59 | post /mini/user/follow (FollowRequest) | 68 | post /mini/user/follow (FollowRequest) |
@@ -115,6 +124,23 @@ type( | @@ -115,6 +124,23 @@ type( | ||
115 | ArticleId int64 `json:"articleId,optional"` // 按文章ID(返回文章可见的用户) | 124 | ArticleId int64 `json:"articleId,optional"` // 按文章ID(返回文章可见的用户) |
116 | RoleId int64 `json:"roleId,optional"` // 按角色角色关联的用户 | 125 | RoleId int64 `json:"roleId,optional"` // 按角色角色关联的用户 |
117 | } | 126 | } |
127 | + MiniUserNewsRequest{ | ||
128 | + AuthorId int64 `json:"authorId,optional"` // 特定作者ID | ||
129 | + LastArticleId int64 `json:"lastArticleId,optional"`// 最后文章ID | ||
130 | + Size int `json:"size"` // 数量 | ||
131 | + } | ||
132 | + MiniUserNewsResposne{ | ||
133 | + List []UserNewsItem `json:"list"` | ||
134 | + Total int64 `json:"total"` | ||
135 | + } | ||
136 | + UserNewsItem{ | ||
137 | + NewsId int64 `json:"newsId"` // 快讯ID | ||
138 | + Type string `json:"type"` // 快讯类型 文章:Article 讨论:Discuss ... | ||
139 | + Title string `json:"title"` // 标题 | ||
140 | + Summary string `json:"summary"` // 快讯概要 | ||
141 | + Time int64 `json:"time"` // 时间 | ||
142 | + ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读 | ||
143 | + } | ||
118 | MiniUserFollowedSearchRequest{ | 144 | MiniUserFollowedSearchRequest{ |
119 | Page int `json:"page,optional"` | 145 | Page int `json:"page,optional"` |
120 | Size int `json:"size,optional"` | 146 | Size int `json:"size,optional"` |
@@ -123,6 +149,11 @@ type( | @@ -123,6 +149,11 @@ type( | ||
123 | List []*UserFollowItem `json:"users"` | 149 | List []*UserFollowItem `json:"users"` |
124 | Total int64 `json:"total"` | 150 | Total int64 `json:"total"` |
125 | } | 151 | } |
152 | + | ||
153 | + MiniUserFollowingMarkReadRequest{ | ||
154 | + UserId int64 `json:"userId"` | ||
155 | + } | ||
156 | + | ||
126 | UserItem { | 157 | UserItem { |
127 | Id int64 `json:"id,omitempty"` // 用户ID | 158 | Id int64 `json:"id,omitempty"` // 用户ID |
128 | CompanyId int64 `json:"companyId,omitempty"` // 公司ID | 159 | CompanyId int64 `json:"companyId,omitempty"` // 公司ID |
@@ -176,6 +207,7 @@ type( | @@ -176,6 +207,7 @@ type( | ||
176 | Position string `json:"position"` // 职位 | 207 | Position string `json:"position"` // 职位 |
177 | Followed bool `json:"followed"` // 关注 | 208 | Followed bool `json:"followed"` // 关注 |
178 | MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识 | 209 | MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识 |
210 | + ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读(小红点) | ||
179 | } | 211 | } |
180 | ) | 212 | ) |
181 | 213 | ||
@@ -229,7 +261,7 @@ service Core { | @@ -229,7 +261,7 @@ service Core { | ||
229 | post /system/user/statistics (UserStatisticsRequest) returns (UserStatisticsResponse) | 261 | post /system/user/statistics (UserStatisticsRequest) returns (UserStatisticsResponse) |
230 | @doc "用户列表" | 262 | @doc "用户列表" |
231 | @handler systemUsersList | 263 | @handler systemUsersList |
232 | - post /system/user/user-list (MiniUsersListRequest) | 264 | + post /system/user/user_list (MiniUsersListRequest) |
233 | 265 | ||
234 | @doc "用户详情" | 266 | @doc "用户详情" |
235 | @handler systemUserGet | 267 | @handler systemUserGet |
@@ -123,7 +123,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -123,7 +123,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
123 | []rest.Route{ | 123 | []rest.Route{ |
124 | { | 124 | { |
125 | Method: http.MethodPost, | 125 | Method: http.MethodPost, |
126 | - Path: "/mini/user/apply-join-company", | 126 | + Path: "/mini/user/apply_join_company", |
127 | Handler: user.MiniUserApplyJoinCompanyHandler(serverCtx), | 127 | Handler: user.MiniUserApplyJoinCompanyHandler(serverCtx), |
128 | }, | 128 | }, |
129 | { | 129 | { |
@@ -139,7 +139,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -139,7 +139,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
139 | []rest.Route{ | 139 | []rest.Route{ |
140 | { | 140 | { |
141 | Method: http.MethodPost, | 141 | Method: http.MethodPost, |
142 | - Path: "/mini/user/switch-account", | 142 | + Path: "/mini/user/switch_account", |
143 | Handler: user.MiniUserSwitchAccountHandler(serverCtx), | 143 | Handler: user.MiniUserSwitchAccountHandler(serverCtx), |
144 | }, | 144 | }, |
145 | { | 145 | { |
@@ -154,7 +154,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -154,7 +154,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
154 | }, | 154 | }, |
155 | { | 155 | { |
156 | Method: http.MethodPost, | 156 | Method: http.MethodPost, |
157 | - Path: "/mini/user/audit-list", | 157 | + Path: "/mini/user/audit_list", |
158 | Handler: user.MiniUserAuditListHandler(serverCtx), | 158 | Handler: user.MiniUserAuditListHandler(serverCtx), |
159 | }, | 159 | }, |
160 | { | 160 | { |
@@ -164,16 +164,21 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -164,16 +164,21 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
164 | }, | 164 | }, |
165 | { | 165 | { |
166 | Method: http.MethodPost, | 166 | Method: http.MethodPost, |
167 | - Path: "/mini/user/department-users", | 167 | + Path: "/mini/user/department_users", |
168 | Handler: user.MiniUserDepartmentUsersHandler(serverCtx), | 168 | Handler: user.MiniUserDepartmentUsersHandler(serverCtx), |
169 | }, | 169 | }, |
170 | { | 170 | { |
171 | Method: http.MethodPost, | 171 | Method: http.MethodPost, |
172 | - Path: "/mini/user/user-list", | 172 | + Path: "/mini/user/user_list", |
173 | Handler: user.MiniUsersListHandler(serverCtx), | 173 | Handler: user.MiniUsersListHandler(serverCtx), |
174 | }, | 174 | }, |
175 | { | 175 | { |
176 | Method: http.MethodPost, | 176 | Method: http.MethodPost, |
177 | + Path: "/mini/user/news", | ||
178 | + Handler: user.MiniUserNewsHandler(serverCtx), | ||
179 | + }, | ||
180 | + { | ||
181 | + Method: http.MethodPost, | ||
177 | Path: "/mini/user/follower", | 182 | Path: "/mini/user/follower", |
178 | Handler: user.MiniUserFollowerHandler(serverCtx), | 183 | Handler: user.MiniUserFollowerHandler(serverCtx), |
179 | }, | 184 | }, |
@@ -184,6 +189,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -184,6 +189,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
184 | }, | 189 | }, |
185 | { | 190 | { |
186 | Method: http.MethodPost, | 191 | Method: http.MethodPost, |
192 | + Path: "/mini/user/following/latest_unread_list", | ||
193 | + Handler: user.MiniUserFollowingLatestUnreadListHandler(serverCtx), | ||
194 | + }, | ||
195 | + { | ||
196 | + Method: http.MethodPost, | ||
197 | + Path: "/mini/user/following/mark_read", | ||
198 | + Handler: user.MiniUserFollowingMarkReadHandler(serverCtx), | ||
199 | + }, | ||
200 | + { | ||
201 | + Method: http.MethodPost, | ||
187 | Path: "/mini/user/follow", | 202 | Path: "/mini/user/follow", |
188 | Handler: user.MiniUserFollowHandler(serverCtx), | 203 | Handler: user.MiniUserFollowHandler(serverCtx), |
189 | }, | 204 | }, |
@@ -218,7 +233,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | @@ -218,7 +233,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { | ||
218 | }, | 233 | }, |
219 | { | 234 | { |
220 | Method: http.MethodPost, | 235 | Method: http.MethodPost, |
221 | - Path: "/system/user/user-list", | 236 | + Path: "/system/user/user_list", |
222 | Handler: user.SystemUsersListHandler(serverCtx), | 237 | Handler: user.SystemUsersListHandler(serverCtx), |
223 | }, | 238 | }, |
224 | { | 239 | { |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result" | ||
5 | + "net/http" | ||
6 | + | ||
7 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | +) | ||
12 | + | ||
13 | +func MiniUserFollowingLatestUnreadListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
14 | + return func(w http.ResponseWriter, r *http.Request) { | ||
15 | + var req types.MiniUserFollowedSearchRequest | ||
16 | + if err := httpx.Parse(r, &req); err != nil { | ||
17 | + httpx.ErrorCtx(r.Context(), w, err) | ||
18 | + return | ||
19 | + } | ||
20 | + | ||
21 | + l := user.NewMiniUserFollowingLatestUnreadListLogic(r.Context(), svcCtx) | ||
22 | + resp, err := l.MiniUserFollowingLatestUnreadList(&req) | ||
23 | + result.HttpResult(r, w, resp, err) | ||
24 | + } | ||
25 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result" | ||
5 | + "net/http" | ||
6 | + | ||
7 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | +) | ||
12 | + | ||
13 | +func MiniUserFollowingMarkReadHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
14 | + return func(w http.ResponseWriter, r *http.Request) { | ||
15 | + var req types.MiniUserFollowingMarkReadRequest | ||
16 | + if err := httpx.Parse(r, &req); err != nil { | ||
17 | + httpx.ErrorCtx(r.Context(), w, err) | ||
18 | + return | ||
19 | + } | ||
20 | + | ||
21 | + l := user.NewMiniUserFollowingMarkReadLogic(r.Context(), svcCtx) | ||
22 | + resp, err := l.MiniUserFollowingMarkRead(&req) | ||
23 | + result.HttpResult(r, w, resp, err) | ||
24 | + } | ||
25 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/result" | ||
5 | + "net/http" | ||
6 | + | ||
7 | + "github.com/zeromicro/go-zero/rest/httpx" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/logic/user" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
11 | +) | ||
12 | + | ||
13 | +func MiniUserNewsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { | ||
14 | + return func(w http.ResponseWriter, r *http.Request) { | ||
15 | + var req types.MiniUserNewsRequest | ||
16 | + if err := httpx.Parse(r, &req); err != nil { | ||
17 | + httpx.ErrorCtx(r.Context(), w, err) | ||
18 | + return | ||
19 | + } | ||
20 | + | ||
21 | + l := user.NewMiniUserNewsLogic(r.Context(), svcCtx) | ||
22 | + resp, err := l.MiniUserNews(&req) | ||
23 | + result.HttpResult(r, w, resp, err) | ||
24 | + } | ||
25 | +} |
@@ -6,6 +6,7 @@ import ( | @@ -6,6 +6,7 @@ import ( | ||
6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | 6 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" |
7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | 7 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" |
8 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | 8 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" |
9 | + "time" | ||
9 | 10 | ||
10 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | 11 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" |
11 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | 12 | "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" |
@@ -32,6 +33,7 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | @@ -32,6 +33,7 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | ||
32 | conn = l.svcCtx.DefaultDBConn() | 33 | conn = l.svcCtx.DefaultDBConn() |
33 | user *domain.User | 34 | user *domain.User |
34 | targetUser *domain.User | 35 | targetUser *domain.User |
36 | + userFollow *domain.UserFollow | ||
35 | userToken = contextdata.GetUserTokenFromCtx(l.ctx) | 37 | userToken = contextdata.GetUserTokenFromCtx(l.ctx) |
36 | ) | 38 | ) |
37 | if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil { | 39 | if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil { |
@@ -40,6 +42,9 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | @@ -40,6 +42,9 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | ||
40 | if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil { | 42 | if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil { |
41 | return xerr.NewErrMsgErr("关注的用户不存在", err) | 43 | return xerr.NewErrMsgErr("关注的用户不存在", err) |
42 | } | 44 | } |
45 | + if userFollow, err = l.svcCtx.UserFollowRepository.FindOneUserFollowing(l.ctx, conn, user.Id, targetUser.Id); err == nil && userFollow != nil { | ||
46 | + return xerr.NewErrMsgErr("用户已关注", err) | ||
47 | + } | ||
43 | if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { | 48 | if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { |
44 | if err = user.Follow(targetUser); err != nil { | 49 | if err = user.Follow(targetUser); err != nil { |
45 | return err | 50 | return err |
@@ -50,6 +55,14 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | @@ -50,6 +55,14 @@ func (l *MiniUserFollowLogic) MiniUserFollow(req *types.FollowRequest) (err erro | ||
50 | if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil { | 55 | if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil { |
51 | return err | 56 | return err |
52 | } | 57 | } |
58 | + userFollow = &domain.UserFollow{ | ||
59 | + FromUserId: user.Id, | ||
60 | + ToUserId: targetUser.Id, | ||
61 | + LastReadAt: time.Now().Unix(), | ||
62 | + } | ||
63 | + if userFollow, err = l.svcCtx.UserFollowRepository.Insert(ctx, conn, userFollow); err != nil { | ||
64 | + return err | ||
65 | + } | ||
53 | return nil | 66 | return nil |
54 | }, true); err != nil { | 67 | }, true); err != nil { |
55 | return xerr.NewErrMsgErr("关注用户失败", err) | 68 | return xerr.NewErrMsgErr("关注用户失败", err) |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "github.com/samber/lo" | ||
6 | + "github.com/zeromicro/go-zero/core/collection" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
9 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
10 | + | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
13 | + | ||
14 | + "github.com/zeromicro/go-zero/core/logx" | ||
15 | +) | ||
16 | + | ||
17 | +type MiniUserFollowingLatestUnreadListLogic struct { | ||
18 | + logx.Logger | ||
19 | + ctx context.Context | ||
20 | + svcCtx *svc.ServiceContext | ||
21 | +} | ||
22 | + | ||
23 | +func NewMiniUserFollowingLatestUnreadListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniUserFollowingLatestUnreadListLogic { | ||
24 | + return &MiniUserFollowingLatestUnreadListLogic{ | ||
25 | + Logger: logx.WithContext(ctx), | ||
26 | + ctx: ctx, | ||
27 | + svcCtx: svcCtx, | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +func (l *MiniUserFollowingLatestUnreadListLogic) MiniUserFollowingLatestUnreadList(req *types.MiniUserFollowedSearchRequest) (resp *types.MiniUserFollowedSearchResponse, err error) { | ||
32 | + var ( | ||
33 | + conn = l.svcCtx.DefaultDBConn() | ||
34 | + user *domain.User | ||
35 | + userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
36 | + limit = 6 | ||
37 | + ) | ||
38 | + if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil { | ||
39 | + return nil, xerr.NewErrMsgErr("用户不存在", err) | ||
40 | + } | ||
41 | + var ( | ||
42 | + users = user.Following | ||
43 | + setUsers = collection.NewSet() | ||
44 | + ) | ||
45 | + _, userArticlesUnread, _ := l.svcCtx.ArticleRepository.FindAuthorsLatestFirstUnreadArticle(l.ctx, conn, user.CompanyId, users, user.Id, limit) | ||
46 | + _, userArticlesLatest, _ := l.svcCtx.ArticleRepository.FindAuthorsLatestFirstArticle(l.ctx, conn, user.CompanyId, users, user.Id, limit) | ||
47 | + _, userFollows, _ := l.svcCtx.UserFollowRepository.Find(l.ctx, conn, domain.IndexCompanyId(userToken.CompanyId)().WithKV("fromUserId", user.Id).WithFindOnly()) | ||
48 | + resp = &types.MiniUserFollowedSearchResponse{ | ||
49 | + Total: int64(len(users)), | ||
50 | + List: make([]*types.UserFollowItem, 0), | ||
51 | + } | ||
52 | + addUser := func(userId int64, readFlag bool) { | ||
53 | + if setUsers.Contains(userId) { | ||
54 | + return | ||
55 | + } | ||
56 | + if len(resp.List) == limit { | ||
57 | + return | ||
58 | + } | ||
59 | + setUsers.Add(userId) | ||
60 | + if foundUser, _ := l.svcCtx.UserRepository.FindOne(l.ctx, conn, userId); foundUser != nil { | ||
61 | + resp.List = append(resp.List, &types.UserFollowItem{ | ||
62 | + Id: foundUser.Id, | ||
63 | + Name: foundUser.Name, | ||
64 | + Avatar: foundUser.Avatar, | ||
65 | + Position: foundUser.Position, | ||
66 | + ReadFlag: readFlag, | ||
67 | + }) | ||
68 | + } | ||
69 | + return | ||
70 | + } | ||
71 | + userFollowsMap := lo.KeyBy(userFollows, func(item *domain.UserFollow) int64 { | ||
72 | + return item.ToUserId | ||
73 | + }) | ||
74 | + lo.ForEach(userArticlesUnread, func(item *domain.Article, index int) { | ||
75 | + var readFlag = true | ||
76 | + if v, ok := userFollowsMap[item.AuthorId]; ok && v.LastReadAt < item.CreatedAt { | ||
77 | + readFlag = false | ||
78 | + } | ||
79 | + addUser(item.AuthorId, readFlag) | ||
80 | + }) | ||
81 | + lo.ForEach(userArticlesLatest, func(item *domain.Article, index int) { | ||
82 | + addUser(item.AuthorId, true) | ||
83 | + }) | ||
84 | + lo.ForEach(users, func(item int64, index int) { | ||
85 | + addUser(item, true) | ||
86 | + }) | ||
87 | + return | ||
88 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/db/transaction" | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/interanl/pkg/domain" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/contextdata" | ||
8 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/pkg/xerr" | ||
9 | + "time" | ||
10 | + | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
13 | + | ||
14 | + "github.com/zeromicro/go-zero/core/logx" | ||
15 | +) | ||
16 | + | ||
17 | +type MiniUserFollowingMarkReadLogic struct { | ||
18 | + logx.Logger | ||
19 | + ctx context.Context | ||
20 | + svcCtx *svc.ServiceContext | ||
21 | +} | ||
22 | + | ||
23 | +func NewMiniUserFollowingMarkReadLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniUserFollowingMarkReadLogic { | ||
24 | + return &MiniUserFollowingMarkReadLogic{ | ||
25 | + Logger: logx.WithContext(ctx), | ||
26 | + ctx: ctx, | ||
27 | + svcCtx: svcCtx, | ||
28 | + } | ||
29 | +} | ||
30 | + | ||
31 | +func (l *MiniUserFollowingMarkReadLogic) MiniUserFollowingMarkRead(req *types.MiniUserFollowingMarkReadRequest) (resp interface{}, err error) { | ||
32 | + var ( | ||
33 | + conn = l.svcCtx.DefaultDBConn() | ||
34 | + user *domain.User | ||
35 | + userFollow *domain.UserFollow | ||
36 | + userToken = contextdata.GetUserTokenFromCtx(l.ctx) | ||
37 | + ) | ||
38 | + if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil { | ||
39 | + return nil, xerr.NewErrMsgErr("用户不存在", err) | ||
40 | + } | ||
41 | + if userFollow, err = l.svcCtx.UserFollowRepository.FindOneUserFollowing(l.ctx, conn, userToken.UserId, user.Id); err != nil { | ||
42 | + return nil, xerr.NewErrMsgErr("用户还未关注", err) | ||
43 | + } | ||
44 | + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { | ||
45 | + userFollow.LastReadAt = time.Now().Unix() | ||
46 | + if userFollow, err = l.svcCtx.UserFollowRepository.UpdateWithVersion(ctx, conn, userFollow); err != nil { | ||
47 | + return err | ||
48 | + } | ||
49 | + return nil | ||
50 | + }, true); err != nil { | ||
51 | + return nil, xerr.NewErrMsgErr("关注用户标记已读失败", err) | ||
52 | + } | ||
53 | + resp = struct{}{} | ||
54 | + return | ||
55 | +} |
1 | +package user | ||
2 | + | ||
3 | +import ( | ||
4 | + "context" | ||
5 | + | ||
6 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/svc" | ||
7 | + "gitlab.fjmaimaimai.com/allied-creation/sumifcc-discuss/cmd/discuss/api/internal/types" | ||
8 | + | ||
9 | + "github.com/zeromicro/go-zero/core/logx" | ||
10 | +) | ||
11 | + | ||
12 | +type MiniUserNewsLogic struct { | ||
13 | + logx.Logger | ||
14 | + ctx context.Context | ||
15 | + svcCtx *svc.ServiceContext | ||
16 | +} | ||
17 | + | ||
18 | +func NewMiniUserNewsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MiniUserNewsLogic { | ||
19 | + return &MiniUserNewsLogic{ | ||
20 | + Logger: logx.WithContext(ctx), | ||
21 | + ctx: ctx, | ||
22 | + svcCtx: svcCtx, | ||
23 | + } | ||
24 | +} | ||
25 | + | ||
26 | +func (l *MiniUserNewsLogic) MiniUserNews(req *types.MiniUserNewsRequest) (resp *types.MiniUserNewsResposne, err error) { | ||
27 | + // todo: add your logic here and delete this line | ||
28 | + | ||
29 | + return | ||
30 | +} |
@@ -32,6 +32,7 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | @@ -32,6 +32,7 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | ||
32 | conn = l.svcCtx.DefaultDBConn() | 32 | conn = l.svcCtx.DefaultDBConn() |
33 | user *domain.User | 33 | user *domain.User |
34 | targetUser *domain.User | 34 | targetUser *domain.User |
35 | + userFollow *domain.UserFollow | ||
35 | userToken = contextdata.GetUserTokenFromCtx(l.ctx) | 36 | userToken = contextdata.GetUserTokenFromCtx(l.ctx) |
36 | ) | 37 | ) |
37 | if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil { | 38 | if user, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, userToken.UserId); err != nil { |
@@ -40,6 +41,9 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | @@ -40,6 +41,9 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | ||
40 | if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil { | 41 | if targetUser, err = l.svcCtx.UserRepository.FindOne(l.ctx, conn, req.UserId); err != nil { |
41 | return xerr.NewErrMsgErr("关注的用户不存在", err) | 42 | return xerr.NewErrMsgErr("关注的用户不存在", err) |
42 | } | 43 | } |
44 | + if userFollow, err = l.svcCtx.UserFollowRepository.FindOneUserFollowing(l.ctx, conn, user.Id, targetUser.Id); err != nil { | ||
45 | + return xerr.NewErrMsgErr("用户还未关注", err) | ||
46 | + } | ||
43 | if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { | 47 | if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { |
44 | if err = user.Unfollow(targetUser); err != nil { | 48 | if err = user.Unfollow(targetUser); err != nil { |
45 | return err | 49 | return err |
@@ -50,6 +54,9 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | @@ -50,6 +54,9 @@ func (l *MiniUserUnFollowLogic) MiniUserUnFollow(req *types.FollowRequest) (err | ||
50 | if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil { | 54 | if targetUser, err = l.svcCtx.UserRepository.UpdateWithVersion(ctx, conn, targetUser); err != nil { |
51 | return err | 55 | return err |
52 | } | 56 | } |
57 | + if userFollow, err = l.svcCtx.UserFollowRepository.Delete(ctx, conn, userFollow); err != nil { | ||
58 | + return err | ||
59 | + } | ||
53 | return nil | 60 | return nil |
54 | }, true); err != nil { | 61 | }, true); err != nil { |
55 | return xerr.NewErrMsgErr("关注用户失败", err) | 62 | return xerr.NewErrMsgErr("关注用户失败", err) |
@@ -330,6 +330,26 @@ type MiniUsersListRequest struct { | @@ -330,6 +330,26 @@ type MiniUsersListRequest struct { | ||
330 | RoleId int64 `json:"roleId,optional"` // 按角色角色关联的用户 | 330 | RoleId int64 `json:"roleId,optional"` // 按角色角色关联的用户 |
331 | } | 331 | } |
332 | 332 | ||
333 | +type MiniUserNewsRequest struct { | ||
334 | + AuthorId int64 `json:"authorId,optional"` // 特定作者ID | ||
335 | + LastArticleId int64 `json:"lastArticleId,optional"` // 最后文章ID | ||
336 | + Size int `json:"size"` // 数量 | ||
337 | +} | ||
338 | + | ||
339 | +type MiniUserNewsResposne struct { | ||
340 | + List []UserNewsItem `json:"list"` | ||
341 | + Total int64 `json:"total"` | ||
342 | +} | ||
343 | + | ||
344 | +type UserNewsItem struct { | ||
345 | + NewsId int64 `json:"newsId"` // 快讯ID | ||
346 | + Type string `json:"type"` // 快讯类型 文章:Article 讨论:Discuss ... | ||
347 | + Title string `json:"title"` // 标题 | ||
348 | + Summary string `json:"summary"` // 快讯概要 | ||
349 | + Time int64 `json:"time"` // 时间 | ||
350 | + ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读 | ||
351 | +} | ||
352 | + | ||
333 | type MiniUserFollowedSearchRequest struct { | 353 | type MiniUserFollowedSearchRequest struct { |
334 | Page int `json:"page,optional"` | 354 | Page int `json:"page,optional"` |
335 | Size int `json:"size,optional"` | 355 | Size int `json:"size,optional"` |
@@ -340,6 +360,10 @@ type MiniUserFollowedSearchResponse struct { | @@ -340,6 +360,10 @@ type MiniUserFollowedSearchResponse struct { | ||
340 | Total int64 `json:"total"` | 360 | Total int64 `json:"total"` |
341 | } | 361 | } |
342 | 362 | ||
363 | +type MiniUserFollowingMarkReadRequest struct { | ||
364 | + UserId int64 `json:"userId"` | ||
365 | +} | ||
366 | + | ||
343 | type UserItem struct { | 367 | type UserItem struct { |
344 | Id int64 `json:"id,omitempty"` // 用户ID | 368 | Id int64 `json:"id,omitempty"` // 用户ID |
345 | CompanyId int64 `json:"companyId,omitempty"` // 公司ID | 369 | CompanyId int64 `json:"companyId,omitempty"` // 公司ID |
@@ -397,6 +421,7 @@ type UserFollowItem struct { | @@ -397,6 +421,7 @@ type UserFollowItem struct { | ||
397 | Position string `json:"position"` // 职位 | 421 | Position string `json:"position"` // 职位 |
398 | Followed bool `json:"followed"` // 关注 | 422 | Followed bool `json:"followed"` // 关注 |
399 | MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识 | 423 | MutualFollowed bool `json:"mutualFollowed"` // 互相关注标识 |
424 | + ReadFlag bool `json:"readFlag"` // 已读标识 true:已读 false:未读(小红点) | ||
400 | } | 425 | } |
401 | 426 | ||
402 | type MiniMyLikeRequest struct { | 427 | type MiniMyLikeRequest struct { |
@@ -10,11 +10,13 @@ import ( | @@ -10,11 +10,13 @@ import ( | ||
10 | 10 | ||
11 | type UserFollow struct { | 11 | type UserFollow struct { |
12 | Id int64 // 唯一标识 | 12 | Id int64 // 唯一标识 |
13 | - | ||
14 | - CreatedAt int64 `json:"createdAt,omitempty"` | ||
15 | - UpdatedAt int64 `json:"updatedAt,omitempty"` | ||
16 | - DeletedAt int64 `json:"deletedAt,omitempty"` | ||
17 | - Version int `json:"version,omitempty"` | 13 | + FromUserId int64 |
14 | + ToUserId int64 | ||
15 | + LastReadAt int64 | ||
16 | + CreatedAt int64 | ||
17 | + UpdatedAt int64 | ||
18 | + DeletedAt int64 | ||
19 | + Version int | ||
18 | } | 20 | } |
19 | 21 | ||
20 | func (m *UserFollow) TableName() string { | 22 | func (m *UserFollow) TableName() string { |
@@ -156,6 +156,127 @@ func (repository *ArticleRepository) Find(ctx context.Context, conn transaction. | @@ -156,6 +156,127 @@ func (repository *ArticleRepository) Find(ctx context.Context, conn transaction. | ||
156 | return total, dms, nil | 156 | return total, dms, nil |
157 | } | 157 | } |
158 | 158 | ||
159 | +// FindAuthorsLatestArticle 作者最新的文章 | ||
160 | +func (repository *ArticleRepository) FindAuthorsLatestArticle(ctx context.Context, conn transaction.Conn, | ||
161 | + companyId int64, authors []int64, whoRead int64, lastId int64, limit int) (int64, []*domain.Article, error) { | ||
162 | + var ( | ||
163 | + tx = conn.DB() | ||
164 | + ms []*models.Article | ||
165 | + dms = make([]*domain.Article, 0) | ||
166 | + total int64 | ||
167 | + ) | ||
168 | + queryFunc := func() (interface{}, error) { | ||
169 | + tx = tx.Model(&ms). | ||
170 | + Where("id < ?", lastId). | ||
171 | + Where("company_id=?", companyId). | ||
172 | + Where("author_id in (?)", authors). | ||
173 | + Where("target_user=0 or who_read @>'[?]'", whoRead). | ||
174 | + Where("show = 1"). | ||
175 | + Order("id desc") | ||
176 | + if limit > 0 { | ||
177 | + tx.Limit(limit) | ||
178 | + } | ||
179 | + if total, tx = transaction.PaginationAndCount(ctx, tx, domain.NewQueryOptions().WithFindOnly(), &ms); tx.Error != nil { | ||
180 | + return dms, tx.Error | ||
181 | + } | ||
182 | + return dms, nil | ||
183 | + } | ||
184 | + | ||
185 | + if _, err := repository.Query(queryFunc); err != nil { | ||
186 | + return 0, nil, err | ||
187 | + } | ||
188 | + | ||
189 | + for _, item := range ms { | ||
190 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
191 | + return 0, dms, err | ||
192 | + } else { | ||
193 | + dms = append(dms, dm) | ||
194 | + } | ||
195 | + } | ||
196 | + return total, dms, nil | ||
197 | +} | ||
198 | + | ||
199 | +// FindAuthorsLatestFirstArticle 作者最新的第一篇文章 | ||
200 | +func (repository *ArticleRepository) FindAuthorsLatestFirstArticle(ctx context.Context, conn transaction.Conn, | ||
201 | + companyId int64, authors []int64, whoRead int64, limit int) (int64, []*domain.Article, error) { | ||
202 | + var ( | ||
203 | + tx = conn.DB() | ||
204 | + ms []*models.Article | ||
205 | + dms = make([]*domain.Article, 0) | ||
206 | + total int64 | ||
207 | + ) | ||
208 | + queryFunc := func() (interface{}, error) { | ||
209 | + tx = tx.Model(&ms).Select("max(id) id", "max(author_id) author_id", "max(created_at) created_at"). | ||
210 | + Where("company_id=?", companyId). | ||
211 | + Where("author_id in (?)", authors). | ||
212 | + Where("target_user=0 or who_read @>'[?]'", whoRead). | ||
213 | + Where("show = 1"). | ||
214 | + Group("author_id"). | ||
215 | + Order("id desc") | ||
216 | + if limit > 0 { | ||
217 | + tx.Limit(limit) | ||
218 | + } | ||
219 | + if total, tx = transaction.PaginationAndCount(ctx, tx, domain.NewQueryOptions().WithFindOnly(), &ms); tx.Error != nil { | ||
220 | + return dms, tx.Error | ||
221 | + } | ||
222 | + return dms, nil | ||
223 | + } | ||
224 | + | ||
225 | + if _, err := repository.Query(queryFunc); err != nil { | ||
226 | + return 0, nil, err | ||
227 | + } | ||
228 | + | ||
229 | + for _, item := range ms { | ||
230 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
231 | + return 0, dms, err | ||
232 | + } else { | ||
233 | + dms = append(dms, dm) | ||
234 | + } | ||
235 | + } | ||
236 | + return total, dms, nil | ||
237 | +} | ||
238 | + | ||
239 | +// FindAuthorsLatestFirstUnreadArticle 作者最新的第一篇未读文章 | ||
240 | +func (repository *ArticleRepository) FindAuthorsLatestFirstUnreadArticle(ctx context.Context, conn transaction.Conn, | ||
241 | + companyId int64, authors []int64, whoRead int64, limit int) (int64, []*domain.Article, error) { | ||
242 | + var ( | ||
243 | + tx = conn.DB() | ||
244 | + ms []*models.Article | ||
245 | + dms = make([]*domain.Article, 0) | ||
246 | + total int64 | ||
247 | + ) | ||
248 | + queryFunc := func() (interface{}, error) { | ||
249 | + tx = tx.Model(&ms).Select("max(id) id", "max(author_id) author_id", "max(created_at) created_at"). | ||
250 | + Where("company_id=?", companyId). | ||
251 | + Where("author_id in (?)", authors). | ||
252 | + Where("target_user=0 or who_read @>'[?]'", whoRead). | ||
253 | + Where("show = 1"). | ||
254 | + Where("id not in (select article_id from user_read_article where user_id = ?)", whoRead). | ||
255 | + Group("author_id"). | ||
256 | + Order("id desc") | ||
257 | + if limit > 0 { | ||
258 | + tx.Limit(limit) | ||
259 | + } | ||
260 | + if total, tx = transaction.PaginationAndCount(ctx, tx, domain.NewQueryOptions().WithFindOnly(), &ms); tx.Error != nil { | ||
261 | + return dms, tx.Error | ||
262 | + } | ||
263 | + return dms, nil | ||
264 | + } | ||
265 | + | ||
266 | + if _, err := repository.Query(queryFunc); err != nil { | ||
267 | + return 0, nil, err | ||
268 | + } | ||
269 | + | ||
270 | + for _, item := range ms { | ||
271 | + if dm, err := repository.ModelToDomainModel(item); err != nil { | ||
272 | + return 0, dms, err | ||
273 | + } else { | ||
274 | + dms = append(dms, dm) | ||
275 | + } | ||
276 | + } | ||
277 | + return total, dms, nil | ||
278 | +} | ||
279 | + | ||
159 | func (repository *ArticleRepository) ModelToDomainModel(from *models.Article) (*domain.Article, error) { | 280 | func (repository *ArticleRepository) ModelToDomainModel(from *models.Article) (*domain.Article, error) { |
160 | to := &domain.Article{ | 281 | to := &domain.Article{ |
161 | Id: from.Id, | 282 | Id: from.Id, |
@@ -111,6 +111,26 @@ func (repository *UserFollowRepository) FindOne(ctx context.Context, conn transa | @@ -111,6 +111,26 @@ func (repository *UserFollowRepository) FindOne(ctx context.Context, conn transa | ||
111 | return repository.ModelToDomainModel(m) | 111 | return repository.ModelToDomainModel(m) |
112 | } | 112 | } |
113 | 113 | ||
114 | +func (repository *UserFollowRepository) FindOneUserFollowing(ctx context.Context, conn transaction.Conn, userId int64, followingId int64) (*domain.UserFollow, error) { | ||
115 | + var ( | ||
116 | + err error | ||
117 | + tx = conn.DB() | ||
118 | + m = new(models.UserFollow) | ||
119 | + ) | ||
120 | + queryFunc := func() (interface{}, error) { | ||
121 | + tx = tx.Model(m).Where("from_user_id = ?", userId).Where("to_user_id = ?", followingId).First(m) | ||
122 | + if errors.Is(tx.Error, gorm.ErrRecordNotFound) { | ||
123 | + return nil, domain.ErrNotFound | ||
124 | + } | ||
125 | + return m, tx.Error | ||
126 | + } | ||
127 | + cacheModel := new(models.UserFollow) | ||
128 | + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil { | ||
129 | + return nil, err | ||
130 | + } | ||
131 | + return repository.ModelToDomainModel(m) | ||
132 | +} | ||
133 | + | ||
114 | func (repository *UserFollowRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserFollow, error) { | 134 | func (repository *UserFollowRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.UserFollow, error) { |
115 | var ( | 135 | var ( |
116 | tx = conn.DB() | 136 | tx = conn.DB() |
@@ -120,6 +140,12 @@ func (repository *UserFollowRepository) Find(ctx context.Context, conn transacti | @@ -120,6 +140,12 @@ func (repository *UserFollowRepository) Find(ctx context.Context, conn transacti | ||
120 | ) | 140 | ) |
121 | queryFunc := func() (interface{}, error) { | 141 | queryFunc := func() (interface{}, error) { |
122 | tx = tx.Model(&ms).Order("id desc") | 142 | tx = tx.Model(&ms).Order("id desc") |
143 | + if v, ok := queryOptions["fromUserId"]; ok { | ||
144 | + tx.Where("from_user_id = ?", v) | ||
145 | + } | ||
146 | + if v, ok := queryOptions["toUserIds"]; ok { | ||
147 | + tx.Where("to_user_id in (?)", v) | ||
148 | + } | ||
123 | if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil { | 149 | if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil { |
124 | return dms, tx.Error | 150 | return dms, tx.Error |
125 | } | 151 | } |
@@ -38,6 +38,8 @@ type ArticleRepository interface { | @@ -38,6 +38,8 @@ type ArticleRepository interface { | ||
38 | UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error) | 38 | UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *Article) (*Article, error) |
39 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Article, error) | 39 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*Article, error) |
40 | Find(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*Article, error) | 40 | Find(ctx context.Context, conn transaction.Conn, companyId int64, queryOptions map[string]interface{}) (int64, []*Article, error) |
41 | + FindAuthorsLatestFirstArticle(ctx context.Context, conn transaction.Conn, companyId int64, authors []int64, whoRead int64, limit int) (int64, []*Article, error) | ||
42 | + FindAuthorsLatestFirstUnreadArticle(ctx context.Context, conn transaction.Conn, companyId int64, authors []int64, whoRead int64, limit int) (int64, []*Article, error) | ||
41 | IncreaseCountLove(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //点赞数量变动 | 43 | IncreaseCountLove(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //点赞数量变动 |
42 | IncreaseCountComment(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //评论数量变动 | 44 | IncreaseCountComment(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //评论数量变动 |
43 | IncreaseCountRead(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //浏览数量变动 | 45 | IncreaseCountRead(ctx context.Context, conn transaction.Conn, incr int, articleId int64) error //浏览数量变动 |
@@ -7,8 +7,9 @@ import ( | @@ -7,8 +7,9 @@ import ( | ||
7 | 7 | ||
8 | type UserFollow struct { | 8 | type UserFollow struct { |
9 | Id int64 `json:"id,omitempty"` // 唯一标识 | 9 | Id int64 `json:"id,omitempty"` // 唯一标识 |
10 | - FromUserId int64 `json:"fromUserId,omitempty"` /// 发起关注的人 | ||
11 | - ToUserId int64 `json:"toUserId,omitempty"` /// 被关注的人 | 10 | + FromUserId int64 `json:"fromUserId,omitempty"` // 发起关注的人 |
11 | + ToUserId int64 `json:"toUserId,omitempty"` // 被关注的人 | ||
12 | + LastReadAt int64 `json:"lastReadAt,omitempty"` // 上一次读取信息时间 | ||
12 | CreatedAt int64 `json:"createdAt,omitempty"` | 13 | CreatedAt int64 `json:"createdAt,omitempty"` |
13 | UpdatedAt int64 `json:"updatedAt,omitempty"` | 14 | UpdatedAt int64 `json:"updatedAt,omitempty"` |
14 | DeletedAt int64 `json:"deletedAt,omitempty"` | 15 | DeletedAt int64 `json:"deletedAt,omitempty"` |
@@ -21,6 +22,7 @@ type UserFollowRepository interface { | @@ -21,6 +22,7 @@ type UserFollowRepository interface { | ||
21 | UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error) | 22 | UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error) |
22 | Delete(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error) | 23 | Delete(ctx context.Context, conn transaction.Conn, dm *UserFollow) (*UserFollow, error) |
23 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserFollow, error) | 24 | FindOne(ctx context.Context, conn transaction.Conn, id int64) (*UserFollow, error) |
25 | + FindOneUserFollowing(ctx context.Context, conn transaction.Conn, userId int64, followingId int64) (*UserFollow, error) | ||
24 | Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserFollow, error) | 26 | Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*UserFollow, error) |
25 | } | 27 | } |
26 | 28 |
-
请 注册 或 登录 后发表评论