Răsfoiți Sursa

v1.0.0-beta.6

xjg 3 luni în urmă
părinte
comite
792e56b44b

+ 1 - 1
.drone.yml

@@ -21,7 +21,7 @@ steps:
       repo: sghharbor.com/micro/auth-service
       registry: sghharbor.com
       tags:
-        - v1.0.0-beta.5
+        - v1.0.0-beta.6
 volumes:
   - name: docker-ca
     host:

+ 5 - 0
.gitignore

@@ -16,6 +16,11 @@ role:
 base:
 	protoc --proto_path=. --micro_out=. --go_out=:. proto/base_service.proto
 
+
+.PHONY: team
+team:
+	protoc --proto_path=. --micro_out=. --go_out=:. proto/team_service.proto
+
 .PHONY: health
 health:
 	protoc --proto_path=. --micro_out=. --go_out=:. proto/health.proto

+ 0 - 23
README.md

@@ -1,23 +0,0 @@
-package request
-
-// AdminTeam 直接将用户添加到团队的 Members 中
-// db.Model(&team).Update("Members", gorm.Expr("ARRAY_APPEND(members, ?)", userID))
-// 假设 teamID 为团队的 ID
-// var team Team
-// if err := db.Preload("Members").First(&team, teamID).Error; err != nil {
-// // 处理团队不存在的情况
-// }
-type AdminTeam struct {
-	ID          int64             `gorm:"primary_key;not_null;auto_increment;" json:"id"`
-	Name        string            `json:"name"`        // 团队名称
-	Description string            `json:"description"` // 团队描述
-	LeaderID    int64             `json:"leader_id"`   // 团队领导的用户 ID
-	CreatedBy   string            `json:"created_by"`  // 创建团队的用户
-	CreateTime  int64             `json:"create_time"` // 团队创建时间
-	Leader      AdminUser         `gorm:"foreignkey:LeaderID" json:"leader"`
-	Members     []AdminUser       `gorm:"many2many:admin_team_member;" json:"members"`
-	Roles       []AdminRole       `gorm:"many2many:admin_team_role;" json:"roles"`
-	Permissions []AdminPermission `gorm:"many2many:admin_team_permission;" json:"permissions"`
-	Website     string            `json:"website"`     // 团队网站
-	MaxMembers  int               `json:"max_members"` // 团队最大成员数
-}

+ 1 - 1
domain/model/request/admin_user.go

@@ -18,6 +18,6 @@ type AdminUser struct {
 	UpdatedAt   *time.Time    `json:"updated_at"`                          // 更新时间
 	CreatorID   int64         `json:"creator_id"`                          // 创建人
 	UpdaterID   string        `json:"updater_id"`                          // 操作人
-	Teams       []AdminTeam   `gorm:"many2many:admin_team_member;" json:"teams"`
+	Teams       []Team        `gorm:"many2many:admin_team_member;" json:"teams"`
 	Roles       []AdminRole   `gorm:"many2many:admin_user_role;" json:"roles"`
 }

+ 30 - 0
domain/model/request/audit_log.go

@@ -0,0 +1,30 @@
+package request
+
+import (
+	"gorm.io/gorm"
+	pb "sghgogs.com/micro/auth-service/proto"
+	"time"
+)
+
+// Team 直接将用户添加到团队的 Members 中
+// db.Model(&team).Update("Members", gorm.Expr("ARRAY_APPEND(members, ?)", userID))
+// 假设 teamID 为团队的 ID
+// var team Team
+// if err := db.Preload("Members").First(&team, teamID).Error; err != nil {
+// // 处理团队不存在的情况
+// }
+type Team struct {
+	ID               int64         `gorm:"primary_key;not_null;auto_increment;" json:"id"`
+	Name             string        `json:"name"`        // 团队名称
+	Description      string        `json:"description"` // 团队描述
+	CreatedBy        string        `json:"created_by"`  // 创建团队的用户
+	UpdatedBy        string        `json:"updated_by"`  // 更新团队的用户
+	CreatedAt        time.Time     `json:"created_at"`  // 团队创建时间
+	Avatar           string        `json:"avatar"`      // 团队头像
+	UpdatedAt        *time.Time    `json:"updated_at"`
+	Website          string        `json:"website"`                             // 团队网站
+	MaxMembers       int32         `json:"max_members"`                         // 团队最大成员数
+	Status           pb.StatusEnum `json:"status" gorm:"unique_index;not_null"` // 可以是 "enabled", "disabled", "deleted" 等
+	Credential       string        `json:"credential"`
+	RegistrationDate gorm.DeletedAt
+}

+ 1 - 1
domain/repository/admin_common.go

@@ -62,7 +62,7 @@ func (u *Repository) CreateAdminPermission(permission req.AdminPermission, roles
 		return err
 	}
 	if len(roles) > 0 {
-		if _, err := u.getAdminPermissionValidIDs(roles); err != nil {
+		if _, err := u.getAdminRoleValidIDs(roles); err != nil {
 			tx.Rollback()
 			return err
 		}

+ 1 - 1
domain/repository/admin_role.go

@@ -145,7 +145,7 @@ func (u *Repository) UpdateAdminRole(updateRole *pb.UpdateAdminRoleRequest) erro
 		}
 	}
 	if len(updateRole.Permissions) > 0 {
-		if _, err := u.getAdminUserValidIDs(updateRole.Permissions); err != nil {
+		if _, err := u.getAdminPermissionValidIDs(updateRole.Permissions); err != nil {
 			tx.Rollback()
 			return err
 		}

+ 4 - 4
domain/repository/admin_user.go

@@ -81,9 +81,9 @@ func (u *Repository) CreateAdminUser(user *req.AdminUser, adminRoles []int64, ad
 			tx.Rollback()
 			return err
 		}
-		teams := make([]req.AdminTeam, 0)
+		teams := make([]req.Team, 0)
 		for _, ID := range adminTeams {
-			teams = append(teams, req.AdminTeam{ID: ID})
+			teams = append(teams, req.Team{ID: ID})
 		}
 		if err := tx.Model(&user).Association("Teams").Append(&teams); err != nil {
 			tx.Rollback()
@@ -130,9 +130,9 @@ func (u *Repository) UpdateAdminUser(updateUser *pb.UpdateAdminUserRequest) erro
 			tx.Rollback()
 			return err
 		}
-		teams := make([]req.AdminTeam, 0)
+		teams := make([]req.Team, 0)
 		for _, ID := range updateUser.Teams {
-			teams = append(teams, req.AdminTeam{
+			teams = append(teams, req.Team{
 				ID: ID,
 			})
 		}

+ 10 - 1
domain/repository/repository.go

@@ -51,6 +51,14 @@ type IRepository interface {
 	DeleteAdminPermission(int64) error
 	ToggleAdminPermission(*pb.ToggleAdminPermissionRequest) error
 	IsAdminPermissionExists(interface{}) (bool, error)
+
+	GetTeamList(*pb.GetTeamListRequest) ([]req.Team, int64, error)
+	GetAllTeams() ([]req.Team, error)
+	GetTeam(*pb.GetTeamRequest) (req.Team, error)
+	CreateTeam(*req.Team) error
+	ToggleTeam(*pb.ToggleTeamRequest) error
+	UpdateTeam(*pb.UpdateTeamRequest) error
+	DeleteTeam(*pb.DeleteTeamRequest) error
 }
 
 func NewRepository(db *gorm.DB) IRepository {
@@ -67,6 +75,7 @@ func (u *Repository) InitTable() error {
 	return u.db.AutoMigrate(
 		&req.AuditLog{},
 		&req.AdminUser{},
+		&req.Team{},
 		&req.AdminRole{},
 		&req.AdminPermission{},
 		&req.AdminUserProfile{},
@@ -134,7 +143,7 @@ func (u *Repository) getAdminRoleValidIDs(ids []int64) ([]int64, error) {
 // 检测团队ID如果不存在会抛出错误
 func (u *Repository) getAdminTeamValidIDs(ids []int64) ([]int64, error) {
 	var validIDs []int64
-	result := u.db.Model(&req.AdminTeam{}).Where("id IN ?", ids).Pluck("id", &validIDs)
+	result := u.db.Model(&req.Team{}).Where("id IN ?", ids).Pluck("id", &validIDs)
 	if result.Error != nil {
 		return nil, result.Error
 	}

+ 94 - 0
domain/repository/team.go

@@ -0,0 +1,94 @@
+package repository
+
+import (
+	"fmt"
+	req "sghgogs.com/micro/auth-service/domain/model/request"
+	pb "sghgogs.com/micro/auth-service/proto"
+	"sghgogs.com/micro/auth-service/utils/authutil"
+	"time"
+)
+
+func (u *Repository) GetTeamList(query *pb.GetTeamListRequest) ([]req.Team, int64, error) {
+	teams := make([]req.Team, 0)
+	// u.db.Model(&req.Team{}).Where()
+	var totalCount int64
+	tx := u.db.Model(&req.Team{}).Order("id desc").Select("id, name, description, created_by, created_at, updated_at, website, max_members, status, avatar")
+	if query.Keyword != "" {
+		tx.Where("name = ? ", query.Keyword)
+	}
+	if query.Status > 0 {
+		tx.Where("status = ?", query.Status)
+	}
+	tx.Count(&totalCount)
+	// users := make([]req.AdminUser, 0)
+	return teams, totalCount, tx.Limit(int(query.PageSize)).Offset(int((query.Page - 1) * query.PageSize)).Find(&teams).Error
+}
+
+func (u *Repository) GetAllTeams() ([]req.Team, error) {
+	teams := make([]req.Team, 0)
+	return teams, u.db.Model(&req.Team{}).Where("status = ?", pb.StatusEnum_ENABLED).Select("name, description").
+		Order("id desc").Find(&teams).Error
+}
+
+func (u *Repository) GetTeam(query *pb.GetTeamRequest) (req.Team, error) {
+	var team req.Team
+	return team, u.db.Model(&req.Team{}).Where("id = ? OR name = ?", query.TeamId, query.Keyword).First(&team).Error
+}
+
+func (u *Repository) CreateTeam(team *req.Team) error {
+	// 开始事务
+	tx := u.db.Begin()
+	// 错误处理
+	defer func() {
+		if r := recover(); r != nil {
+			tx.Rollback()
+		}
+	}()
+	if err := tx.Create(&team).Error; err != nil {
+		tx.Rollback()
+		return err
+	}
+	expiry := time.Second * time.Duration(720*3600)
+	md := map[string]string{}
+	md["name"] = team.Name
+	md["team_id"] = fmt.Sprintf("%d", team.ID)
+	md["expiry"] = fmt.Sprintf("%d", time.Now().Add(expiry).Unix())
+	generate, err := authutil.JWTAuthService.GenerateTeamToken(team.ID, md)
+	if err != nil {
+		tx.Rollback()
+		return err
+	}
+	token, err := authutil.JWTAuthService.Token(team.ID, generate.Secret, expiry)
+	if err != nil {
+		tx.Rollback()
+		return err
+	}
+	if err = tx.Model(&req.Team{}).Where("id = ?", team.ID).Updates(map[string]interface{}{"credential": token.AccessToken}).Error; err != nil {
+		tx.Rollback()
+		return err
+	}
+	return tx.Commit().Error
+}
+
+func (u *Repository) ToggleTeam(query *pb.ToggleTeamRequest) error {
+	return u.db.Model(&req.Team{}).Where("id = ? ", query.TeamId).Updates(map[string]interface{}{
+		"status":     query.Status,
+		"updated_at": time.Now(),
+		"updated_by": query.UpdatedBy,
+	}).Error
+}
+
+func (u *Repository) UpdateTeam(query *pb.UpdateTeamRequest) error {
+	return u.db.Model(&req.Team{}).Where("id = ?", query.TeamId).Updates(map[string]interface{}{
+		"name":        query.Name,
+		"description": query.Description,
+		"website":     query.Website,
+		"max_members": query.MaxMembers,
+		"updated_at":  time.Now(),
+		"updated_by":  query.UpdatedBy,
+	}).Error
+}
+
+func (u *Repository) DeleteTeam(query *pb.DeleteTeamRequest) error {
+	return u.db.Model(&req.Team{}).Where("id = ?", query.TeamId).Delete(&req.Team{ID: query.TeamId}).Error
+}

+ 11 - 1
domain/service/admin_common.go

@@ -48,6 +48,14 @@ type IService interface {
 	UpdateAdminPermission(context.Context, *pb.UpdateAdminPermissionRequest) error
 	DeleteAdminPermission(*pb.DeleteAdminPermissionRequest) error
 	ToggleAdminPermission(*pb.ToggleAdminPermissionRequest) error
+
+	GetTeamList(*pb.GetTeamListRequest) ([]*pb.Team, int64, error)
+	GetTeam(*pb.GetTeamRequest) (*pb.Team, error)
+	CreateTeam(context.Context, *pb.Team) error
+	ToggleTeam(context.Context, *pb.ToggleTeamRequest) error
+	UpdateTeam(context.Context, *pb.UpdateTeamRequest) error
+	DeleteTeam(context.Context, *pb.DeleteTeamRequest) error
+	GetAllTeams() ([]*pb.Team, error)
 	// AssociateUserWithRole(context.Context, *pb.AssociateAdminUserWithRoleRequest) error
 	// UpdateAdminUserProfileInfoRequest(*pb.UpdateAdminUserProfileInfoRequest) error
 }
@@ -117,14 +125,16 @@ func ParseMetadata(ctx context.Context) (int64, string, string, string) {
 	return userId, createdBy, IPAddress, md["Agent"]
 }
 
-func NewService(r repository.IRepository) IService {
+func NewService(r repository.IRepository, namespace string) IService {
 	return &Service{
 		Repository: r,
+		Namespace:  namespace,
 	}
 }
 
 type Service struct {
 	Repository repository.IRepository
+	Namespace  string
 }
 
 func (s *Service) UpdateRulesItems(roles []req.AdminRole) []*auth.Rule {

+ 97 - 0
domain/service/team.go

@@ -0,0 +1,97 @@
+package service
+
+import (
+	"context"
+	req "sghgogs.com/micro/auth-service/domain/model/request"
+	pb "sghgogs.com/micro/auth-service/proto"
+	"sghgogs.com/micro/common"
+	"sghgogs.com/micro/common/errorcode"
+	"time"
+)
+
+func (s *Service) GetTeamList(query *pb.GetTeamListRequest) ([]*pb.Team, int64, error) {
+	teams := make([]*pb.Team, 0)
+	list, i, err := s.Repository.GetTeamList(query)
+	if err != nil {
+		return teams, 0, errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	for _, item := range list {
+		teams = append(teams, s.getTeamRes(item))
+	}
+	return teams, i, nil
+}
+
+func (s *Service) GetTeam(query *pb.GetTeamRequest) (*pb.Team, error) {
+	team, err := s.Repository.GetTeam(query)
+	if err != nil {
+		return &pb.Team{}, errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	return s.getTeamRes(team), nil
+}
+
+func (s *Service) getTeamRes(team req.Team) *pb.Team {
+	var res pb.Team
+	common.SwapTo(team, &res)
+	res.CreatedAt = ConvertTimeToInt64(team.CreatedAt)
+	if team.UpdatedAt != nil {
+		res.UpdatedAt = ConvertTimeToInt64(*team.UpdatedAt)
+	}
+	return &res
+}
+
+func (s *Service) GetAllTeams() ([]*pb.Team, error) {
+	teams := make([]*pb.Team, 0)
+	list, err := s.Repository.GetAllTeams()
+	if err != nil {
+		return teams, errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	for _, item := range list {
+		teams = append(teams, s.getTeamRes(item))
+	}
+	return teams, nil
+}
+
+func (s *Service) CreateTeam(ctx context.Context, team *pb.Team) error {
+	_, by, _, _ := ParseMetadata(ctx)
+	if err := s.Repository.CreateTeam(&req.Team{
+		Name:        team.Name,
+		Description: team.Description,
+		CreatedBy:   by,
+		CreatedAt:   time.Now(),
+		UpdatedAt:   nil,
+		Website:     team.Website,
+		Avatar:      team.Avatar,
+		MaxMembers:  team.MaxMembers,
+		Status:      pb.StatusEnum_ENABLED,
+	}); err != nil {
+		return errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	return nil
+}
+
+func (s *Service) ToggleTeam(ctx context.Context, query *pb.ToggleTeamRequest) error {
+	_, by, _, _ := ParseMetadata(ctx)
+	query.UpdatedBy = by
+	if err := s.Repository.ToggleTeam(query); err != nil {
+		return errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	return nil
+}
+
+func (s *Service) UpdateTeam(ctx context.Context, query *pb.UpdateTeamRequest) error {
+	_, by, _, _ := ParseMetadata(ctx)
+	query.UpdatedBy = by
+	if err := s.Repository.UpdateTeam(query); err != nil {
+		return errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	return nil
+}
+
+func (s *Service) DeleteTeam(ctx context.Context, query *pb.DeleteTeamRequest) error {
+	_, by, _, _ := ParseMetadata(ctx)
+	query.UpdatedBy = by
+	if err := s.Repository.DeleteTeam(query); err != nil {
+		return errorcode.New(s.Namespace, err.Error(), 500)
+	}
+	return nil
+}

+ 3 - 1
go.mod

@@ -25,6 +25,8 @@ require (
 	sghgogs.com/micro/common v0.0.0-20240110100620-babd9b87dfe2
 )
 
+//replace sghgogs.com/micro/shopping-service => ../shopping/shopping-service/shopping-service
+
 require (
 	github.com/Microsoft/go-winio v0.6.0 // indirect
 	github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect
@@ -84,7 +86,7 @@ require (
 	github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
 	github.com/prometheus/common v0.44.0 // indirect
 	github.com/prometheus/procfs v0.11.1 // indirect
-	github.com/rogpeppe/go-internal v1.11.0 // indirect
+	github.com/rogpeppe/go-internal v1.12.0 // indirect
 	github.com/russross/blackfriday/v2 v2.0.1 // indirect
 	github.com/sergi/go-diff v1.1.0 // indirect
 	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect

+ 2 - 2
go.sum

@@ -487,8 +487,8 @@ github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0
 github.com/redis/rueidis v1.0.19 h1:s65oWtotzlIFN8eMPhyYwxlwLR1lUdhza2KtWprKYSo=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
-github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
-github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
+github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
+github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
 github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=

+ 4 - 2
handler/admin/common/common.go

@@ -45,6 +45,7 @@ func (svc *Common) AdminLogin(ctx context.Context, loginUser *pb.AdminLoginReque
 		for _, role := range user.Roles {
 			roles = append(roles, strings.ToLower(role.Key))
 		}
+		expiry := time.Second * time.Duration(2*3600)
 		generate, err := authutil.JWTAuthService.GenerateToken(
 			user.Id,
 			"system",
@@ -52,15 +53,16 @@ func (svc *Common) AdminLogin(ctx context.Context, loginUser *pb.AdminLoginReque
 			loginUser.Password,
 			roles,
 			md,
+			expiry,
 		)
 		if err != nil {
 			return errorcode.BadRequest("authorization service", common.ErrorMessage[common.FailedToGenerateTokenErrorCode])
 		}
-		token, err := authutil.JWTAuthService.Token(user.Id, generate.Secret)
+		token, err := authutil.JWTAuthService.Token(user.Id, generate.Secret, expiry)
 		if err != nil {
 			return errorcode.BadRequest("authorization service", common.ErrorMessage[common.FailedToGenerateTokenErrorCode])
 		}
-		if err = authutil.JWTAuthService.StoreToken(ctx, user.Id, user.Username, token.AccessToken); err != nil {
+		if err = authutil.JWTAuthService.StoreToken(ctx, user.Id, user.Username, token.AccessToken, expiry); err != nil {
 			return errorcode.BadRequest("authorization service", common.ErrorMessage[common.FailedToStoreTokenErrorCode])
 		}
 		rsp.Token = token.AccessToken

+ 69 - 0
handler/admin/permission/permission.go

@@ -0,0 +1,69 @@
+package team
+
+import (
+	"context"
+	"sghgogs.com/micro/auth-service/domain/service"
+	pb "sghgogs.com/micro/auth-service/proto"
+)
+
+type Team struct {
+	Service service.IService
+}
+
+func (svc *Team) GetTeamList(ctx context.Context, query *pb.GetTeamListRequest, rsp *pb.GetTeamListResponse) error {
+	list, i, err := svc.Service.GetTeamList(query)
+	if err != nil {
+		return err
+	}
+	rsp.TotalCount = i
+	rsp.Items = list
+	return nil
+}
+
+func (svc *Team) GetAllTeams(ctx context.Context, query *pb.GetAllTeamsRequest, rsp *pb.GetAllTeamsResponse) error {
+	list, err := svc.Service.GetAllTeams()
+	if err != nil {
+		return err
+	}
+	rsp.Items = list
+	return nil
+}
+
+// GetAllTeams
+
+func (svc *Team) GetTeam(ctx context.Context, query *pb.GetTeamRequest, rsp *pb.GetTeamResponse) error {
+	team, err := svc.Service.GetTeam(query)
+	if err != nil {
+		return err
+	}
+	rsp.Data = team
+	return nil
+}
+
+func (svc *Team) CreateTeam(ctx context.Context, team *pb.Team, rsp *pb.CreateTeamResponse) error {
+	if err := svc.Service.CreateTeam(ctx, team); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (svc *Team) ToggleTeam(ctx context.Context, query *pb.ToggleTeamRequest, rsp *pb.ToggleTeamResponse) error {
+	if err := svc.Service.ToggleTeam(ctx, query); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (svc *Team) DeleteTeam(ctx context.Context, query *pb.DeleteTeamRequest, rsp *pb.DeleteTeamResponse) error {
+	if err := svc.Service.DeleteTeam(ctx, query); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (svc *Team) UpdateTeam(ctx context.Context, update *pb.UpdateTeamRequest, rsp *pb.UpdateTeamResponse) error {
+	if err := svc.Service.UpdateTeam(ctx, update); err != nil {
+		return err
+	}
+	return nil
+}

+ 36 - 0
handler/admin/user/user.go

@@ -0,0 +1,36 @@
+package user
+
+import (
+	"context"
+	"sghgogs.com/micro/auth-service/domain/service"
+	pb "sghgogs.com/micro/auth-service/proto"
+)
+
+type User struct {
+	Service service.IService
+}
+
+func (u User) GetTeamList(ctx context.Context, request *pb.GetTeamListRequest, rsp *pb.GetTeamListResponse) error {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (u User) CreateTeam(ctx context.Context, team *pb.Team, rsp *pb.CreateTeamResponse) error {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (u User) ToggleTeam(ctx context.Context, request *pb.ToggleTeamRequest, rsp *pb.ToggleTeamResponse) error {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (u User) DeleteTeam(ctx context.Context, request *pb.DeleteTeamRequest, rsp *pb.DeleteTeamResponse) error {
+	// TODO implement me
+	panic("implement me")
+}
+
+func (u User) UpdateTeam(ctx context.Context, request *pb.UpdateTeamRequest, rsp *pb.UpdateTeamResponse) error {
+	// TODO implement me
+	panic("implement me")
+}

+ 4 - 1
k8s/auth-service.yaml

@@ -26,8 +26,10 @@ import (
 	admin_common "sghgogs.com/micro/auth-service/handler/admin/common"
 	admin_permission "sghgogs.com/micro/auth-service/handler/admin/permission"
 	admin_role "sghgogs.com/micro/auth-service/handler/admin/role"
+	"sghgogs.com/micro/auth-service/handler/admin/team"
 	admin_user "sghgogs.com/micro/auth-service/handler/admin/user"
 	pb "sghgogs.com/micro/auth-service/proto"
+
 	"sghgogs.com/micro/auth-service/utils/authutil"
 	"sghgogs.com/micro/auth-service/utils/middleware"
 	"sghgogs.com/micro/auth-service/utils/tracing"
@@ -129,12 +131,13 @@ func main() {
 	newRepository := repository.NewRepository(db)
 	newRepository.InitTable()
 	// 6.初始化 service
-	newService := service.NewService(newRepository)
+	newService := service.NewService(newRepository, name)
 	// 注册  Register handler
 	pb.RegisterCommonServiceHandler(srv.Server(), &admin_common.Common{Service: newService})
 	pb.RegisterAdminRoleServiceHandler(srv.Server(), &admin_role.Role{Service: newService})
 	pb.RegisterAdminUserServiceHandler(srv.Server(), &admin_user.User{Service: newService})
 	pb.RegisterAdminPermissionServiceHandler(srv.Server(), &admin_permission.Permission{Service: newService})
+	pb.RegisterTeamServiceHandler(srv.Server(), &team.Team{Service: newService})
 	// Run service
 	logrus.Info("Run service")
 	if err := srv.Run(); err != nil {

+ 177 - 15
proto/admin_permission_service.pb.go

@@ -492,6 +492,133 @@ func (x *AdminPermission) GetEndpoint() string {
 	return ""
 }
 
+type Team struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id          int64      `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+	Name        string     `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Description string     `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+	CreatedBy   string     `protobuf:"bytes,4,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
+	CreatedAt   int64      `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
+	UpdatedAt   int64      `protobuf:"varint,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+	Website     string     `protobuf:"bytes,7,opt,name=website,proto3" json:"website,omitempty"`
+	MaxMembers  int32      `protobuf:"varint,8,opt,name=max_members,json=maxMembers,proto3" json:"max_members,omitempty"`
+	Status      StatusEnum `protobuf:"varint,9,opt,name=status,proto3,enum=base_service.StatusEnum" json:"status,omitempty"`
+	Credential  string     `protobuf:"bytes,10,opt,name=credential,proto3" json:"credential,omitempty"`
+	Avatar      string     `protobuf:"bytes,11,opt,name=avatar,proto3" json:"avatar,omitempty"`
+}
+
+func (x *Team) Reset() {
+	*x = Team{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_proto_base_service_proto_msgTypes[4]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Team) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Team) ProtoMessage() {}
+
+func (x *Team) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_base_service_proto_msgTypes[4]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Team.ProtoReflect.Descriptor instead.
+func (*Team) Descriptor() ([]byte, []int) {
+	return file_proto_base_service_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *Team) GetId() int64 {
+	if x != nil {
+		return x.Id
+	}
+	return 0
+}
+
+func (x *Team) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *Team) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
+func (x *Team) GetCreatedBy() string {
+	if x != nil {
+		return x.CreatedBy
+	}
+	return ""
+}
+
+func (x *Team) GetCreatedAt() int64 {
+	if x != nil {
+		return x.CreatedAt
+	}
+	return 0
+}
+
+func (x *Team) GetUpdatedAt() int64 {
+	if x != nil {
+		return x.UpdatedAt
+	}
+	return 0
+}
+
+func (x *Team) GetWebsite() string {
+	if x != nil {
+		return x.Website
+	}
+	return ""
+}
+
+func (x *Team) GetMaxMembers() int32 {
+	if x != nil {
+		return x.MaxMembers
+	}
+	return 0
+}
+
+func (x *Team) GetStatus() StatusEnum {
+	if x != nil {
+		return x.Status
+	}
+	return StatusEnum_UNKNOWN
+}
+
+func (x *Team) GetCredential() string {
+	if x != nil {
+		return x.Credential
+	}
+	return ""
+}
+
+func (x *Team) GetAvatar() string {
+	if x != nil {
+		return x.Avatar
+	}
+	return ""
+}
+
 var File_proto_base_service_proto protoreflect.FileDescriptor
 
 var file_proto_base_service_proto_rawDesc = []byte{
@@ -568,14 +695,35 @@ var file_proto_base_service_proto_rawDesc = []byte{
 	0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01,
 	0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x12, 0x1a,
 	0x0a, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
-	0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2a, 0x41, 0x0a, 0x0a, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e,
-	0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45, 0x44,
-	0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x02,
-	0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x42, 0x1f, 0x5a,
-	0x1d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
-	0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62, 0x06,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x52, 0x08, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x22, 0xce, 0x02, 0x0a, 0x04, 0x54,
+	0x65, 0x61, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x72,
+	0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74,
+	0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65,
+	0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x61, 0x78, 0x5f, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x18,
+	0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x6d, 0x61, 0x78, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72,
+	0x73, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x18, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
+	0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
+	0x69, 0x61, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x0b, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x2a, 0x41, 0x0a, 0x0a, 0x53,
+	0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b,
+	0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x45, 0x4e, 0x41, 0x42, 0x4c, 0x45,
+	0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10,
+	0x02, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x03, 0x42, 0x1f,
+	0x5a, 0x1d, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
+	0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x62,
+	0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -591,13 +739,14 @@ func file_proto_base_service_proto_rawDescGZIP() []byte {
 }
 
 var file_proto_base_service_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_proto_base_service_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_proto_base_service_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
 var file_proto_base_service_proto_goTypes = []interface{}{
 	(StatusEnum)(0),         // 0: base_service.StatusEnum
 	(*AdminBase)(nil),       // 1: base_service.AdminBase
 	(*AdminUser)(nil),       // 2: base_service.AdminUser
 	(*AdminRole)(nil),       // 3: base_service.AdminRole
 	(*AdminPermission)(nil), // 4: base_service.AdminPermission
+	(*Team)(nil),            // 5: base_service.Team
 }
 var file_proto_base_service_proto_depIdxs = []int32{
 	0, // 0: base_service.AdminUser.status:type_name -> base_service.StatusEnum
@@ -608,11 +757,12 @@ var file_proto_base_service_proto_depIdxs = []int32{
 	0, // 5: base_service.AdminRole.status:type_name -> base_service.StatusEnum
 	1, // 6: base_service.AdminPermission.roles:type_name -> base_service.AdminBase
 	0, // 7: base_service.AdminPermission.status:type_name -> base_service.StatusEnum
-	8, // [8:8] is the sub-list for method output_type
-	8, // [8:8] is the sub-list for method input_type
-	8, // [8:8] is the sub-list for extension type_name
-	8, // [8:8] is the sub-list for extension extendee
-	0, // [0:8] is the sub-list for field type_name
+	0, // 8: base_service.Team.status:type_name -> base_service.StatusEnum
+	9, // [9:9] is the sub-list for method output_type
+	9, // [9:9] is the sub-list for method input_type
+	9, // [9:9] is the sub-list for extension type_name
+	9, // [9:9] is the sub-list for extension extendee
+	0, // [0:9] is the sub-list for field type_name
 }
 
 func init() { file_proto_base_service_proto_init() }
@@ -669,6 +819,18 @@ func file_proto_base_service_proto_init() {
 				return nil
 			}
 		}
+		file_proto_base_service_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Team); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -676,7 +838,7 @@ func file_proto_base_service_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_proto_base_service_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   4,
+			NumMessages:   5,
 			NumExtensions: 0,
 			NumServices:   0,
 		},

+ 14 - 0
proto/base_service.pb.micro.go

@@ -60,6 +60,20 @@ message AdminPermission {
   string endpoint = 10;
 }
 
+message Team {
+  int64 id = 1;
+  string name = 2;
+  string description = 3;
+  string created_by = 4;
+  int64 created_at = 5;
+  int64 updated_at = 6;
+  string website = 7;
+  int32 max_members = 8;
+  StatusEnum status = 9;
+  string credential = 10;
+  string avatar = 11;
+}
+
 enum StatusEnum {
   UNKNOWN = 0;
   ENABLED = 1;

+ 68 - 0
proto/common_service.pb.go

@@ -0,0 +1,68 @@
+syntax = "proto3";
+
+package team_service;
+
+option go_package = "./proto;authorization_service";
+
+import "proto/base_service.proto";
+
+service TeamService {
+  rpc GetTeamList(GetTeamListRequest) returns(GetTeamListResponse); // 获取详情
+  rpc GetAllTeams(GetAllTeamsRequest) returns (GetAllTeamsResponse); // 获取所有
+  rpc GetTeam(GetTeamRequest) returns(GetTeamResponse); // 获取详情
+  rpc CreateTeam(base_service.Team) returns (CreateTeamResponse); // 获取用户
+  rpc ToggleTeam(ToggleTeamRequest) returns(ToggleTeamResponse); // 启用/禁用 用户
+  rpc DeleteTeam(DeleteTeamRequest) returns(DeleteTeamResponse); // 删除用户
+  rpc UpdateTeam(UpdateTeamRequest) returns (UpdateTeamResponse); // 更新
+}
+
+message GetTeamListRequest{
+  int32 page = 1;
+  int32 page_size = 2;
+  string keyword = 3;
+  base_service.StatusEnum status = 4;
+}
+message GetAllTeamsRequest{}
+message GetAllTeamsResponse{
+  repeated base_service.Team items = 1;
+}
+
+
+message GetTeamListResponse{
+  repeated base_service.Team items = 1;
+  int64 total_count = 2;
+}
+
+message GetTeamRequest{
+  int64 team_id = 1;
+  string keyword = 3;
+}
+message GetTeamResponse {
+  base_service.Team data = 1;
+}
+
+message CreateTeamResponse{}
+
+message ToggleTeamRequest{
+  int64 team_id = 1;
+  base_service.StatusEnum status = 2;
+  string updated_by = 3;
+}
+message ToggleTeamResponse{}
+
+message DeleteTeamRequest{
+  int64 team_id = 1;
+  string updated_by = 2;
+}
+message DeleteTeamResponse{}
+
+message UpdateTeamRequest{
+  int64 team_id = 1;
+  string name = 2;
+  string description = 3;
+  string website = 4;
+  int32 max_members = 5;
+  string updated_by = 6;
+  string avatar = 7;
+}
+message UpdateTeamResponse{}

+ 1 - 1
test/admin_common/admin_common_test.go

@@ -37,7 +37,7 @@ func TestPermission(t *testing.T) {
 	// }
 
 	repo := repository.NewRepository(db)
-	newService := service.NewService(repo)
+	newService := service.NewService(repo, "t")
 	// getAuthentication = &auth.Resource{
 	// 	Type:     "user",
 	// 	Name:     name,

+ 1 - 1
test/admin_role/admin_role_test.go

@@ -36,7 +36,7 @@ func TestAdminLogin(t *testing.T) {
 		t.Fatal(err)
 	}
 	repo := repository.NewRepository(db)
-	newService := service.NewService(repo)
+	newService := service.NewService(repo, "tesr")
 	t.Run("创建角色", func(t *testing.T) {
 		roleRequest := &pb.CreateAdminRoleRequest{
 			Name:        "kubernetes",

+ 1 - 1
test/adminuser/admin_user_test.go

@@ -34,7 +34,7 @@ func TestAdminLogin(t *testing.T) {
 		t.Fatal(err)
 	}
 	repo := repository.NewRepository(db)
-	newService := service.NewService(repo)
+	newService := service.NewService(repo, "name")
 	t.Run("sql 测试查询", func(t *testing.T) {
 		var unassignedRoles []req.AdminRole
 

+ 83 - 0
test/common/admin_login_test.go

@@ -0,0 +1,83 @@
+package team
+
+import (
+	"context"
+	"fmt"
+	"github.com/redis/go-redis/v9"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+	"gorm.io/gorm/logger"
+	"gorm.io/gorm/schema"
+	"sghgogs.com/micro/auth-service/domain/repository"
+	"sghgogs.com/micro/auth-service/domain/service"
+	pb "sghgogs.com/micro/auth-service/proto"
+	"sghgogs.com/micro/auth-service/utils/authutil"
+	"strconv"
+	"testing"
+	"time"
+)
+
+func TestTeam(t *testing.T) {
+	address := fmt.Sprintf("%v:%v@(%v:%v)/%v?charset=utf8mb4,utf8&parseTime=True&loc=Local", "root", "xugang131500", "47.56.16.206", 3306, "sghblog")
+	db, err := gorm.Open(mysql.Open(address), &gorm.Config{
+		Logger: logger.Default.LogMode(logger.Info),
+		NamingStrategy: schema.NamingStrategy{
+			SingularTable: true,
+		}})
+	if err != nil {
+		t.Fatal(err)
+	}
+	repo := repository.NewRepository(db)
+	t.Run("初始化", func(t *testing.T) {
+		repo.InitTable()
+	})
+	t.Run("初始化", func(t *testing.T) {
+		// authutil.NewJWTAuth(redis.NewClient(&redis.Options{
+		// 	Addr:     "localhost:6379", // Redis 服务器地址
+		// 	Password: "xugang131500",   // Redis 密码,如果有的话
+		// 	DB:       0,                // 默认数据库
+		// }), "authorizationservice", true)
+	})
+	newService := service.NewService(repo, "authorizationservice")
+	t.Run("创建", func(t *testing.T) {
+		authutil.NewJWTAuth(redis.NewClient(&redis.Options{
+			Addr:     "localhost:6379", // Redis 服务器地址
+			Password: "xugang131500",   // Redis 密码,如果有的话
+			DB:       0,                // 默认数据库
+		}), "authorizationservice", true)
+		err2 := newService.CreateTeam(context.Background(), &pb.Team{
+			Name:        "shoppingservice_wanke",
+			Description: "万科",
+			CreatedBy:   "system",
+			MaxMembers:  10,
+		})
+		fmt.Println(err2)
+		// fmt.Println(err2)
+	})
+	t.Run("获取列表", func(t *testing.T) {
+		list, i, err2 := newService.GetTeamList(&pb.GetTeamListRequest{
+			Page:     1,
+			PageSize: 10,
+		})
+		fmt.Println(list)
+		fmt.Println(i)
+		fmt.Println(err2)
+	})
+	t.Run("获取详情", func(t *testing.T) {
+		authutil.NewJWTAuth(redis.NewClient(&redis.Options{
+			Addr:     "localhost:6379", // Redis 服务器地址
+			Password: "xugang131500",   // Redis 密码,如果有的话
+			DB:       0,                // 默认数据库
+		}), "authorizationservice", true)
+		team, err2 := newService.GetTeam(&pb.GetTeamRequest{Keyword: "shoppingservice_wanke"})
+		fmt.Println(team)
+		inspect, err2 := authutil.JWTAuthService.Inspect(team.Credential)
+		if value, ok := inspect.Metadata["expiry"]; ok {
+			expiry, _ := strconv.ParseInt(value, 10, 64)
+			fmt.Println("expiry", expiry-time.Now().Unix())
+		}
+		fmt.Println(inspect)
+		fmt.Println(err2)
+	})
+	// service.NewService(repo)
+}

+ 61 - 3
utils/authutil/authutil.go

@@ -15,6 +15,7 @@ import (
 	"os/signal"
 	"sghgogs.com/micro/common"
 	"sghgogs.com/micro/common/errorcode"
+	"strconv"
 	"strings"
 	"sync"
 	"syscall"
@@ -99,7 +100,15 @@ func (svc *JWTAuth) GetRuleItems() []*auth.Rule {
 }
 
 // GenerateToken 示例:生成令牌
-func (svc *JWTAuth) GenerateToken(userID int64, provider, withType, secret string, scopes []string, md map[string]string) (*auth.Account, error) {
+func (svc *JWTAuth) GenerateToken(
+	userID int64,
+	provider,
+	withType,
+	secret string,
+	scopes []string,
+	md map[string]string,
+	expiry time.Duration,
+) (*auth.Account, error) {
 	var account *auth.Account
 	lock := svc.Mu.NewMutex(fmt.Sprintf("generate-token-lock-%d", userID))
 	// 获取锁,保证原子性
@@ -123,9 +132,58 @@ func (svc *JWTAuth) GenerateToken(userID int64, provider, withType, secret strin
 	}
 	return generate, nil
 }
+func (svc *JWTAuth) GenerateTeamToken(teamID int64, md map[string]string) (*auth.Account, error) {
+	var account *auth.Account
+	lock := svc.Mu.NewMutex(fmt.Sprintf("generate-token-lock-team-%d", teamID))
+	// 获取锁,保证原子性
+	if err := lock.Lock(); err != nil {
+		return account, err
+	}
+	defer lock.Unlock()
+	generate, err := svc.Auth.Generate(
+		fmt.Sprintf("%d", teamID),
+		auth.WithType("user"),
+		auth.WithProvider("system"),
+		auth.WithMetadata(md),
+	)
+	if err != nil {
+		code := common.FailedToGenerateTokenErrorCode
+		return account, errorcode.New(svc.namespace, common.ErrorMessage[code], int32(code))
+	}
+	return generate, nil
+}
+
+func (svc *JWTAuth) RefreshToken(token string) (*auth.Token, error) {
+	var authToken *auth.Token
+	lock := svc.Mu.NewMutex(fmt.Sprintf("%v-refresh-generate-token-lock", svc.namespace))
+	// 获取锁,保证原子性
+	if err := lock.Lock(); err != nil {
+		return authToken, err
+	}
+	defer lock.Unlock()
+	inspect, err := svc.Auth.Inspect(token)
+	if err != nil {
+		return authToken, err
+	}
+	inspect.Metadata["expiry"] = fmt.Sprintf("%d", time.Now().Add(expiry).Unix())
+	generate, err := svc.Auth.Generate(
+		inspect.Metadata["id"],
+		auth.WithType("user"),
+		auth.WithProvider("system"),
+		auth.WithScopes(strings.Join(inspect.Scopes, ",")),
+		auth.WithSecret(inspect.Metadata["password"]),
+		auth.WithMetadata(inspect.Metadata),
+	)
+	if err != nil {
+		code := common.FailedToGenerateTokenErrorCode
+		return authToken, errorcode.New(svc.namespace, common.ErrorMessage[code], int32(code))
+	}
+	userId, _ := strconv.ParseInt(inspect.Metadata["id"], 10, 64)
+	return svc.Token(userId, generate.Secret, expiry)
+}
 
 // Token 重新刷新token
-func (svc *JWTAuth) Token(userID int64, accessToken string) (*auth.Token, error) {
+func (svc *JWTAuth) Token(userID int64, accessToken string, expiry time.Duration) (*auth.Token, error) {
 	var authToken *auth.Token
 	lock := svc.Mu.NewMutex(fmt.Sprintf("token-lock-%d", userID))
 	// 获取锁,保证原子性
@@ -154,7 +212,7 @@ func (svc *JWTAuth) Inspect(accessToken string) (*auth.Account, error) {
 }
 
 // StoreToken 存储令牌到Redis
-func (svc *JWTAuth) StoreToken(ctx context.Context, ID int64, name, accessToken string) error {
+func (svc *JWTAuth) StoreToken(ctx context.Context, ID int64, name, accessToken string, expiry time.Duration) error {
 	lock := svc.Mu.NewMutex(fmt.Sprintf("store-token-lock-%d", ID))
 	// 获取锁
 	if err := lock.Lock(); err != nil {

+ 3 - 0
utils/middleware/middleware.go

@@ -170,6 +170,9 @@ func NewAuthWrapper(service micro.Service) server.HandlerWrapper {
 			if req.Endpoint() == "CommonService.AdminLogin" {
 				return h(ctx, req, rsp)
 			}
+			if req.Endpoint() == "TeamService.GetTeam" {
+				return h(ctx, req, rsp)
+			}
 			if req.Endpoint() == "AdminUserService.GetAdminUserAssociatedRoles" {
 				return h(ctx, req, rsp)
 			}

+ 0 - 0
utils/tracing/tracing.go