Skip to content

Commit cf4c5e9

Browse files
authored
Merge pull request #672 from actiontech/dms/feat-980
fix: 用户仅加入成员组时用户中心「所属项目」不显示该项目
2 parents 69554cc + ac19a7b commit cf4c5e9

2 files changed

Lines changed: 80 additions & 1 deletion

File tree

‎internal/dms/storage/convert.go‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,9 +255,15 @@ func convertModelUser(u *model.User) (*biz.User, error) {
255255
}
256256

257257
projects := make([]string, 0)
258+
seenProjects := make(map[string]struct{})
258259
for _, member := range u.Members {
259260
if member != nil && member.Project != nil {
260-
projects = append(projects, member.Project.Name)
261+
name := member.Project.Name
262+
if _, ok := seenProjects[name]; ok {
263+
continue
264+
}
265+
seenProjects[name] = struct{}{}
266+
projects = append(projects, name)
261267
}
262268
}
263269

‎internal/dms/storage/user.go‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,82 @@ func (d *UserRepo) ListUsers(ctx context.Context, opt *biz.ListUsersOption) (use
189189
}
190190
users = append(users, ds)
191191
}
192+
193+
// Batch fill projects = direct members ∪ member groups (same semantics as GetUserProject; no N+1).
194+
uids := make([]string, 0, len(users))
195+
for _, u := range users {
196+
if u != nil && u.UID != "" {
197+
uids = append(uids, u.UID)
198+
}
199+
}
200+
projectNamesByUID, err := d.listProjectNamesByUserUIDs(ctx, uids)
201+
if err != nil {
202+
return nil, 0, pkgErr.WrapStorageErr(d.log, err)
203+
}
204+
for _, u := range users {
205+
if u == nil {
206+
continue
207+
}
208+
if names, ok := projectNamesByUID[u.UID]; ok {
209+
u.Projects = names
210+
} else {
211+
u.Projects = []string{}
212+
}
213+
}
192214
return users, total, nil
193215
}
194216

217+
type userProjectNameRow struct {
218+
UserUID string `gorm:"column:user_uid"`
219+
ProjectName string `gorm:"column:project_name"`
220+
}
221+
222+
// listProjectNamesByUserUIDs returns project names per user UID in one query
223+
// (members UNION member_groups via member_group_users), matching GetUserProject set semantics.
224+
func (d *UserRepo) listProjectNamesByUserUIDs(ctx context.Context, uids []string) (map[string][]string, error) {
225+
result := make(map[string][]string)
226+
if len(uids) == 0 {
227+
return result, nil
228+
}
229+
230+
var rows []userProjectNameRow
231+
if err := transaction(d.log, ctx, d.db, func(tx *gorm.DB) error {
232+
if err := tx.WithContext(ctx).Raw(`
233+
SELECT m.user_uid AS user_uid, n.name AS project_name
234+
FROM projects n
235+
JOIN members m ON n.uid = m.project_uid
236+
WHERE m.user_uid IN (?)
237+
UNION
238+
SELECT mgu.user_uid AS user_uid, n.name AS project_name
239+
FROM projects n
240+
JOIN member_groups mg ON n.uid = mg.project_uid
241+
JOIN member_group_users mgu ON mgu.member_group_uid = mg.uid
242+
WHERE mgu.user_uid IN (?)
243+
`, uids, uids).Scan(&rows).Error; err != nil {
244+
return fmt.Errorf("failed to list project names by user uids: %v", err)
245+
}
246+
return nil
247+
}); err != nil {
248+
return nil, err
249+
}
250+
251+
seen := make(map[string]map[string]struct{}, len(uids))
252+
for _, row := range rows {
253+
if row.UserUID == "" || row.ProjectName == "" {
254+
continue
255+
}
256+
if _, ok := seen[row.UserUID]; !ok {
257+
seen[row.UserUID] = make(map[string]struct{})
258+
}
259+
if _, dup := seen[row.UserUID][row.ProjectName]; dup {
260+
continue
261+
}
262+
seen[row.UserUID][row.ProjectName] = struct{}{}
263+
result[row.UserUID] = append(result[row.UserUID], row.ProjectName)
264+
}
265+
return result, nil
266+
}
267+
195268
func (d *UserRepo) CountUsers(ctx context.Context, opts []constant.FilterCondition) (total int64, err error) {
196269
if err := transaction(d.log, ctx, d.db, func(tx *gorm.DB) error {
197270
// find total

0 commit comments

Comments
 (0)