@@ -5,8 +5,10 @@ import (
55 "fmt"
66 "log/slog"
77 "strings"
8+ "time"
89
910 "github.com/google/uuid"
11+ "github.com/patrickmn/go-cache"
1012 "github.com/samber/do"
1113
1214 "github.com/chaitin/MonkeyCode/backend/config"
@@ -15,6 +17,7 @@ import (
1517 "github.com/chaitin/MonkeyCode/backend/domain"
1618 "github.com/chaitin/MonkeyCode/backend/errcode"
1719 "github.com/chaitin/MonkeyCode/backend/pkg/cvt"
20+ gitpkg "github.com/chaitin/MonkeyCode/backend/pkg/git"
1821 "github.com/chaitin/MonkeyCode/backend/pkg/git/gitea"
1922 "github.com/chaitin/MonkeyCode/backend/pkg/git/gitee"
2023 "github.com/chaitin/MonkeyCode/backend/pkg/git/github"
@@ -27,6 +30,7 @@ type GitIdentityUsecase struct {
2730 repo domain.GitIdentityRepo
2831 tokenProvider * TokenProvider
2932 logger * slog.Logger
33+ repoCache * cache.Cache
3034}
3135
3236// NewGitIdentityUsecase 创建 Git 身份认证用例
@@ -36,6 +40,7 @@ func NewGitIdentityUsecase(i *do.Injector) (domain.GitIdentityUsecase, error) {
3640 repo : do.MustInvoke [domain.GitIdentityRepo ](i ),
3741 tokenProvider : do.MustInvoke [* TokenProvider ](i ),
3842 logger : do.MustInvoke [* slog.Logger ](i ).With ("module" , "GitIdentityUsecase" ),
43+ repoCache : cache .New (7 * 24 * time .Hour , 10 * time .Minute ),
3944 }, nil
4045}
4146
@@ -47,45 +52,29 @@ func (u *GitIdentityUsecase) List(ctx context.Context, uid uuid.UUID) ([]*domain
4752 return nil , err
4853 }
4954 return cvt .Iter (identities , func (_ int , identity * db.GitIdentity ) * domain.GitIdentity {
50- tmp := cvt .From (identity , & domain.GitIdentity {})
51- if client := u .gitClienter (identity ); client != nil {
52- token , err := u .tokenProvider .GetToken (ctx , identity .ID )
53- if err != nil {
54- u .logger .WarnContext (ctx , "failed to get token" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
55- return tmp
56- }
57- repos , err := client .Repositories (ctx , & domain.RepositoryOptions {
58- Token : token ,
59- InstallID : identity .InstallationID ,
60- IsOAuth : identity .OauthRefreshToken != "" ,
61- })
62- if err != nil {
63- u .logger .WarnContext (ctx , "failed to get authorized repositories" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
64- } else {
65- tmp .AuthorizedRepositories = repos
66- }
67- }
68- return tmp
55+ return cvt .From (identity , & domain.GitIdentity {})
6956 }), nil
7057}
7158
7259func (u * GitIdentityUsecase ) gitClienter (identity * db.GitIdentity ) domain.GitClienter {
60+ var inner domain.GitClienter
7361 switch identity .Platform {
7462 case consts .GitPlatformGithub :
75- return github .NewGithub (u .logger , u .cfg )
63+ inner = github .NewGithub (u .logger , u .cfg )
7664 case consts .GitPlatformGitLab :
77- return gitlab .NewGitlabForBaseURL (identity .BaseURL , u .logger )
65+ inner = gitlab .NewGitlabForBaseURL (identity .BaseURL , u .logger )
7866 case consts .GitPlatformGitea :
79- return gitea .NewGitea (u .logger , identity .BaseURL )
67+ inner = gitea .NewGitea (u .logger , identity .BaseURL )
8068 case consts .GitPlatformGitee :
81- return gitee .NewGitee (identity .BaseURL , u .logger )
69+ inner = gitee .NewGitee (identity .BaseURL , u .logger )
8270 default :
8371 return nil
8472 }
73+ return gitpkg .NewCachedGitClient (inner , u .repoCache , identity .UserID .String ()+ ":" + identity .ID .String ())
8574}
8675
8776// Get 获取单个 Git 身份认证(仅限当前用户)
88- func (u * GitIdentityUsecase ) Get (ctx context.Context , uid uuid.UUID , id uuid.UUID ) (* domain.GitIdentity , error ) {
77+ func (u * GitIdentityUsecase ) Get (ctx context.Context , uid uuid.UUID , id uuid.UUID , flush bool ) (* domain.GitIdentity , error ) {
8978 identity , err := u .repo .GetByUserID (ctx , uid , id )
9079 if err != nil {
9180 if db .IsNotFound (err ) {
@@ -99,19 +88,20 @@ func (u *GitIdentityUsecase) Get(ctx context.Context, uid uuid.UUID, id uuid.UUI
9988 if client := u .gitClienter (identity ); client != nil {
10089 token , err := u .tokenProvider .GetToken (ctx , identity .ID )
10190 if err != nil {
102- u .logger .WarnContext (ctx , "failed to get token" , "error" , err , "platform" , identity .Platform , "identity_id" , id )
91+ u .logger .WarnContext (ctx , "failed to get token" , "error" , err , "platform" , identity .Platform , "identity_id" , identity . ID )
10392 return gi , nil
10493 }
10594 repos , err := client .Repositories (ctx , & domain.RepositoryOptions {
10695 Token : token ,
10796 InstallID : identity .InstallationID ,
10897 IsOAuth : identity .OauthRefreshToken != "" ,
98+ Flush : flush ,
10999 })
110100 if err != nil {
111- u .logger .WarnContext (ctx , "failed to get authorized repositories" , "error" , err , "platform" , identity .Platform , "identity_id" , id )
112- } else {
113- gi .AuthorizedRepositories = repos
101+ u .logger .WarnContext (ctx , "failed to get authorized repositories" , "error" , err , "platform" , identity .Platform , "identity_id" , identity .ID )
102+ return gi , nil
114103 }
104+ gi .AuthorizedRepositories = repos
115105 }
116106
117107 return gi , nil
@@ -134,6 +124,7 @@ func (u *GitIdentityUsecase) Update(ctx context.Context, uid uuid.UUID, req *dom
134124 return err
135125 }
136126 u .tokenProvider .ClearCache (req .ID )
127+ u .repoCache .Delete (uid .String () + ":" + req .ID .String ())
137128 return nil
138129}
139130
@@ -164,6 +155,7 @@ func (u *GitIdentityUsecase) Delete(ctx context.Context, uid uuid.UUID, id uuid.
164155 return err
165156 }
166157 u .tokenProvider .ClearCache (id )
158+ u .repoCache .Delete (uid .String () + ":" + id .String ())
167159 return nil
168160}
169161
0 commit comments