Skip to content

Commit 3a9c10e

Browse files
committed
feat(team): add team name uniqueness check and related functionalities
- Add CheckNameUnique method to Team interface and implement it in teamRepoImpl - Add FindByName method to Team interface and implement it in teamRepoImpl - Modify SaveTeam method to check for team name uniqueness before saving - Update Create and Update methods in teamRepoImpl to return errors instead of team objects - Add CONFLICT error type in i18n files and err.proto
1 parent 5961634 commit 3a9c10e

7 files changed

Lines changed: 89 additions & 44 deletions

File tree

cmd/palace/internal/biz/repository/team.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ import (
99

1010
type Team interface {
1111
FindByID(ctx context.Context, id uint32) (do.Team, error)
12-
Create(ctx context.Context, team bo.CreateTeamRequest) (do.Team, error)
13-
Update(ctx context.Context, team bo.UpdateTeamRequest) (do.Team, error)
12+
Create(ctx context.Context, team bo.CreateTeamRequest) error
13+
Update(ctx context.Context, team bo.UpdateTeamRequest) error
1414
Delete(ctx context.Context, id uint32) error
1515
List(ctx context.Context, req *bo.TeamListRequest) (*bo.TeamListReply, error)
16+
CheckNameUnique(ctx context.Context, name string, teamID uint32) error
17+
FindByName(ctx context.Context, name string) (do.Team, error)
1618
}

cmd/palace/internal/biz/team.go

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -128,31 +128,12 @@ func (t *Team) getTeamMembers(ctx context.Context, ids []uint32) []do.TeamMember
128128
}
129129

130130
func (t *Team) SaveTeam(ctx context.Context, req *bo.SaveOneTeamRequest) error {
131+
// check team name is unique
132+
if err := t.teamRepo.CheckNameUnique(ctx, req.GetName(), req.TeamID); err != nil {
133+
return err
134+
}
135+
131136
return t.transaction.MainExec(ctx, func(ctx context.Context) error {
132-
var (
133-
teamDo do.Team
134-
err error
135-
)
136-
defer func() {
137-
if err != nil {
138-
t.helper.WithContext(ctx).Errorw("msg", "save team fail", "err", err)
139-
return
140-
}
141-
if err = t.userRepo.AppendTeam(ctx, teamDo); err != nil {
142-
t.helper.WithContext(ctx).Errorw("msg", "append team to user fail", "err", err)
143-
return
144-
}
145-
createMemberParams := &bo.CreateTeamMemberReq{
146-
Team: teamDo,
147-
User: teamDo.GetLeader(),
148-
Status: vobj.MemberStatusNormal,
149-
Position: vobj.PositionSuperAdmin,
150-
}
151-
if err := t.memberRepo.Create(ctx, createMemberParams); err != nil {
152-
t.helper.WithContext(ctx).Errorw("msg", "create team member fail", "err", err)
153-
return
154-
}
155-
}()
156137
if req.TeamID <= 0 {
157138
leaderId, ok := permission.GetUserIDByContext(ctx)
158139
if !ok {
@@ -163,16 +144,39 @@ func (t *Team) SaveTeam(ctx context.Context, req *bo.SaveOneTeamRequest) error {
163144
return err
164145
}
165146
createParams := req.WithCreateTeamRequest(leaderDo)
166-
teamDo, err = t.teamRepo.Create(ctx, createParams)
167-
return err
147+
if err := t.teamRepo.Create(ctx, createParams); err != nil {
148+
return err
149+
}
150+
} else {
151+
teamInfo, err := t.teamRepo.FindByID(ctx, req.TeamID)
152+
if err != nil {
153+
return err
154+
}
155+
updateTeamParams := req.WithUpdateTeamRequest(teamInfo)
156+
if err := t.teamRepo.Update(ctx, updateTeamParams); err != nil {
157+
return err
158+
}
168159
}
169-
teamInfo, err := t.teamRepo.FindByID(ctx, req.TeamID)
160+
teamDo, err := t.teamRepo.FindByName(ctx, req.GetName())
170161
if err != nil {
171162
return err
172163
}
173-
updateTeamParams := req.WithUpdateTeamRequest(teamInfo)
174-
teamDo, err = t.teamRepo.Update(ctx, updateTeamParams)
175-
return err
164+
165+
if err := t.userRepo.AppendTeam(ctx, teamDo); err != nil {
166+
t.helper.WithContext(ctx).Errorw("msg", "append team to user fail", "err", err)
167+
return err
168+
}
169+
createMemberParams := &bo.CreateTeamMemberReq{
170+
Team: teamDo,
171+
User: teamDo.GetLeader(),
172+
Status: vobj.MemberStatusNormal,
173+
Position: vobj.PositionSuperAdmin,
174+
}
175+
if err := t.memberRepo.Create(ctx, createMemberParams); err != nil {
176+
t.helper.WithContext(ctx).Errorw("msg", "create team member fail", "err", err)
177+
return err
178+
}
179+
return nil
176180
})
177181
}
178182

cmd/palace/internal/data/impl/team.go

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@ package impl
33
import (
44
"context"
55

6+
"github.com/go-kratos/kratos/v2/errors"
67
"github.com/go-kratos/kratos/v2/log"
78
"gorm.io/gen"
89
"gorm.io/gen/field"
10+
"gorm.io/gorm"
911

1012
"github.com/aide-family/moon/cmd/palace/internal/biz/bo"
1113
"github.com/aide-family/moon/cmd/palace/internal/biz/do"
1214
"github.com/aide-family/moon/cmd/palace/internal/biz/do/system"
1315
"github.com/aide-family/moon/cmd/palace/internal/biz/repository"
1416
"github.com/aide-family/moon/cmd/palace/internal/biz/vobj"
1517
"github.com/aide-family/moon/cmd/palace/internal/data"
18+
"github.com/aide-family/moon/pkg/merr"
1619
"github.com/aide-family/moon/pkg/util/crypto"
1720
"github.com/aide-family/moon/pkg/util/slices"
1821
"github.com/aide-family/moon/pkg/util/validate"
@@ -30,7 +33,7 @@ type teamRepoImpl struct {
3033
helper *log.Helper
3134
}
3235

33-
func (r *teamRepoImpl) Create(ctx context.Context, team bo.CreateTeamRequest) (do.Team, error) {
36+
func (r *teamRepoImpl) Create(ctx context.Context, team bo.CreateTeamRequest) error {
3437
teamMutation := getMainQuery(ctx, r).Team
3538
teamDo := &system.Team{
3639
Name: team.GetName(),
@@ -47,13 +50,10 @@ func (r *teamRepoImpl) Create(ctx context.Context, team bo.CreateTeamRequest) (d
4750
AlarmDBConfig: crypto.NewObject(team.GetAlarmDBConfig()),
4851
}
4952
teamDo.WithContext(ctx)
50-
if err := teamMutation.WithContext(ctx).Create(teamDo); err != nil {
51-
return nil, err
52-
}
53-
return teamDo, nil
53+
return teamMutation.WithContext(ctx).Create(teamDo)
5454
}
5555

56-
func (r *teamRepoImpl) Update(ctx context.Context, team bo.UpdateTeamRequest) (do.Team, error) {
56+
func (r *teamRepoImpl) Update(ctx context.Context, team bo.UpdateTeamRequest) error {
5757
teamMutation := getMainQuery(ctx, r).Team
5858
wrappers := []gen.Condition{
5959
teamMutation.ID.Eq(team.GetTeam().GetID()),
@@ -64,10 +64,7 @@ func (r *teamRepoImpl) Update(ctx context.Context, team bo.UpdateTeamRequest) (d
6464
teamMutation.Logo.Value(team.GetLogo()),
6565
}
6666
_, err := teamMutation.WithContext(ctx).Where(wrappers...).UpdateColumnSimple(mutations...)
67-
if err != nil {
68-
return nil, err
69-
}
70-
return r.FindByID(ctx, team.GetTeam().GetID())
67+
return err
7168
}
7269

7370
func (r *teamRepoImpl) Delete(ctx context.Context, id uint32) error {
@@ -81,7 +78,7 @@ func (r *teamRepoImpl) Delete(ctx context.Context, id uint32) error {
8178

8279
func (r *teamRepoImpl) FindByID(ctx context.Context, id uint32) (do.Team, error) {
8380
systemQuery := getMainQuery(ctx, r).Team
84-
teamDo, err := systemQuery.WithContext(ctx).Where(systemQuery.ID.Eq(id)).First()
81+
teamDo, err := systemQuery.WithContext(ctx).Preload(field.Associations).Where(systemQuery.ID.Eq(id)).First()
8582
if err != nil {
8683
return nil, teamNotFound(err)
8784
}
@@ -91,7 +88,7 @@ func (r *teamRepoImpl) FindByID(ctx context.Context, id uint32) (do.Team, error)
9188
func (r *teamRepoImpl) List(ctx context.Context, req *bo.TeamListRequest) (*bo.TeamListReply, error) {
9289
query := getMainQuery(ctx, r)
9390
teamQuery := query.Team
94-
wrapper := teamQuery.WithContext(ctx)
91+
wrapper := teamQuery.WithContext(ctx).Preload(field.Associations)
9592
if !validate.TextIsNull(req.Keyword) {
9693
wrapper = wrapper.Where(teamQuery.Name.Like(req.Keyword))
9794
}
@@ -138,3 +135,35 @@ func (r *teamRepoImpl) List(ctx context.Context, req *bo.TeamListRequest) (*bo.T
138135
rows := slices.Map(teamDos, func(teamDo *system.Team) do.Team { return teamDo })
139136
return req.ToListReply(rows), nil
140137
}
138+
139+
func (r *teamRepoImpl) CheckNameUnique(ctx context.Context, name string, teamID uint32) error {
140+
teamQuery := getMainQuery(ctx, r).Team
141+
wrapper := teamQuery.WithContext(ctx)
142+
if teamID > 0 {
143+
wrapper = wrapper.Where(teamQuery.ID.Neq(teamID))
144+
}
145+
teamDo, err := wrapper.Where(teamQuery.Name.Eq(name)).First()
146+
if err != nil {
147+
if errors.Is(err, gorm.ErrRecordNotFound) {
148+
return nil
149+
}
150+
return err
151+
}
152+
if teamDo != nil {
153+
return merr.ErrorConflict("team name already exists")
154+
}
155+
return nil
156+
}
157+
158+
func (r *teamRepoImpl) FindByName(ctx context.Context, name string) (do.Team, error) {
159+
teamQuery := getMainQuery(ctx, r).Team
160+
wrapper := teamQuery.WithContext(ctx).Preload(field.Associations)
161+
teamDo, err := wrapper.Where(teamQuery.Name.Eq(name)).First()
162+
if err != nil {
163+
return nil, teamNotFound(err)
164+
}
165+
if teamDo == nil {
166+
return nil, merr.ErrorNotFound("team not found")
167+
}
168+
return teamDo, nil
169+
}

i18n/en.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ other = "Resource not open"
5555
[REQUIRED]
5656
other = "Params is required"
5757

58+
[CONFLICT]
59+
other = ""
60+
5861
[UNAUTHORIZED]
5962
other = "Unauthorized"
6063

i18n/ja.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ other = "リソースが開放されていません"
5555
[REQUIRED]
5656
other = "パラメーターが必須です"
5757

58+
[CONFLICT]
59+
other = ""
60+
5861
[UNAUTHORIZED]
5962
other = "未認証"
6063

i18n/zh.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ other = "资源未开放"
5555
[REQUIRED]
5656
other = "参数不能为空"
5757

58+
[CONFLICT]
59+
other = ""
60+
5861
[UNAUTHORIZED]
5962
other = "未授权"
6063

proto/api/merr/err.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum ClientError {
1818
EXIST = 7;
1919
RESOURCE_NOT_OPEN = 8;
2020
REQUIRED = 9;
21+
CONFLICT = 10;
2122
}
2223

2324
enum UnauthorizedError {

0 commit comments

Comments
 (0)