Skip to content

Commit 3cb2116

Browse files
authored
Merge pull request #620 from chaitin/feat-member-manager
feat: 定义团队成员接口
2 parents 191546f + 0db7ad2 commit 3cb2116

6 files changed

Lines changed: 17 additions & 521 deletions

File tree

backend/biz/team/handler/http/v1/user.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ type TeamGroupUserHandler struct {
2525
auditMiddleware *middleware.AuditMiddleware
2626
logger *slog.Logger
2727
captcha *captcha.Captcha
28+
memberManager domain.MemberManager
2829
}
2930

3031
// NewTeamGroupUserHandler 创建团队分组用户处理器 (samber/do 风格)
@@ -42,6 +43,7 @@ func NewTeamGroupUserHandler(i *do.Injector) (*TeamGroupUserHandler, error) {
4243
auditMiddleware: audit,
4344
logger: logger.With("module", "handler.team_group_user"),
4445
captcha: do.MustInvoke[*captcha.Captcha](i),
46+
memberManager: do.MustInvoke[domain.MemberManager](i),
4547
}
4648

4749
adminAuth := middleware.TeamAdminAuth(func(ctx context.Context, teamID, userID uuid.UUID) bool {
@@ -205,7 +207,7 @@ func (h *TeamGroupUserHandler) ChangePassword(c *web.Context, req domain.ChangeP
205207
// @Router /api/v1/teams/users [post]
206208
func (h *TeamGroupUserHandler) AddUser(c *web.Context, req domain.AddTeamUserReq) error {
207209
teamUser := middleware.GetTeamUser(c)
208-
resp, err := h.usecase.AddUser(c.Request().Context(), teamUser, &req)
210+
resp, err := h.memberManager.AddUser(c.Request().Context(), teamUser, &req)
209211
if err != nil {
210212
return err
211213
}
@@ -227,7 +229,7 @@ func (h *TeamGroupUserHandler) AddUser(c *web.Context, req domain.AddTeamUserReq
227229
// @Router /api/v1/teams/users/with-password [post]
228230
func (h *TeamGroupUserHandler) AddUserWithPassword(c *web.Context, req domain.AddTeamUserReq) error {
229231
teamUser := middleware.GetTeamUser(c)
230-
resp, err := h.usecase.AddUserWithPassword(c.Request().Context(), teamUser, &req)
232+
resp, err := h.memberManager.AddUserWithPassword(c.Request().Context(), teamUser, &req)
231233
if err != nil {
232234
return err
233235
}
@@ -249,7 +251,7 @@ func (h *TeamGroupUserHandler) AddUserWithPassword(c *web.Context, req domain.Ad
249251
// @Router /api/v1/teams/admin [post]
250252
func (h *TeamGroupUserHandler) AddAdmin(c *web.Context, req domain.AddTeamAdminReq) error {
251253
teamUser := middleware.GetTeamUser(c)
252-
resp, err := h.usecase.AddAdmin(c.Request().Context(), teamUser, &req)
254+
resp, err := h.memberManager.AddAdmin(c.Request().Context(), teamUser, &req)
253255
if err != nil {
254256
return err
255257
}

backend/biz/team/repo/user.go

Lines changed: 0 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -71,146 +71,6 @@ func (r *TeamGroupUserRepo) Create(ctx context.Context, teamID uuid.UUID, req *d
7171
Save(ctx)
7272
}
7373

74-
// CreateUsers 创建团队成员
75-
func (r *TeamGroupUserRepo) CreateUsers(ctx context.Context, teamID uuid.UUID, req *domain.AddTeamUserReq) ([]*db.User, error) {
76-
if err := r.checkTeamMemberLimit(ctx, teamID, req.Emails); err != nil {
77-
return nil, err
78-
}
79-
80-
var users []*db.User
81-
82-
for _, emailAddr := range req.Emails {
83-
// 检查邮箱是否已注册
84-
existingUser, err := r.db.User.Query().Where(user.EmailEQ(emailAddr)).First(ctx)
85-
if err == nil && existingUser != nil {
86-
// 用户已存在,检查是否已在团队中
87-
_, err := r.db.TeamMember.Query().Where(
88-
teammember.TeamIDEQ(teamID),
89-
teammember.UserIDEQ(existingUser.ID),
90-
).First(ctx)
91-
if err == nil {
92-
continue // 用户已在团队中
93-
}
94-
// 添加到团队
95-
_, err = r.db.TeamMember.Create().
96-
SetTeamID(teamID).
97-
SetUserID(existingUser.ID).
98-
SetRole(consts.TeamMemberRoleUser).
99-
Save(ctx)
100-
if err != nil {
101-
r.logger.ErrorContext(ctx, "add user to team failed", "error", err)
102-
continue
103-
}
104-
users = append(users, existingUser)
105-
continue
106-
}
107-
108-
// 创建新用户
109-
newUser, err := r.db.User.Create().
110-
SetName(emailAddr).
111-
SetEmail(emailAddr).
112-
SetStatus(consts.UserStatusActive).
113-
SetPassword("").
114-
SetRole(consts.UserRoleSubAccount).
115-
Save(ctx)
116-
if err != nil {
117-
r.logger.ErrorContext(ctx, "create user failed", "error", err, "email", emailAddr)
118-
continue
119-
}
120-
121-
// 添加到团队
122-
_, err = r.db.TeamMember.Create().
123-
SetTeamID(teamID).
124-
SetUserID(newUser.ID).
125-
SetRole(consts.TeamMemberRoleUser).
126-
Save(ctx)
127-
if err != nil {
128-
r.logger.ErrorContext(ctx, "add user to team failed", "error", err)
129-
continue
130-
}
131-
users = append(users, newUser)
132-
}
133-
return users, nil
134-
}
135-
136-
func (r *TeamGroupUserRepo) CreateUsersWithPassword(ctx context.Context, teamID uuid.UUID, req *domain.AddTeamUserWithPasswordReq) ([]*db.User, error) {
137-
if err := r.checkTeamMemberLimit(ctx, teamID, req.Emails); err != nil {
138-
return nil, err
139-
}
140-
141-
var users []*db.User
142-
143-
for _, emailAddr := range req.Emails {
144-
existingUser, err := r.db.User.Query().Where(user.EmailEQ(emailAddr)).First(ctx)
145-
if err == nil && existingUser != nil {
146-
_, err := r.db.TeamMember.Query().Where(
147-
teammember.TeamIDEQ(teamID),
148-
teammember.UserIDEQ(existingUser.ID),
149-
).First(ctx)
150-
if err == nil {
151-
continue
152-
}
153-
if existingUser.Password == "" {
154-
hashedPassword, err := crypto.HashPassword(req.Passwords[emailAddr])
155-
if err != nil {
156-
r.logger.ErrorContext(ctx, "hash password failed", "error", err, "email", emailAddr)
157-
continue
158-
}
159-
existingUser, err = r.db.User.UpdateOneID(existingUser.ID).
160-
SetPassword(hashedPassword).
161-
Save(ctx)
162-
if err != nil {
163-
r.logger.ErrorContext(ctx, "set user password failed", "error", err, "email", emailAddr)
164-
continue
165-
}
166-
}
167-
_, err = r.db.TeamMember.Create().
168-
SetID(uuid.New()).
169-
SetTeamID(teamID).
170-
SetUserID(existingUser.ID).
171-
SetRole(consts.TeamMemberRoleUser).
172-
Save(ctx)
173-
if err != nil {
174-
r.logger.ErrorContext(ctx, "add user to team failed", "error", err)
175-
continue
176-
}
177-
users = append(users, existingUser)
178-
continue
179-
}
180-
181-
hashedPassword, err := crypto.HashPassword(req.Passwords[emailAddr])
182-
if err != nil {
183-
r.logger.ErrorContext(ctx, "hash password failed", "error", err, "email", emailAddr)
184-
continue
185-
}
186-
newUser, err := r.db.User.Create().
187-
SetID(uuid.New()).
188-
SetName(emailAddr).
189-
SetEmail(emailAddr).
190-
SetStatus(consts.UserStatusActive).
191-
SetPassword(hashedPassword).
192-
SetRole(consts.UserRoleSubAccount).
193-
Save(ctx)
194-
if err != nil {
195-
r.logger.ErrorContext(ctx, "create user failed", "error", err, "email", emailAddr)
196-
continue
197-
}
198-
199-
_, err = r.db.TeamMember.Create().
200-
SetID(uuid.New()).
201-
SetTeamID(teamID).
202-
SetUserID(newUser.ID).
203-
SetRole(consts.TeamMemberRoleUser).
204-
Save(ctx)
205-
if err != nil {
206-
r.logger.ErrorContext(ctx, "add user to team failed", "error", err)
207-
continue
208-
}
209-
users = append(users, newUser)
210-
}
211-
return users, nil
212-
}
213-
21474
func (r *TeamGroupUserRepo) ResetPassword(ctx context.Context, userID uuid.UUID, newPassword string) error {
21575
hashedPassword, err := crypto.HashPassword(newPassword)
21676
if err != nil {
@@ -219,84 +79,6 @@ func (r *TeamGroupUserRepo) ResetPassword(ctx context.Context, userID uuid.UUID,
21979
return r.db.User.UpdateOneID(userID).SetPassword(hashedPassword).Exec(ctx)
22080
}
22181

222-
// CreateAdmin 创建团队管理员
223-
func (r *TeamGroupUserRepo) CreateAdmin(ctx context.Context, teamID uuid.UUID, req *domain.AddTeamAdminReq) (*db.User, error) {
224-
if err := r.checkTeamMemberLimit(ctx, teamID, []string{req.Email}); err != nil {
225-
return nil, err
226-
}
227-
228-
// 检查邮箱是否已注册
229-
existingUser, err := r.db.User.Query().Where(user.EmailEQ(req.Email)).First(ctx)
230-
if err == nil && existingUser != nil {
231-
// 检查是否已在团队中
232-
_, err := r.db.TeamMember.Query().Where(
233-
teammember.TeamIDEQ(teamID),
234-
teammember.UserIDEQ(existingUser.ID),
235-
).First(ctx)
236-
if err == nil {
237-
return nil, errcode.ErrUserAlreadyExists
238-
}
239-
// 添加到团队
240-
_, err = r.db.TeamMember.Create().
241-
SetTeamID(teamID).
242-
SetUserID(existingUser.ID).
243-
SetRole(consts.TeamMemberRoleAdmin).
244-
Save(ctx)
245-
if err != nil {
246-
return nil, err
247-
}
248-
return existingUser, nil
249-
}
250-
251-
// 创建新用户
252-
newUser, err := r.db.User.Create().
253-
SetName(req.Name).
254-
SetEmail(req.Email).
255-
SetPassword("").
256-
SetRole(consts.UserRoleIndividual).
257-
Save(ctx)
258-
if err != nil {
259-
return nil, err
260-
}
261-
262-
// 添加到团队
263-
_, err = r.db.TeamMember.Create().
264-
SetTeamID(teamID).
265-
SetUserID(newUser.ID).
266-
SetRole(consts.TeamMemberRoleAdmin).
267-
Save(ctx)
268-
if err != nil {
269-
return nil, err
270-
}
271-
return newUser, nil
272-
}
273-
274-
func (r *TeamGroupUserRepo) checkTeamMemberLimit(ctx context.Context, teamID uuid.UUID, emails []string) error {
275-
team, err := r.db.Team.Get(ctx, teamID)
276-
if err != nil {
277-
return err
278-
}
279-
if team.MemberLimit <= 0 {
280-
return nil
281-
}
282-
283-
existingCount, err := r.db.TeamMember.Query().
284-
Where(teammember.TeamIDEQ(teamID)).
285-
Count(ctx)
286-
if err != nil {
287-
return err
288-
}
289-
290-
addCount, err := r.countNewTeamMembers(ctx, teamID, emails)
291-
if err != nil {
292-
return err
293-
}
294-
if existingCount+addCount > team.MemberLimit {
295-
return errcode.ErrTeamMemberLimitExceeded
296-
}
297-
return nil
298-
}
299-
30082
func (r *TeamGroupUserRepo) countNewTeamMembers(ctx context.Context, teamID uuid.UUID, emails []string) (int, error) {
30183
seen := make(map[string]struct{}, len(emails))
30284
count := 0

0 commit comments

Comments
 (0)