浏览代码

用户管理

xjg 4 月之前
父节点
当前提交
f80af8f980

+ 10 - 0
domain/model/request/product.go

@@ -13,4 +13,14 @@ type Product struct {
 	UpdatedAt     *time.Time `json:"updated_at"`
 	CategoryID    int64      `json:"category_id"`
 	Category      Category   `gorm:"foreignKey:CategoryID" json:"category"`
+	Images        []Image    `gorm:"foreignKey:ProductID" json:"images"`
+}
+
+// Image 图片表模型
+type Image struct {
+	ID        int64      `gorm:"primary_key;not_null;auto_increment;" json:"id"`
+	URL       string     `json:"url"` // 图片 URL
+	ProductID int64      `json:"product_id"`
+	CreatedAt time.Time  `json:"created_at"`
+	UpdatedAt *time.Time `json:"updated_at"`
 }

+ 25 - 2
domain/repository/adminuser.go

@@ -2,11 +2,29 @@ package repository
 
 import (
 	"fmt"
+	"github.com/pkg/errors"
+	"gorm.io/gorm"
 	"sghgogs.com/micro/shopping-service/domain/model/base"
 	req "sghgogs.com/micro/shopping-service/domain/model/request"
 	pb "sghgogs.com/micro/shopping-service/proto"
+	"sghgogs.com/micro/shopping-service/utils"
 )
 
+func (u *Repository) IsAdminUserExists(identifier interface{}) (bool, error) {
+	var user req.User
+	if err := u.db.
+		Where("id = ? OR username = ?", identifier, identifier).
+		Where("group_id", utils.AdminUserGroupID).
+		Select("id, username").
+		First(&user).Error; err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return false, nil // 记录不存在,账号不存在
+		}
+		return false, err // 发生其他错误
+	}
+	return true, nil
+}
+
 func (u *Repository) GetAdminUserList(query *pb.GetAdminUserListRequest) ([]*req.User, int64, error) {
 	tx := u.db.Model(&req.User{}).
 		Where("group_id", 1).
@@ -35,7 +53,7 @@ func (u *Repository) GetAllAdminUser() ([]*req.User, error) {
 func (u *Repository) GetAdminUser(userID int64) (*req.User, error) {
 	var user *req.User
 	return user, u.db.
-		Where("id = ? AND status = ? AND group_id = ?", userID, pb.StatusEnum_ENABLED, 1).
+		Where("id = ? AND status = ? AND group_id = ?", userID, pb.StatusEnum_ENABLED, utils.AdminUserGroupID).
 		Select("id, username, phone_number, email, avatar, created_at, updated_at, status").
 		Preload("Roles").
 		Find(&user).Error
@@ -153,7 +171,12 @@ func (u *Repository) DeleteAdminUser(userID int64) error {
 			tx.Rollback()
 		}
 	}()
-	if err := tx.Model(&req.User{}).Where("id = ?", userID).Association("Roles").Clear(); err != nil {
+	var user req.User
+	if err := tx.First(&user, userID).Error; err != nil {
+		tx.Rollback()
+		return err
+	}
+	if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
 		tx.Rollback()
 		return err
 	}

+ 8 - 1
domain/repository/auth.go

@@ -9,6 +9,13 @@ func (u *Repository) Login(username string) (req.User, error) {
 	var user req.User
 	return user, u.db.Where("username = ?", username).
 		Preload("Roles", "status =?", pb.StatusEnum_ENABLED).
-		Preload("Group").
 		First(&user).Error
 }
+
+func (u *Repository) Profile(userID int64) (req.User, error) {
+	var user req.User
+	return user, u.db.
+		Select("id, username, phone_number, email, avatar, created_at, status").
+		Preload("Roles", "status = ?", pb.StatusEnum_ENABLED).
+		First(&user, userID).Error
+}

+ 17 - 6
domain/repository/repository.go

@@ -6,10 +6,22 @@ import (
 	pb "sghgogs.com/micro/shopping-service/proto"
 )
 
+// CreateUser(*pb.CreateUserRequest, map[string]interface{}) error
+// GetUserList(*pb.GetUserListRequest) ([]req.User, int64, error)
+// GetUser(int64) (req.User, error)
+// GetUserSelect(int64, string) (req.User, error)
+// UpdateUserRoles(int64, []int64) error // 更新用户角色
+// UpdateUserPassword(int64, map[string]interface{}) error
+// UpdateUserPhoneNumber(int64, map[string]interface{}) error
+// ToggleUser(int64, map[string]interface{}) error
+// DeleteUser(int64) error
+
 type IRepository interface {
 	InitTable() error
 
 	Login(string) (req.User, error)
+	Profile(int64) (req.User, error)
+
 	GetAdminUserList(*pb.GetAdminUserListRequest) ([]*req.User, int64, error)
 	GetAllAdminUser() ([]*req.User, error)
 	GetAdminUser(int64) (*req.User, error)
@@ -17,16 +29,14 @@ type IRepository interface {
 	UpdateAdminUser(int64, []int64, map[string]interface{}) error
 	ToggleAdminUser(int64, pb.StatusEnum, map[string]interface{}) error
 	DeleteAdminUser(int64) error
+	IsAdminUserExists(interface{}) (bool, error)
 
-	CreateUser(*pb.CreateUserRequest, map[string]interface{}) error
 	GetUserList(*pb.GetUserListRequest) ([]req.User, int64, error)
 	GetUser(int64) (req.User, error)
-	GetUserSelect(int64, string) (req.User, error)
-	UpdateUserRoles(int64, []int64) error // 更新用户角色
-	UpdateUserPassword(int64, map[string]interface{}) error
-	UpdateUserPhoneNumber(int64, map[string]interface{}) error
-	ToggleUser(int64, map[string]interface{}) error
+	CreateUser(*req.User) error
+	UpdateUser(int64, map[string]interface{}) error
 	DeleteUser(int64) error
+	ToggleUser(int64, pb.StatusEnum, map[string]interface{}) error
 	IsUserExists(interface{}) (bool, error)
 
 	CreateUserGroup(*pb.CreateUserGroupRequest) error
@@ -110,6 +120,7 @@ func (u *Repository) InitTable() error {
 		req.OrderItem{},
 		req.Payment{},
 		req.Product{},
+		req.Image{},
 		req.ShoppingCart{},
 		req.ShoppingCartItem{},
 	)

+ 81 - 112
domain/repository/user.go

@@ -7,12 +7,18 @@ import (
 	"sghgogs.com/micro/shopping-service/domain/model/base"
 	req "sghgogs.com/micro/shopping-service/domain/model/request"
 	pb "sghgogs.com/micro/shopping-service/proto"
+	"sghgogs.com/micro/shopping-service/utils"
+)
+
+const (
+	UserGroupID = 2
 )
 
 func (u *Repository) IsUserExists(identifier interface{}) (bool, error) {
 	var user req.User
 	if err := u.db.
 		Where("id = ? OR username = ?", identifier, identifier).
+		Where("group_id", utils.UserUserGroupID).
 		Select("id, username").
 		First(&user).Error; err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
@@ -23,53 +29,10 @@ func (u *Repository) IsUserExists(identifier interface{}) (bool, error) {
 	return true, nil
 }
 
-func (u *Repository) CreateUser(query *pb.CreateUserRequest, newUser map[string]interface{}) error {
-	// 开始事务
-	tx := u.db.Begin()
-	// 错误处理
-	defer func() {
-		if r := recover(); r != nil {
-			tx.Rollback()
-		}
-	}()
-	if err := tx.Model(&req.User{}).Create(&newUser).Error; err != nil {
-		tx.Rollback()
-		return err
-	}
-	var user req.User
-	if err := tx.Model(&req.User{}).Where("username = ?", query.Username).First(&user).Error; err != nil {
-		tx.Rollback()
-		return err
-	}
-	// 角色关联
-	if len(query.Roles) > 0 {
-		if _, err := u.getRoleValidIDs(query.Roles); err != nil {
-			tx.Rollback()
-			return err
-		}
-		roles := make([]req.Role, 0)
-		for _, ID := range query.Roles {
-			roles = append(roles, req.Role{ID: ID})
-		}
-		if err := tx.Model(&user).Association("Roles").Append(&roles); err != nil {
-			tx.Rollback()
-			return err
-		}
-	}
-	return tx.Commit().Error
-}
-
-// func (u *Repository) GetAllAdminUser() ([]req.User, error) {
-// 	users := make([]req.User, 0)
-// 	return users, u.db.Model(&req.User{}).
-// 		Select("id, username").
-// 		Where("group_id = ? AND status = ?", 1, pb.StatusEnum_ENABLED).
-// 		Find(&users).Error
-// }
-
 func (u *Repository) GetUserList(query *pb.GetUserListRequest) ([]req.User, int64, error) {
 	tx := u.db.Model(&req.User{}).
-		Preload("Group", "code ? = ", "17a78673-9762-4e9e-8f87-595a049f75bf").
+		Where("group_id = ?", utils.UserUserGroupID).
+		Select("id, username, phone_number, email, avatar, created_at, created_by, updated_at, updated_by, status").
 		Order("id desc")
 	if query.Keyword != "" {
 		tx.Where("username = ? OR phone_number = ?", query.Keyword, query.Keyword)
@@ -83,32 +46,16 @@ func (u *Repository) GetUserList(query *pb.GetUserListRequest) ([]req.User, int6
 	return users, totalCount, tx.Limit(int(query.PageSize)).Offset(int((query.Page - 1) * query.PageSize)).Find(&users).Error
 }
 
-func (u *Repository) GetUserSelect(userID int64, query string) (req.User, error) {
-	var user req.User
-	return user, u.db.
-		Where("id = ? AND status = ?", userID, pb.StatusEnum_ENABLED).
-		Select(query).
-		Find(&user).Error
-}
 func (u *Repository) GetUser(userID int64) (req.User, error) {
 	var user req.User
 	return user, u.db.
-		Where("id = ? AND status = ?", userID, pb.StatusEnum_ENABLED).
-		Select("id, username, phone_number, email, avatar, created_at, updated_at, status").
-		Preload("Roles").
-		// Preload("UserAuth").
-		// Preload("Orders", func(db *gorm.DB) *gorm.DB {
-		// 	return db.Preload("Address").Preload("Payment")
-		// }).
-		// Preload("ShoppingCart", func(db *gorm.DB) *gorm.DB {
-		// 	return db.Preload("Items", func(db *gorm.DB) *gorm.DB {
-		// 		return db.Preload("Product").Preload("Product.Category")
-		// 	})
-		// }).
+		Where("id = ? AND group_id = ?", userID, utils.UserUserGroupID).
+		Select("id, username, phone_number, email, avatar, created_at, created_by, updated_at, updated_by, status").
+		// Preload("Roles").
 		Find(&user).Error
 }
 
-func (u *Repository) UpdateUserRoles(userID int64, roleIDs []int64) error {
+func (u *Repository) CreateUser(user *req.User) error {
 	// 开始事务
 	tx := u.db.Begin()
 	// 错误处理
@@ -117,34 +64,23 @@ func (u *Repository) UpdateUserRoles(userID int64, roleIDs []int64) error {
 			tx.Rollback()
 		}
 	}()
-	var user req.User
-	if err := tx.First(&user, userID).Error; err != nil {
+	if err := tx.Model(&req.User{}).Create(user).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
-	if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
+	var role req.Role
+	if err := tx.Model(&req.Role{}).Where("name = ?", "user").First(&role).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
-	// 角色关联
-	if len(roleIDs) > 0 {
-		if _, err := u.getRoleValidIDs(roleIDs); err != nil {
-			tx.Rollback()
-			return err
-		}
-		roles := make([]req.Role, 0)
-		for _, ID := range roleIDs {
-			roles = append(roles, req.Role{ID: ID})
-		}
-		if err := tx.Model(&user).Association("Roles").Append(&roles); err != nil {
-			tx.Rollback()
-			return err
-		}
+	if err := tx.Model(&user).Association("Roles").Append(&req.Role{ID: role.ID}); err != nil {
+		tx.Rollback()
+		return err
 	}
 	return tx.Commit().Error
 }
 
-func (u *Repository) UpdateUserPassword(userID int64, user map[string]interface{}) error {
+func (u *Repository) UpdateUser(userID int64, user map[string]interface{}) error {
 	// 开始事务
 	tx := u.db.Begin()
 	// 错误处理
@@ -153,14 +89,14 @@ func (u *Repository) UpdateUserPassword(userID int64, user map[string]interface{
 			tx.Rollback()
 		}
 	}()
-	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(&user).Error; err != nil {
+	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(user).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
 	return tx.Commit().Error
 }
 
-func (u *Repository) UpdateUserPhoneNumber(userID int64, user map[string]interface{}) error {
+func (u *Repository) DeleteUser(userID int64) error {
 	// 开始事务
 	tx := u.db.Begin()
 	// 错误处理
@@ -169,39 +105,26 @@ func (u *Repository) UpdateUserPhoneNumber(userID int64, user map[string]interfa
 			tx.Rollback()
 		}
 	}()
-	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(&user).Error; err != nil {
+	var user req.User
+	if err := tx.First(&user, userID).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
-	roles := []req.Role{
-		{ID: 3},
-	}
-	// 关联
-	if err := tx.Model(&user).Association("Roles").Append(&roles); err != nil {
+	if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
 		tx.Rollback()
 		return err
 	}
-	return tx.Commit().Error
-}
-
-func (u *Repository) ToggleUser(userID int64, user map[string]interface{}) error {
-	// 开始事务
-	tx := u.db.Begin()
-	// 错误处理
-	defer func() {
-		if r := recover(); r != nil {
-			tx.Rollback()
-		}
-	}()
-	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(&user).Error; err != nil {
+	if err := tx.Model(&req.User{}).Unscoped().Delete(&req.User{ID: userID}).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
 	return tx.Commit().Error
 }
 
-func (u *Repository) DeleteUser(userID int64) error {
-	// 开始事务
+func (u *Repository) ToggleUser(userID int64, enum pb.StatusEnum, data map[string]interface{}) error {
+	// pb.StatusEnum_DELETED {}
+	fmt.Println("data", data)
+	// 1. 开启事务
 	tx := u.db.Begin()
 	// 错误处理
 	defer func() {
@@ -210,23 +133,69 @@ func (u *Repository) DeleteUser(userID int64) error {
 		}
 	}()
 	var user req.User
+	// 1.查询角色
 	if err := tx.First(&user, userID).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
-	if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
-		tx.Rollback()
-		return err
+	if enum == pb.StatusEnum_DELETED {
+		// 1.1删除关联角色
+		if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
+			tx.Rollback()
+			return err
+		}
 	}
-	if err := tx.Model(&req.User{}).Delete(&req.User{
-		ID: userID,
-	}).Error; err != nil {
+	// 2. 更新状态
+	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(data).Error; err != nil {
 		tx.Rollback()
 		return err
 	}
 	return tx.Commit().Error
 }
 
+// func (u *Repository) ToggleUser(userID int64, user map[string]interface{}) error {
+// 	// 开始事务
+// 	tx := u.db.Begin()
+// 	// 错误处理
+// 	defer func() {
+// 		if r := recover(); r != nil {
+// 			tx.Rollback()
+// 		}
+// 	}()
+// 	if err := tx.Model(&req.User{}).Where("id = ?", userID).Updates(&user).Error; err != nil {
+// 		tx.Rollback()
+// 		return err
+// 	}
+// 	return tx.Commit().Error
+// }
+//
+// func (u *Repository) DeleteUser(userID int64) error {
+// 	// 开始事务
+// 	tx := u.db.Begin()
+// 	// 错误处理
+// 	defer func() {
+// 		if r := recover(); r != nil {
+// 			tx.Rollback()
+// 		}
+// 	}()
+// 	var user req.User
+// 	if err := tx.First(&user, userID).Error; err != nil {
+// 		tx.Rollback()
+// 		return err
+// 	}
+// 	if err := tx.Model(&user).Association("Roles").Clear(); err != nil {
+// 		tx.Rollback()
+// 		return err
+// 	}
+// 	if err := tx.Model(&req.User{}).Delete(&req.User{
+// 		ID: userID,
+// 	}).Error; err != nil {
+// 		tx.Rollback()
+// 		return err
+// 	}
+// 	return tx.Commit().Error
+// }
+
 // 检测用户ID如果不存在会抛出错误
 func (u *Repository) getUserValidIDs(ids []int64) ([]int64, error) {
 	var validIDs []int64

+ 32 - 11
domain/service/adminuser.go

@@ -14,12 +14,12 @@ import (
 	"time"
 )
 
-func (svc *Service) GetAdminUserList(query *pb.GetAdminUserListRequest) ([]*pb.User, int64, error) {
+func (svc *Service) GetAdminUserList(params *pb.GetAdminUserListRequest) ([]*pb.User, int64, error) {
 	users := make([]*pb.User, 0)
-	list, count, err := svc.Repository.GetAdminUserList(query)
+	list, count, err := svc.Repository.GetAdminUserList(params)
 	if err != nil {
 		if errors.Is(err, gorm.ErrRecordNotFound) {
-			return users, 0, nil // 记录不存在,角色不存在
+			return users, 0, nil
 		} else {
 			return users, 0, err
 		}
@@ -45,16 +45,16 @@ func (svc *Service) GetAllAdminUser() ([]*pb.Base, error) {
 	return bases, nil
 }
 
-func (svc *Service) GetAdminUser(query *pb.GetAdminUserRequest) (*pb.User, error) {
+func (svc *Service) GetAdminUser(params *pb.GetAdminUserRequest) (*pb.User, error) {
 	var rsp *pb.User
-	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
+	if exists, err := svc.Repository.IsAdminUserExists(params.UserId); err != nil {
 		return rsp, errorcode.New(svc.Namespace, err.Error(), 500)
 	} else {
 		if !exists {
 			return rsp, errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
-	user, err := svc.Repository.GetAdminUser(query.UserId)
+	user, err := svc.Repository.GetAdminUser(params.UserId)
 	if err != nil {
 		return rsp, errorcode.New(svc.Namespace, err.Error(), 500)
 	}
@@ -88,6 +88,13 @@ func (svc *Service) CreateAdminUser(ctx context.Context, data *pb.CreateAdminUse
 }
 
 func (svc *Service) UpdateAdminUser(ctx context.Context, data *pb.UpdateAdminUserRequest) error {
+	if exists, err := svc.Repository.IsAdminUserExists(data.UserId); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), 500)
+	} else {
+		if !exists {
+			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+		}
+	}
 	_, by, _, _ := utils.ParseMetadata(ctx)
 	m := map[string]interface{}{
 		"email":        data.Email,
@@ -102,20 +109,34 @@ func (svc *Service) UpdateAdminUser(ctx context.Context, data *pb.UpdateAdminUse
 	return nil
 }
 
-func (svc *Service) ToggleAdminUser(ctx context.Context, query *pb.ToggleAdminUserRequest) error {
+func (svc *Service) ToggleAdminUser(ctx context.Context, data *pb.ToggleAdminUserRequest) error {
+	if exists, err := svc.Repository.IsAdminUserExists(data.UserId); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), 500)
+	} else {
+		if !exists {
+			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+		}
+	}
 	_, by, _, _ := utils.ParseMetadata(ctx)
-	if err := svc.Repository.ToggleAdminUser(query.UserId, query.Status, map[string]interface{}{
+	if err := svc.Repository.ToggleAdminUser(data.UserId, data.Status, map[string]interface{}{
 		"updated_at": time.Now(),
 		"updated_by": by,
-		"status":     query.Status,
+		"status":     data.Status,
 	}); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
 	}
 	return nil
 }
 
-func (svc *Service) DeleteAdminUser(query *pb.DeleteAdminUserRequest) error {
-	if err := svc.Repository.DeleteUser(query.UserId); err != nil {
+func (svc *Service) DeleteAdminUser(data *pb.DeleteAdminUserRequest) error {
+	if exists, err := svc.Repository.IsAdminUserExists(data.UserId); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), 500)
+	} else {
+		if !exists {
+			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+		}
+	}
+	if err := svc.Repository.DeleteAdminUser(data.UserId); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
 	}
 	return nil

+ 47 - 10
domain/service/auth.go

@@ -1,30 +1,67 @@
 package service
 
 import (
+	"github.com/pkg/errors"
+	"gorm.io/gorm"
 	"sghgogs.com/micro/common"
 	"sghgogs.com/micro/common/errorcode"
 	pb "sghgogs.com/micro/shopping-service/proto"
 	"sghgogs.com/micro/shopping-service/utils"
 )
 
-func (svc *Service) Login(auth *pb.LoginRequest) (*pb.User, error) {
+func (svc *Service) Login(auth *pb.LoginRequest) (*pb.User, int64, error) {
 	var user *pb.User
-	if exists, err := svc.Repository.IsUserExists(auth.Username); err != nil {
-		return user, errorcode.New(svc.Namespace, err.Error(), 500)
-	} else {
-		if !exists {
-			return user, errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+	group, err := svc.Repository.GetUserGroup(&pb.GetUserGroupRequest{Code: auth.Code})
+	if err != nil {
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return user, 0, errorcode.New(svc.Namespace, common.ErrorMessage[common.InvalidCodeError], 500)
+		}
+		return user, 0, errorcode.New(svc.Namespace, err.Error(), 500)
+	}
+	if !utils.IsUserGroup(group.ID) {
+		return user, 0, errorcode.New(svc.Namespace, common.ErrorMessage[common.NotAssignedError], 500)
+	}
+	if utils.UserUserGroupID == group.ID {
+		if exists, err := svc.Repository.IsUserExists(auth.Username); err != nil {
+			return user, 0, errorcode.New(svc.Namespace, err.Error(), 500)
+		} else {
+			if !exists {
+				return user, 0, errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+			}
+		}
+	}
+	if utils.AdminUserGroupID == group.ID {
+		if exists, err := svc.Repository.IsAdminUserExists(auth.Username); err != nil {
+			return user, 0, errorcode.New(svc.Namespace, err.Error(), 500)
+		} else {
+			if !exists {
+				return user, 0, errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
+			}
 		}
 	}
 	login, err := svc.Repository.Login(auth.Username)
 	if err != nil {
-		return user, errorcode.New(svc.Namespace, err.Error(), 500)
+		return user, 0, errorcode.New(svc.Namespace, err.Error(), 500)
 	}
 	if !utils.CheckPasswordHash(auth.Password, login.Password) {
-		return user, errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.IncorrectPasswordErrorCode])
+		return user, 0, errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.IncorrectPasswordErrorCode])
 	}
 	res := svc.getUserRes(&login)
-	res.Roles = svc.getBaseRoleRes(login.Roles)
-	res.GroupId = login.GroupID
+	if utils.AdminUserGroupID == group.ID {
+		res.Roles = svc.getBaseRoleRes(login.Roles)
+	}
+	return res, group.ID, nil
+}
+
+func (svc *Service) Profile(groupID int64, userID int64) (*pb.User, error) {
+	// Profile
+	profile, err := svc.Repository.Profile(userID)
+	if err != nil {
+		return &pb.User{}, errorcode.New(svc.Namespace, err.Error(), 500)
+	}
+	res := svc.getUserRes(&profile)
+	if utils.AdminUserGroupID == groupID {
+		res.Roles = svc.getBaseRoleRes(profile.Roles)
+	}
 	return res, nil
 }

+ 162 - 0
domain/service/enter.go

@@ -0,0 +1,162 @@
+package service
+
+import (
+	"reflect"
+	req "sghgogs.com/micro/shopping-service/domain/model/request"
+	pb "sghgogs.com/micro/shopping-service/proto"
+	"sghgogs.com/micro/shopping-service/utils"
+	"time"
+)
+
+func (svc *Service) getPaymentRes(payment *req.Payment) *pb.Payment {
+	var updatedAt int64
+	if payment.UpdatedAt != nil {
+		if payment.CreatedAt.Truncate(time.Second) == payment.UpdatedAt.Truncate(time.Second) {
+			payment.UpdatedAt = nil
+		} else {
+			updatedAt = utils.ConvertTimeToInt64(*payment.UpdatedAt)
+		}
+	}
+	return &pb.Payment{
+		Id:            payment.ID,
+		OrderId:       payment.OrderID,
+		Amount:        payment.Amount,
+		Status:        payment.Status,
+		PaymentMethod: payment.PaymentMethod,
+		CreatedAt:     utils.ConvertTimeToInt64(payment.CreatedAt),
+		UpdatedAt:     updatedAt,
+	}
+}
+
+func (svc *Service) getUserRes(user *req.User) *pb.User {
+	var updatedAt int64
+	if user.UpdatedAt != nil {
+		if user.CreatedAt.Truncate(time.Second) == user.UpdatedAt.Truncate(time.Second) {
+			user.UpdatedAt = nil
+		} else {
+			updatedAt = utils.ConvertTimeToInt64(*user.UpdatedAt)
+		}
+	}
+	return &pb.User{
+		Id:          user.ID,
+		Username:    user.Username,
+		Password:    user.Password,
+		PhoneNumber: user.PhoneNumber,
+		Email:       user.Email,
+		Avatar:      user.Avatar,
+		CreatedAt:   utils.ConvertTimeToInt64(user.CreatedAt),
+		CreatedBy:   user.CreatedBy,
+		UpdatedAt:   updatedAt,
+		UpdatedBy:   user.UpdatedBy,
+		Status:      user.Status,
+	}
+}
+
+// func (svc *Service) getOrdersRes() []*pb.Order {
+// }
+
+func (svc *Service) getShoppingCarts(cart req.ShoppingCart) *pb.ShoppingCart {
+	return &pb.ShoppingCart{
+		Id:        cart.ID,
+		UserId:    cart.UserID,
+		CreatedAt: utils.ConvertTimeToInt64(cart.CreatedAt),
+		UpdatedAt: utils.ConvertTimeToInt64(*cart.UpdatedAt),
+		Quantity:  cart.Quantity,
+		Items:     svc.getShoppingCartItem(cart.Items),
+	}
+}
+
+func (svc *Service) getShoppingCartItem(items []req.ShoppingCartItem) []*pb.ShoppingCartItem {
+	cartItems := make([]*pb.ShoppingCartItem, 0)
+	for _, item := range items {
+		cartItems = append(cartItems, &pb.ShoppingCartItem{
+			Id:             item.ID,
+			ShoppingCartId: item.ShoppingCartID,
+			ProductId:      item.ProductID,
+			Product:        svc.getProduct(item.Product),
+			Quantity:       item.Quantity,
+			TotalPrice:     item.TotalPrice,
+		})
+	}
+	return cartItems
+}
+
+func (svc *Service) getProduct(product req.Product) *pb.Product {
+	return &pb.Product{
+		Id:            product.ID,
+		Name:          product.Name,
+		Description:   product.Description,
+		Price:         product.Price,
+		StockQuantity: product.StockQuantity,
+		CreatedAt:     utils.ConvertTimeToInt64(product.CreatedAt),
+		UpdatedAt:     utils.ConvertTimeToInt64(*product.UpdatedAt),
+		CategoryId:    product.CategoryID,
+		Category:      svc.getCategory(product.Category),
+	}
+}
+
+func (svc *Service) getCategory(category req.Category) *pb.Category {
+	return &pb.Category{
+		Id:        category.ID,
+		Name:      category.Name,
+		CreatedAt: utils.ConvertTimeToInt64(category.CreatedAt),
+		UpdatedAt: utils.ConvertTimeToInt64(*category.UpdatedAt),
+	}
+}
+
+func (svc *Service) getAddresses(address []req.Address) []*pb.Address {
+	addresses := make([]*pb.Address, 0)
+	for _, item := range address {
+		addresses = append(addresses, &pb.Address{
+			Id:        item.ID,
+			UserId:    item.UserID,
+			Country:   item.Country,
+			Province:  item.Province,
+			City:      item.City,
+			District:  item.District,
+			Remark:    item.Remark,
+			IsDefault: item.IsDefault,
+		})
+	}
+	return addresses
+}
+func (svc *Service) filterNilFields(m map[string]interface{}) map[string]interface{} {
+	result := make(map[string]interface{})
+	for key, value := range m {
+		// 判断是否为布尔值或数值类型的默认零值
+		if value != reflect.Zero(reflect.TypeOf(value)).Interface() {
+			result[key] = value
+		}
+	}
+	return result
+}
+
+func (svc *Service) getOrdersRes(orders []req.Order) []*pb.Order {
+	items := make([]*pb.Order, 0)
+	for _, item := range orders {
+		items = append(items, svc.getOrderRes(item))
+	}
+	return items
+}
+func (svc *Service) getOrderRes(order req.Order) *pb.Order {
+	var updatedAt int64
+	if order.UpdatedAt != nil {
+		if order.CreatedAt.Truncate(time.Second) == order.UpdatedAt.Truncate(time.Second) {
+			order.UpdatedAt = nil
+		} else {
+			updatedAt = utils.ConvertTimeToInt64(*order.UpdatedAt)
+		}
+	}
+	return &pb.Order{
+		Id:            order.ID,
+		UserId:        order.UserID,
+		AddressId:     order.AddressID,
+		Address:       svc.getAddressRes(order.Address),
+		TotalAmount:   order.TotalAmount,
+		Status:        order.Status,
+		PaymentMethod: order.PaymentMethod,
+		CreatedAt:     utils.ConvertTimeToInt64(order.CreatedAt),
+		UpdatedAt:     updatedAt,
+		Payment:       svc.getPaymentRes(&order.Payment),
+	}
+}

+ 30 - 155
domain/service/service.go

@@ -2,16 +2,13 @@ package service
 
 import (
 	"context"
-	"reflect"
-	req "sghgogs.com/micro/shopping-service/domain/model/request"
 	"sghgogs.com/micro/shopping-service/domain/repository"
 	pb "sghgogs.com/micro/shopping-service/proto"
-	"sghgogs.com/micro/shopping-service/utils"
-	"time"
 )
 
 type IService interface {
-	Login(request *pb.LoginRequest) (*pb.User, error) // admin
+	Login(request *pb.LoginRequest) (*pb.User, int64, error) // admin
+	Profile(int64, int64) (*pb.User, error)
 
 	GetAdminUserList(*pb.GetAdminUserListRequest) ([]*pb.User, int64, error)
 	GetAllAdminUser() ([]*pb.Base, error)
@@ -23,12 +20,35 @@ type IService interface {
 
 	GetUserList(*pb.GetUserListRequest) ([]*pb.User, int64, error)
 	GetUser(*pb.GetUserRequest) (*pb.User, error)
-	CreateUser(*pb.CreateUserRequest) error
-	UpdateUserRoles(*pb.UpdateUserRolesRequest) error
-	UpdateUserPassword(*pb.UpdateUserPasswordRequest) error
-
-	ToggleUser(*pb.ToggleUserRequest) error
+	CreateUser(context.Context, *pb.CreateUserRequest) error
+	UpdateUser(context.Context, *pb.UpdateUserRequest) error
 	DeleteUser(*pb.DeleteUserRequest) error
+	ToggleUser(context.Context, *pb.ToggleUserRequest) error
+
+	GetRoleList(*pb.GetRoleListRequest) ([]*pb.Role, int64, error)
+	GetRole(*pb.GetRoleRequest) (*pb.Role, error)
+	GetAllRoles() ([]*pb.Base, error)
+	CreateRole(context.Context, *pb.CreateRoleRequest) error
+	UpdateRole(context.Context, *pb.UpdateRoleRequest) error
+	ToggleRole(context.Context, *pb.ToggleRoleRequest) error
+	DeleteRole(*pb.DeleteRoleRequest) error
+
+	GetPermissionList(*pb.GetPermissionListRequest) ([]*pb.Permission, int64, error)
+	GetPermission(*pb.GetPermissionRequest) (*pb.Permission, error)
+	CreatePermission(context.Context, *pb.CreatePermissionRequest) error
+	UpdatePermission(context.Context, *pb.UpdatePermissionRequest) error
+	CreateMultiplePermissions(context.Context, *pb.CreateMultiplePermissionsRequest) error
+	DeletePermission(*pb.DeletePermissionRequest) error
+	TogglePermission(*pb.TogglePermissionRequest) error
+
+	// GetUserList(*pb.GetUserListRequest) ([]*pb.User, int64, error)
+	// GetUser(*pb.GetUserRequest) (*pb.User, error)
+	// CreateUser(*pb.CreateUserRequest) error
+	// UpdateUserRoles(*pb.UpdateUserRolesRequest) error
+	// UpdateUserPassword(*pb.UpdateUserPasswordRequest) error
+
+	// ToggleUser(*pb.ToggleUserRequest) error
+	// DeleteUser(*pb.DeleteUserRequest) error
 
 	CreateUserGroup(*pb.CreateUserGroupRequest) error
 	GetUserGroup(*pb.GetUserGroupRequest) (pb.UserGroup, error)
@@ -57,30 +77,6 @@ type IService interface {
 	CreateOrderItem(*pb.CreateOrderItemRequest) error
 
 	CreatePayment(*pb.CreatePaymentRequest) error
-
-	// Login(*pb.AdminLoginRequest) (*pb.AdminUser, error) // 登录
-	// GetAdminUserList(*pb.GetAdminUserListRequest) ([]*pb.AdminUser, int64, error)
-	// GetAdminUser(*pb.GetAdminUserRequest) (*pb.AdminUser, error)
-	// CreateAdminUser(context.Context, *pb.CreateAdminUserRequest) error
-	// UpdateAdminUser(context.Context, *pb.UpdateAdminUserRequest) error
-	// ToggleAdminUser(context.Context, *pb.ToggleAdminUserRequest) error
-	// DeleteAdminUser(*pb.DeleteAdminUserRequest) error
-
-	GetRoleList(*pb.GetRoleListRequest) ([]*pb.Role, int64, error)
-	GetRole(*pb.GetRoleRequest) (*pb.Role, error)
-	GetAllRoles() ([]*pb.Base, error)
-	CreateRole(context.Context, *pb.CreateRoleRequest) error
-	UpdateRole(context.Context, *pb.UpdateRoleRequest) error
-	ToggleRole(context.Context, *pb.ToggleRoleRequest) error
-	DeleteRole(*pb.DeleteRoleRequest) error
-
-	GetPermissionList(*pb.GetPermissionListRequest) ([]*pb.Permission, int64, error)
-	GetPermission(*pb.GetPermissionRequest) (*pb.Permission, error)
-	CreatePermission(context.Context, *pb.CreatePermissionRequest) error
-	UpdatePermission(context.Context, *pb.UpdatePermissionRequest) error
-	CreateMultiplePermissions(context.Context, *pb.CreateMultiplePermissionsRequest) error
-	DeletePermission(*pb.DeletePermissionRequest) error
-	TogglePermission(*pb.TogglePermissionRequest) error
 }
 
 func NewService(r repository.IRepository, namespace string) IService {
@@ -94,124 +90,3 @@ type Service struct {
 	Repository repository.IRepository
 	Namespace  string
 }
-
-func (svc *Service) getPaymentRes(payment *req.Payment) *pb.Payment {
-	var updatedAt int64
-	if payment.UpdatedAt != nil {
-		if payment.CreatedAt.Truncate(time.Second) == payment.UpdatedAt.Truncate(time.Second) {
-			payment.UpdatedAt = nil
-		} else {
-			updatedAt = utils.ConvertTimeToInt64(*payment.UpdatedAt)
-		}
-	}
-	return &pb.Payment{
-		Id:            payment.ID,
-		OrderId:       payment.OrderID,
-		Amount:        payment.Amount,
-		Status:        payment.Status,
-		PaymentMethod: payment.PaymentMethod,
-		CreatedAt:     utils.ConvertTimeToInt64(payment.CreatedAt),
-		UpdatedAt:     updatedAt,
-	}
-}
-
-func (svc *Service) getUserRes(user *req.User) *pb.User {
-	var updatedAt int64
-	if user.UpdatedAt != nil {
-		if user.CreatedAt.Truncate(time.Second) == user.UpdatedAt.Truncate(time.Second) {
-			user.UpdatedAt = nil
-		} else {
-			updatedAt = utils.ConvertTimeToInt64(*user.UpdatedAt)
-		}
-	}
-	return &pb.User{
-		Id:          user.ID,
-		Username:    user.Username,
-		Password:    user.Password,
-		PhoneNumber: user.PhoneNumber,
-		Email:       user.Email,
-		Avatar:      user.Avatar,
-		CreatedAt:   utils.ConvertTimeToInt64(user.CreatedAt),
-		UpdatedAt:   updatedAt,
-		Status:      user.Status,
-	}
-}
-
-// func (svc *Service) getOrdersRes() []*pb.Order {
-// }
-
-func (svc *Service) getShoppingCarts(cart req.ShoppingCart) *pb.ShoppingCart {
-	return &pb.ShoppingCart{
-		Id:        cart.ID,
-		UserId:    cart.UserID,
-		CreatedAt: utils.ConvertTimeToInt64(cart.CreatedAt),
-		UpdatedAt: utils.ConvertTimeToInt64(*cart.UpdatedAt),
-		Quantity:  cart.Quantity,
-		Items:     svc.getShoppingCartItem(cart.Items),
-	}
-}
-
-func (svc *Service) getShoppingCartItem(items []req.ShoppingCartItem) []*pb.ShoppingCartItem {
-	cartItems := make([]*pb.ShoppingCartItem, 0)
-	for _, item := range items {
-		cartItems = append(cartItems, &pb.ShoppingCartItem{
-			Id:             item.ID,
-			ShoppingCartId: item.ShoppingCartID,
-			ProductId:      item.ProductID,
-			Product:        svc.getProduct(item.Product),
-			Quantity:       item.Quantity,
-			TotalPrice:     item.TotalPrice,
-		})
-	}
-	return cartItems
-}
-
-func (svc *Service) getProduct(product req.Product) *pb.Product {
-	return &pb.Product{
-		Id:            product.ID,
-		Name:          product.Name,
-		Description:   product.Description,
-		Price:         product.Price,
-		StockQuantity: product.StockQuantity,
-		CreatedAt:     utils.ConvertTimeToInt64(product.CreatedAt),
-		UpdatedAt:     utils.ConvertTimeToInt64(*product.UpdatedAt),
-		CategoryId:    product.CategoryID,
-		Category:      svc.getCategory(product.Category),
-	}
-}
-
-func (svc *Service) getCategory(category req.Category) *pb.Category {
-	return &pb.Category{
-		Id:        category.ID,
-		Name:      category.Name,
-		CreatedAt: utils.ConvertTimeToInt64(category.CreatedAt),
-		UpdatedAt: utils.ConvertTimeToInt64(*category.UpdatedAt),
-	}
-}
-
-func (svc *Service) getAddresses(address []req.Address) []*pb.Address {
-	addresses := make([]*pb.Address, 0)
-	for _, item := range address {
-		addresses = append(addresses, &pb.Address{
-			Id:        item.ID,
-			UserId:    item.UserID,
-			Country:   item.Country,
-			Province:  item.Province,
-			City:      item.City,
-			District:  item.District,
-			Remark:    item.Remark,
-			IsDefault: item.IsDefault,
-		})
-	}
-	return addresses
-}
-func (svc *Service) filterNilFields(m map[string]interface{}) map[string]interface{} {
-	result := make(map[string]interface{})
-	for key, value := range m {
-		// 判断是否为布尔值或数值类型的默认零值
-		if value != reflect.Zero(reflect.TypeOf(value)).Interface() {
-			result[key] = value
-		}
-	}
-	return result
-}

+ 56 - 193
domain/service/user.go

@@ -1,6 +1,7 @@
 package service
 
 import (
+	"context"
 	"github.com/pkg/errors"
 	"gorm.io/gorm"
 	"net/http"
@@ -12,70 +13,6 @@ import (
 	"time"
 )
 
-func (svc *Service) CreateUser(query *pb.CreateUserRequest) error {
-	if exists, err := svc.Repository.IsUserExists(query.Username); err != nil {
-		return errorcode.New(svc.Namespace, err.Error(), 500)
-	} else {
-		if exists {
-			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
-		}
-	}
-	group, err := svc.Repository.GetUserGroup(&pb.GetUserGroupRequest{Code: query.Code})
-	if err != nil {
-		if errors.Is(err, gorm.ErrRecordNotFound) {
-			return errorcode.New(svc.Namespace, "Invalid user group", 500)
-		} else {
-			return errorcode.New(svc.Namespace, err.Error(), 500)
-		}
-	}
-	password, _ := utils.HashPassword(query.Password)
-	user := map[string]interface{}{
-		"username":     query.Username,
-		"password":     password,
-		"phone_number": query.PhoneNumber,
-		"email":        query.Email,
-		"avatar":       query.Avatar,
-		"created_at":   time.Now(),
-		"group_id":     group.ID,
-		"status":       pb.StatusEnum_ENABLED,
-	}
-	if err = svc.Repository.CreateUser(query, user); err != nil {
-		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
-	}
-	return nil
-}
-
-// func (svc *Service) CreateAdminUser(create *pb.CreateAdminUserRequest) error {
-// 	if exists, err := svc.Repository.IsUserExists(create.Username); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	} else {
-// 		if exists {
-// 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
-// 		}
-// 	}
-// 	password, _ := utils.HashPassword(create.Password)
-// 	user := req.User{
-// 		Username:    create.Username,
-// 		Password:    password,
-// 		PhoneNumber: password,
-// 		Email:       create.Email,
-// 		Avatar:      create.Avatar,
-// 		CreatedAt:   time.Now(),
-// 		Status:      pb.StatusEnum_ENABLED,
-// 	}
-// 	if err := svc.Repository.CreateAdminUser(&user, create.Roles); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
-// 	}
-// 	return nil
-// }
-
-func (svc *Service) UpdateUserRoles(query *pb.UpdateUserRolesRequest) error {
-	if err := svc.Repository.UpdateUserRoles(query.UserId, query.Roles); err != nil {
-		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
-	}
-	return nil
-}
-
 func (svc *Service) GetUserList(query *pb.GetUserListRequest) ([]*pb.User, int64, error) {
 	users := make([]*pb.User, 0)
 	list, count, err := svc.Repository.GetUserList(query)
@@ -92,22 +29,6 @@ func (svc *Service) GetUserList(query *pb.GetUserListRequest) ([]*pb.User, int64
 	return users, count, nil
 }
 
-// func (svc *Service) GetAdminUserList(query *pb.GetAdminUserListRequest) ([]*pb.User, int64, error) {
-// 	users := make([]*pb.User, 0)
-// 	list, count, err := svc.Repository.GetAdminUserList(query)
-// 	if err != nil {
-// 		if errors.Is(err, gorm.ErrRecordNotFound) {
-// 			return users, 0, nil // 记录不存在,角色不存在
-// 		} else {
-// 			return users, 0, err
-// 		}
-// 	}
-// 	for _, item := range list {
-// 		users = append(users, svc.getUserRes(&item))
-// 	}
-// 	return users, count, nil
-// }
-
 func (svc *Service) GetUser(query *pb.GetUserRequest) (*pb.User, error) {
 	var rsp pb.User
 	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
@@ -117,163 +38,105 @@ func (svc *Service) GetUser(query *pb.GetUserRequest) (*pb.User, error) {
 			return &rsp, errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
+	// CreateUser
 	user, err := svc.Repository.GetUser(query.UserId)
 	if err != nil {
 		return &rsp, errorcode.New(svc.Namespace, err.Error(), 500)
 	}
 	res := svc.getUserRes(&user)
-	res.Roles = svc.getBaseRoleRes(user.Roles)
+	// res.Roles = svc.getBaseRoleRes(user.Roles)
 	return res, nil
 }
 
-func (svc *Service) UpdateUserPassword(query *pb.UpdateUserPasswordRequest) error {
-	// 1.查询账号是否存在
-	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
+func (svc *Service) CreateUser(ctx context.Context, data *pb.CreateUserRequest) error {
+	if exists, err := svc.Repository.IsUserExists(data.Username); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), 500)
 	} else {
-		if !exists {
+		if exists {
 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
-	user, err := svc.Repository.GetUser(query.UserId)
+	group, err := svc.Repository.GetUserGroup(&pb.GetUserGroupRequest{Code: data.Code})
 	if err != nil {
-		return errorcode.New(svc.Namespace, err.Error(), 500)
-	}
-	if !utils.CheckPasswordHash(query.OldPassword, user.Password) {
-		return errorcode.New(svc.Namespace, common.ErrorMessage[common.ErrOldPasswordIncorrect], 400)
-	}
-	password, _ := utils.HashPassword(query.NewPassword)
-	m := map[string]interface{}{
-		"password":   password,
-		"updated_at": time.Now(),
+		if errors.Is(err, gorm.ErrRecordNotFound) {
+			return errorcode.New(svc.Namespace, common.ErrorMessage[common.NotAssignedError], 500)
+		} else {
+			return errorcode.New(svc.Namespace, err.Error(), 500)
+		}
 	}
-	if err = svc.Repository.UpdateUserPassword(query.UserId, m); err != nil {
-		return errorcode.New(svc.Namespace, err.Error(), 500)
+	if group.ID != utils.UserUserGroupID {
+		return errorcode.New(svc.Namespace, common.ErrorMessage[common.NotAssignedError], 500)
+	}
+	password, _ := utils.HashPassword(data.Password)
+	_, by, _, _ := utils.ParseMetadata(ctx)
+	user := req.User{
+		Username:    data.Username,
+		Password:    password,
+		PhoneNumber: data.PhoneNumber,
+		Email:       data.Email,
+		Avatar:      data.Avatar,
+		CreatedAt:   time.Now(),
+		CreatedBy:   by,
+		GroupID:     utils.UserUserGroupID,
+		Status:      pb.StatusEnum_ENABLED,
+	}
+	if err = svc.Repository.CreateUser(&user); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
 	}
 	return nil
 }
 
-// func (svc *Service) UpdateUserAdminPassword(query *pb.UpdateUserAdminPasswordRequest) error {
-// 	// 1.查询账号是否存在
-// 	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	} else {
-// 		if !exists {
-// 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
-// 		}
-// 	}
-// 	password, _ := utils.HashPassword(query.NewPassword)
-// 	m := map[string]interface{}{
-// 		"password":   password,
-// 		"updated_at": time.Now(),
-// 	}
-// 	if err := svc.Repository.UpdateUserPassword(query.UserId, m); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	}
-// 	return nil
-// }
-//
-// func (svc *Service) UpdateUserPhoneNumber(query *pb.UpdateUserPhoneNumberRequest) error {
-// 	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	} else {
-// 		if !exists {
-// 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
-// 		}
-// 	}
-// 	if user, err := svc.Repository.GetUser(query.UserId); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	} else {
-// 		if user.PhoneNumber != query.OldPhoneNumber {
-// 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.ErrPhoneNumberIncorrect], 400)
-// 		}
-// 	}
-// 	m := map[string]interface{}{
-// 		"phone_number": query.NewPhoneNumber,
-// 		"updated_at":   time.Now(),
-// 	}
-// 	if err := svc.Repository.UpdateUserPhoneNumber(query.UserId, m); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	}
-// 	return nil
-// }
-//
-// func (svc *Service) UpdateUserAdminPhoneNumber(query *pb.UpdateUserAdminPhoneNumberRequest) error {
-// 	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	} else {
-// 		if !exists {
-// 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
-// 		}
-// 	}
-// 	m := map[string]interface{}{
-// 		"phone_number": query.NewPhoneNumber,
-// 		"updated_at":   time.Now(),
-// 	}
-// 	if err := svc.Repository.UpdateUserPhoneNumber(query.UserId, m); err != nil {
-// 		return errorcode.New(svc.Namespace, err.Error(), 500)
-// 	}
-// 	return nil
-// }
-
-func (svc *Service) ToggleUser(query *pb.ToggleUserRequest) error {
-	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
+func (svc *Service) UpdateUser(ctx context.Context, data *pb.UpdateUserRequest) error {
+	if exists, err := svc.Repository.IsUserExists(data.UserId); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), 500)
 	} else {
 		if !exists {
 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
+	_, by, _, _ := utils.ParseMetadata(ctx)
 	m := map[string]interface{}{
-		"status":     query.Status,
-		"updated_at": time.Now(),
+		"email":        data.Email,
+		"avatar":       data.Avatar,
+		"phone_number": data.PhoneNumber,
+		"updated_at":   time.Now(),
+		"updated_by":   by,
 	}
-	if err := svc.Repository.ToggleUser(query.UserId, m); err != nil {
+	if err := svc.Repository.UpdateUser(data.UserId, m); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), 500)
 	}
 	return nil
 }
 
-func (svc *Service) DeleteUser(query *pb.DeleteUserRequest) error {
-	if exists, err := svc.Repository.IsUserExists(query.UserId); err != nil {
+func (svc *Service) DeleteUser(data *pb.DeleteUserRequest) error {
+	if exists, err := svc.Repository.IsUserExists(data.UserId); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), 500)
 	} else {
 		if !exists {
 			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
-	if err := svc.Repository.DeleteUser(query.UserId); err != nil {
+	if err := svc.Repository.DeleteUser(data.UserId); err != nil {
 		return errorcode.New(svc.Namespace, err.Error(), 500)
 	}
 	return nil
 }
 
-func (svc *Service) getOrdersRes(orders []req.Order) []*pb.Order {
-	items := make([]*pb.Order, 0)
-	for _, item := range orders {
-		items = append(items, svc.getOrderRes(item))
-	}
-	return items
-}
-func (svc *Service) getOrderRes(order req.Order) *pb.Order {
-	var updatedAt int64
-	if order.UpdatedAt != nil {
-		if order.CreatedAt.Truncate(time.Second) == order.UpdatedAt.Truncate(time.Second) {
-			order.UpdatedAt = nil
-		} else {
-			updatedAt = utils.ConvertTimeToInt64(*order.UpdatedAt)
+func (svc *Service) ToggleUser(ctx context.Context, data *pb.ToggleUserRequest) error {
+	if exists, err := svc.Repository.IsUserExists(data.UserId); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), 500)
+	} else {
+		if !exists {
+			return errorcode.New(svc.Namespace, common.ErrorMessage[common.AccountDoesNotExist], 400)
 		}
 	}
-	return &pb.Order{
-		Id:            order.ID,
-		UserId:        order.UserID,
-		AddressId:     order.AddressID,
-		Address:       svc.getAddressRes(order.Address),
-		TotalAmount:   order.TotalAmount,
-		Status:        order.Status,
-		PaymentMethod: order.PaymentMethod,
-		CreatedAt:     utils.ConvertTimeToInt64(order.CreatedAt),
-		UpdatedAt:     updatedAt,
-		Payment:       svc.getPaymentRes(&order.Payment),
+	_, by, _, _ := utils.ParseMetadata(ctx)
+	if err := svc.Repository.ToggleAdminUser(data.UserId, data.Status, map[string]interface{}{
+		"updated_at": time.Now(),
+		"updated_by": by,
+		"status":     data.Status,
+	}); err != nil {
+		return errorcode.New(svc.Namespace, err.Error(), http.StatusBadRequest)
 	}
+	return nil
 }

+ 10 - 10
handler/auth/auth.go

@@ -22,7 +22,7 @@ type Auth struct {
 }
 
 func (svc *Auth) Login(ctx context.Context, query *pb.LoginRequest, rsp *pb.LoginResponse) error {
-	login, err := svc.Service.Login(query)
+	login, GroupID, err := svc.Service.Login(query)
 	if err != nil {
 		return err
 	}
@@ -31,7 +31,7 @@ func (svc *Auth) Login(ctx context.Context, query *pb.LoginRequest, rsp *pb.Logi
 	md["user_id"] = fmt.Sprintf("%d", login.Id)
 	md["phone_number"] = login.PhoneNumber
 	md["code"] = query.Code
-	md["group_id"] = fmt.Sprintf("%d", login.GroupId)
+	md["group_id"] = fmt.Sprintf("%d", GroupID)
 	var roles []string
 	for _, role := range login.Roles {
 		roles = append(roles, strings.ToLower(role.Key))
@@ -51,7 +51,6 @@ func (svc *Auth) Login(ctx context.Context, query *pb.LoginRequest, rsp *pb.Logi
 		return errorcode.BadRequest(svc.Namespace, common.ErrorMessage[common.FailedToStoreTokenErrorCode])
 	}
 	rsp.Data = login
-	rsp.Data.GroupId = 0
 	rsp.Token = a.AccessToken
 	return nil
 }
@@ -94,17 +93,18 @@ func (svc *Auth) Profile(ctx context.Context, request *pb.ProfileRequest, rsp *p
 	token := strings.TrimPrefix(authHeader, auth.BearerScheme)
 
 	token = strings.TrimSpace(token)
-	inspect, err := authutil.JWTAuthService.Inspect(token)
-	if err != nil {
+	inspect, errE := authutil.JWTAuthService.Inspect(token)
+	if errE != nil {
 		return errorcode.Unauthorized(svc.Namespace, common.ErrorMessage[common.TokenInvalidErrorCode])
 	}
-	if value, ok := inspect.Metadata["user_id"]; ok {
-		userId, _ := strconv.ParseInt(value, 10, 64)
-		user, err := svc.Service.GetUser(&pb.GetUserRequest{UserId: userId})
-		if err != nil {
+	if value, isOk := inspect.Metadata["user_id"]; isOk {
+		userID, _ := strconv.ParseInt(value, 10, 64)
+		groupID, _ := strconv.ParseInt(inspect.Metadata["group_id"], 10, 64)
+		if profile, err := svc.Service.Profile(groupID, userID); err != nil {
 			return err
+		} else {
+			rsp.Data = profile
 		}
-		rsp.Data = user
 	}
 	return nil
 }

+ 19 - 31
handler/user/user.go

@@ -10,61 +10,49 @@ type User struct {
 	Service service.IService
 }
 
-//
-// func (svc *User) GetAllAdminUser(ctx context.Context, request *pb.GetAllAdminUserRequest, response *pb.GetAllAdminUserResponse) error {
-// 	// TODO implement me
-// 	panic("implement me")
-// }
-
-func (svc *User) CreateUser(ctx context.Context, query *pb.CreateUserRequest, rsp *pb.CreateUserResponse) error {
-	if err := svc.Service.CreateUser(query); err != nil {
-		return err
-	}
-	return nil
-}
-
-func (svc *User) UpdateUserRoles(ctx context.Context, query *pb.UpdateUserRolesRequest, rsp *pb.UpdateUserRolesResponse) error {
-	if err := svc.Service.UpdateUserRoles(query); err != nil {
-		return err
+func (svc *User) GetUserList(ctx context.Context, query *pb.GetUserListRequest, rsp *pb.GetUserListResponse) error {
+	list, i, err := svc.Service.GetUserList(query)
+	if err != nil {
+		return nil
+	} else {
+		rsp.TotalCount = i
+		rsp.Items = list
 	}
 	return nil
 }
 
 func (svc *User) GetUser(ctx context.Context, query *pb.GetUserRequest, rsp *pb.GetUserResponse) error {
-	getUser, err := svc.Service.GetUser(query)
-	if err != nil {
+	if user, err := svc.Service.GetUser(query); err != nil {
 		return err
+	} else {
+		rsp.Data = user
 	}
-	rsp.Data = getUser
 	return nil
 }
 
-func (svc *User) GetUserList(ctx context.Context, query *pb.GetUserListRequest, rsp *pb.GetUserListResponse) error {
-	list, count, err := svc.Service.GetUserList(query)
-	if err != nil {
-		return nil
+func (svc *User) CreateUser(ctx context.Context, data *pb.CreateUserRequest, rsp *pb.CreateUserResponse) error {
+	if err := svc.Service.CreateUser(ctx, data); err != nil {
+		return err
 	}
-	rsp.Items = list
-	rsp.TotalCount = count
 	return nil
 }
 
-func (svc *User) DeleteUser(ctx context.Context, query *pb.DeleteUserRequest, rsp *pb.DeleteUserResponse) error {
-	if err := svc.Service.DeleteUser(query); err != nil {
+func (svc *User) UpdateUser(ctx context.Context, data *pb.UpdateUserRequest, rsp *pb.UpdateUserResponse) error {
+	if err := svc.Service.UpdateUser(ctx, data); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (svc *User) ToggleUser(ctx context.Context, query *pb.ToggleUserRequest, rsp *pb.ToggleUserResponse) error {
-	if err := svc.Service.ToggleUser(query); err != nil {
+func (svc *User) DeleteUser(ctx context.Context, data *pb.DeleteUserRequest, rsp *pb.DeleteUserResponse) error {
+	if err := svc.Service.DeleteUser(data); err != nil {
 		return err
 	}
 	return nil
 }
 
-func (svc *User) UpdateUserPassword(ctx context.Context, query *pb.UpdateUserPasswordRequest, rsp *pb.UpdateUserPasswordResponse) error {
-	if err := svc.Service.UpdateUserPassword(query); err != nil {
+func (svc *User) ToggleUser(ctx context.Context, data *pb.ToggleUserRequest, rsp *pb.ToggleUserResponse) error {
+	if err := svc.Service.ToggleUser(ctx, data); err != nil {
 		return err
 	}
 	return nil

+ 2 - 0
main.go

@@ -32,6 +32,7 @@ import (
 	"sghgogs.com/micro/shopping-service/handler/permission"
 	"sghgogs.com/micro/shopping-service/handler/product"
 	"sghgogs.com/micro/shopping-service/handler/role"
+	"sghgogs.com/micro/shopping-service/handler/user"
 	pb "sghgogs.com/micro/shopping-service/proto"
 	"sghgogs.com/micro/shopping-service/utils/authutil"
 	"sghgogs.com/micro/shopping-service/utils/middleware"
@@ -136,6 +137,7 @@ func main() {
 	pb.RegisterShoppingAdminUserServiceHandler(srv.Server(), &admin_user.AdminUser{Service: newService})
 	pb.RegisterShoppingRoleServiceHandler(srv.Server(), &role.Role{Service: newService})
 	pb.RegisterShoppingPermissionServiceHandler(srv.Server(), &permission.Permission{Service: newService})
+	pb.RegisterShoppingUserServiceHandler(srv.Server(), &user.User{Service: newService})
 
 	pb.RegisterShoppingAuthServiceHandler(srv.Server(), &handler_auth.Auth{Service: newService})
 	pb.RegisterShoppingAddressServiceHandler(srv.Server(), &address.Address{Service: newService})

+ 181 - 151
proto/base_shopping_service.pb.go

@@ -1275,15 +1275,17 @@ type User struct {
 	Email        string        `protobuf:"bytes,5,opt,name=email,proto3" json:"email,omitempty"`
 	Avatar       string        `protobuf:"bytes,6,opt,name=avatar,proto3" json:"avatar,omitempty"`
 	CreatedAt    int64         `protobuf:"varint,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
-	UpdatedAt    int64         `protobuf:"varint,8,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
-	Addresses    []*Address    `protobuf:"bytes,9,rep,name=addresses,proto3" json:"addresses,omitempty"`
-	ShoppingCart *ShoppingCart `protobuf:"bytes,10,opt,name=shopping_cart,json=shoppingCart,proto3" json:"shopping_cart,omitempty"`
-	Orders       []*Order      `protobuf:"bytes,11,rep,name=orders,proto3" json:"orders,omitempty"`
-	UserAuth     []*UserAuth   `protobuf:"bytes,12,rep,name=user_auth,json=userAuth,proto3" json:"user_auth,omitempty"`
-	Status       StatusEnum    `protobuf:"varint,13,opt,name=status,proto3,enum=base_shopping_service.StatusEnum" json:"status,omitempty"`
-	Roles        []*Base       `protobuf:"bytes,14,rep,name=roles,proto3" json:"roles,omitempty"`
-	GroupId      int64         `protobuf:"varint,15,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
-	Group        *UserGroup    `protobuf:"bytes,16,opt,name=group,proto3" json:"group,omitempty"`
+	CreatedBy    string        `protobuf:"bytes,8,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
+	UpdatedAt    int64         `protobuf:"varint,9,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
+	UpdatedBy    string        `protobuf:"bytes,10,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"`
+	Addresses    []*Address    `protobuf:"bytes,11,rep,name=addresses,proto3" json:"addresses,omitempty"`
+	ShoppingCart *ShoppingCart `protobuf:"bytes,12,opt,name=shopping_cart,json=shoppingCart,proto3" json:"shopping_cart,omitempty"`
+	Orders       []*Order      `protobuf:"bytes,13,rep,name=orders,proto3" json:"orders,omitempty"`
+	UserAuth     []*UserAuth   `protobuf:"bytes,14,rep,name=user_auth,json=userAuth,proto3" json:"user_auth,omitempty"`
+	Status       StatusEnum    `protobuf:"varint,15,opt,name=status,proto3,enum=base_shopping_service.StatusEnum" json:"status,omitempty"`
+	Roles        []*Base       `protobuf:"bytes,16,rep,name=roles,proto3" json:"roles,omitempty"`
+	GroupId      int64         `protobuf:"varint,17,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"`
+	Group        *UserGroup    `protobuf:"bytes,18,opt,name=group,proto3" json:"group,omitempty"`
 }
 
 func (x *User) Reset() {
@@ -1367,6 +1369,13 @@ func (x *User) GetCreatedAt() int64 {
 	return 0
 }
 
+func (x *User) GetCreatedBy() string {
+	if x != nil {
+		return x.CreatedBy
+	}
+	return ""
+}
+
 func (x *User) GetUpdatedAt() int64 {
 	if x != nil {
 		return x.UpdatedAt
@@ -1374,6 +1383,13 @@ func (x *User) GetUpdatedAt() int64 {
 	return 0
 }
 
+func (x *User) GetUpdatedBy() string {
+	if x != nil {
+		return x.UpdatedBy
+	}
+	return ""
+}
+
 func (x *User) GetAddresses() []*Address {
 	if x != nil {
 		return x.Addresses
@@ -1727,9 +1743,10 @@ type Permission struct {
 	CreatedAt   int64      `protobuf:"varint,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
 	CreatedBy   string     `protobuf:"bytes,6,opt,name=created_by,json=createdBy,proto3" json:"created_by,omitempty"`
 	UpdatedAt   int64      `protobuf:"varint,7,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"`
-	Status      StatusEnum `protobuf:"varint,8,opt,name=status,proto3,enum=base_shopping_service.StatusEnum" json:"status,omitempty"`
-	IsReserved  bool       `protobuf:"varint,9,opt,name=is_reserved,json=isReserved,proto3" json:"is_reserved,omitempty"`
-	Endpoint    string     `protobuf:"bytes,10,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
+	UpdatedBy   string     `protobuf:"bytes,8,opt,name=updated_by,json=updatedBy,proto3" json:"updated_by,omitempty"`
+	Status      StatusEnum `protobuf:"varint,9,opt,name=status,proto3,enum=base_shopping_service.StatusEnum" json:"status,omitempty"`
+	IsReserved  bool       `protobuf:"varint,10,opt,name=is_reserved,json=isReserved,proto3" json:"is_reserved,omitempty"`
+	Endpoint    string     `protobuf:"bytes,11,opt,name=endpoint,proto3" json:"endpoint,omitempty"`
 }
 
 func (x *Permission) Reset() {
@@ -1813,6 +1830,13 @@ func (x *Permission) GetUpdatedAt() int64 {
 	return 0
 }
 
+func (x *Permission) GetUpdatedBy() string {
+	if x != nil {
+		return x.UpdatedBy
+	}
+	return ""
+}
+
 func (x *Permission) GetStatus() StatusEnum {
 	if x != nil {
 		return x.Status
@@ -2006,7 +2030,7 @@ var file_proto_base_shopping_service_proto_rawDesc = []byte{
 	0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x75, 0x6e,
 	0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74,
 	0x69, 0x61, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65,
-	0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0x9a, 0x05, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e,
+	0x6e, 0x74, 0x69, 0x61, 0x6c, 0x22, 0xd8, 0x05, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x0e,
 	0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1a,
 	0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
 	0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
@@ -2018,151 +2042,157 @@ var file_proto_base_shopping_service_proto_rawDesc = []byte{
 	0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52,
 	0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74,
 	0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
-	0x65, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f,
+	0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
+	0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
+	0x62, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x64, 0x42, 0x79, 0x12, 0x3c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
+	0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68,
+	0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x41,
+	0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65,
+	0x73, 0x12, 0x48, 0x0a, 0x0d, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x63, 0x61,
+	0x72, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f,
 	0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
-	0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
-	0x73, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x0d, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f,
-	0x63, 0x61, 0x72, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x62, 0x61, 0x73,
-	0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69,
-	0x63, 0x65, 0x2e, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x72, 0x74, 0x52,
-	0x0c, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x72, 0x74, 0x12, 0x34, 0x0a,
-	0x06, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e,
-	0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x06, 0x6f, 0x72, 0x64,
-	0x65, 0x72, 0x73, 0x12, 0x3c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x68,
-	0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68,
-	0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55,
-	0x73, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x41, 0x75, 0x74,
-	0x68, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28,
-	0x0e, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e,
-	0x67, 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, 0x31, 0x0a, 0x05,
-	0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x0e, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61,
+	0x2e, 0x53, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x72, 0x74, 0x52, 0x0c, 0x73,
+	0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x43, 0x61, 0x72, 0x74, 0x12, 0x34, 0x0a, 0x06, 0x6f,
+	0x72, 0x64, 0x65, 0x72, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x62, 0x61,
 	0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12,
-	0x19, 0x0a, 0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28,
-	0x03, 0x52, 0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72,
-	0x6f, 0x75, 0x70, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65,
+	0x69, 0x63, 0x65, 0x2e, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x52, 0x06, 0x6f, 0x72, 0x64, 0x65, 0x72,
+	0x73, 0x12, 0x3c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x18, 0x0e,
+	0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70,
+	0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x55, 0x73, 0x65,
+	0x72, 0x41, 0x75, 0x74, 0x68, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x41, 0x75, 0x74, 0x68, 0x12,
+	0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0e, 0x32,
+	0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 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, 0x31, 0x0a, 0x05, 0x72, 0x6f,
+	0x6c, 0x65, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65,
 	0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
-	0x65, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f,
-	0x75, 0x70, 0x22, 0xe1, 0x01, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70,
-	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, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 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, 0x63, 0x72, 0x65,
-	0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61,
-	0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70,
-	0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64,
-	0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x22, 0x2e, 0x0a, 0x04, 0x42, 0x61, 0x73, 0x65, 0x12, 0x10,
-	0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79,
-	0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x96, 0x03, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 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, 0x31, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x04,
-	0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70,
-	0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73,
-	0x65, 0x52, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d,
-	0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e,
-	0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65,
-	0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d,
-	0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74,
-	0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 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, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f,
-	0x62, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x64, 0x42, 0x79, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20,
-	0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70,
-	0x69, 0x6e, 0x67, 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, 0x1f,
-	0x0a, 0x0b, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20,
-	0x01, 0x28, 0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x22,
-	0xda, 0x02, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e,
+	0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x19, 0x0a,
+	0x08, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x07, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75,
+	0x70, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73,
+	0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e,
+	0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70,
+	0x22, 0xe1, 0x01, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x47, 0x72, 0x6f, 0x75, 0x70, 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, 0x31, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20,
-	0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70,
-	0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65,
-	0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 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, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
-	0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
-	0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
-	0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x08,
-	0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70,
-	0x70, 0x69, 0x6e, 0x67, 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,
-	0x1f, 0x0a, 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, 0x2a,
-	0xaa, 0x02, 0x0a, 0x0f, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45,
-	0x6e, 0x75, 0x6d, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b,
-	0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f,
-	0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x4f, 0x52, 0x44,
-	0x45, 0x52, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45,
-	0x4e, 0x54, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x50, 0x41,
-	0x49, 0x44, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x50, 0x52,
-	0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52,
-	0x44, 0x45, 0x52, 0x5f, 0x53, 0x48, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x05, 0x12, 0x13, 0x0a,
-	0x0f, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44,
-	0x10, 0x06, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43,
-	0x45, 0x4c, 0x45, 0x44, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f,
-	0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45,
-	0x53, 0x53, 0x10, 0x08, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x45,
-	0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x09, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x52, 0x44, 0x45,
-	0x52, 0x5f, 0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47,
-	0x52, 0x45, 0x53, 0x53, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f,
-	0x52, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x45, 0x44, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e,
-	0x44, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x10, 0x0c, 0x2a, 0xff, 0x01, 0x0a,
-	0x11, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e,
-	0x75, 0x6d, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e,
-	0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x59, 0x4d, 0x45,
-	0x4e, 0x54, 0x5f, 0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12,
-	0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49,
-	0x4e, 0x47, 0x10, 0x02, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f,
-	0x50, 0x41, 0x49, 0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e,
-	0x54, 0x5f, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41,
-	0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x05,
-	0x12, 0x15, 0x0a, 0x11, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x55,
-	0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45,
-	0x4e, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x07, 0x12, 0x1f, 0x0a,
-	0x1b, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c,
-	0x4c, 0x59, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x1e,
-	0x0a, 0x1a, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41,
-	0x4c, 0x4c, 0x59, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x09, 0x2a, 0x86,
-	0x01, 0x0a, 0x11, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64,
-	0x45, 0x6e, 0x75, 0x6d, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f,
-	0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00,
-	0x12, 0x1b, 0x0a, 0x17, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x48,
-	0x4f, 0x44, 0x5f, 0x42, 0x41, 0x4e, 0x4b, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x19, 0x0a,
-	0x15, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f,
-	0x41, 0x4c, 0x49, 0x50, 0x41, 0x59, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x41, 0x59, 0x4d,
-	0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x57, 0x45, 0x43, 0x48, 0x41,
-	0x54, 0x5f, 0x50, 0x41, 0x59, 0x10, 0x04, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x3b, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76,
-	0x69, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 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, 0x63, 0x72, 0x65, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
+	0x64, 0x5f, 0x61, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x62, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74,
+	0x65, 0x64, 0x42, 0x79, 0x22, 0x2e, 0x0a, 0x04, 0x42, 0x61, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03,
+	0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14,
+	0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x22, 0x96, 0x03, 0x0a, 0x04, 0x52, 0x6f, 0x6c, 0x65, 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, 0x31, 0x0a, 0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69,
+	0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52,
+	0x05, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x3d, 0x0a, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
+	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61,
+	0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73,
+	0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
+	0x5f, 0x62, 0x79, 0x18, 0x06, 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, 0x07, 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, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+	0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
+	0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42,
+	0x79, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e,
+	0x67, 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, 0x1f, 0x0a, 0x0b,
+	0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28,
+	0x08, 0x52, 0x0a, 0x69, 0x73, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x22, 0xf9, 0x02,
+	0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 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, 0x31, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
+	0x0b, 0x32, 0x1b, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e,
+	0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x42, 0x61, 0x73, 0x65, 0x52, 0x05,
+	0x72, 0x6f, 0x6c, 0x65, 0x73, 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, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,
+	0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
+	0x64, 0x42, 0x79, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61,
+	0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64,
+	0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x62, 0x79,
+	0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x42,
+	0x79, 0x12, 0x39, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28,
+	0x0e, 0x32, 0x21, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e,
+	0x67, 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, 0x1f, 0x0a, 0x0b,
+	0x69, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x64, 0x18, 0x0a, 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, 0x0b, 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, 0x2a, 0xaa, 0x02, 0x0a,
+	0x0f, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d,
+	0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
+	0x4e, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x52, 0x45,
+	0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f,
+	0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x10,
+	0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x50, 0x41, 0x49, 0x44, 0x10,
+	0x03, 0x12, 0x14, 0x0a, 0x10, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45,
+	0x53, 0x53, 0x49, 0x4e, 0x47, 0x10, 0x04, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x52, 0x44, 0x45, 0x52,
+	0x5f, 0x53, 0x48, 0x49, 0x50, 0x50, 0x45, 0x44, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x4f, 0x52,
+	0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x06, 0x12,
+	0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45,
+	0x44, 0x10, 0x07, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x46,
+	0x55, 0x4e, 0x44, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53, 0x53, 0x10,
+	0x08, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e,
+	0x44, 0x45, 0x44, 0x10, 0x09, 0x12, 0x1c, 0x0a, 0x18, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x52,
+	0x45, 0x54, 0x55, 0x52, 0x4e, 0x5f, 0x49, 0x4e, 0x5f, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x45, 0x53,
+	0x53, 0x10, 0x0a, 0x12, 0x12, 0x0a, 0x0e, 0x4f, 0x52, 0x44, 0x45, 0x52, 0x5f, 0x52, 0x45, 0x54,
+	0x55, 0x52, 0x4e, 0x45, 0x44, 0x10, 0x0b, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x44, 0x45, 0x52,
+	0x5f, 0x52, 0x45, 0x56, 0x49, 0x45, 0x57, 0x10, 0x0c, 0x2a, 0xff, 0x01, 0x0a, 0x11, 0x50, 0x61,
+	0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x45, 0x6e, 0x75, 0x6d, 0x12,
+	0x13, 0x0a, 0x0f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f,
+	0x57, 0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f,
+	0x50, 0x45, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x50, 0x41, 0x59,
+	0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x43, 0x45, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x10,
+	0x02, 0x12, 0x10, 0x0a, 0x0c, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x41, 0x49,
+	0x44, 0x10, 0x03, 0x12, 0x12, 0x0a, 0x0e, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x46,
+	0x41, 0x49, 0x4c, 0x45, 0x44, 0x10, 0x04, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45,
+	0x4e, 0x54, 0x5f, 0x43, 0x41, 0x4e, 0x43, 0x45, 0x4c, 0x45, 0x44, 0x10, 0x05, 0x12, 0x15, 0x0a,
+	0x11, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x49,
+	0x4e, 0x47, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f,
+	0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x07, 0x12, 0x1f, 0x0a, 0x1b, 0x50, 0x41,
+	0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x4c, 0x59, 0x5f,
+	0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x1e, 0x0a, 0x1a, 0x50,
+	0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x41, 0x52, 0x54, 0x49, 0x41, 0x4c, 0x4c, 0x59,
+	0x5f, 0x52, 0x45, 0x46, 0x55, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x09, 0x2a, 0x86, 0x01, 0x0a, 0x11,
+	0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x45, 0x6e, 0x75,
+	0x6d, 0x12, 0x1a, 0x0a, 0x16, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x4d, 0x65, 0x74,
+	0x68, 0x6f, 0x64, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x1b, 0x0a,
+	0x17, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f,
+	0x42, 0x41, 0x4e, 0x4b, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x19, 0x0a, 0x15, 0x50, 0x41,
+	0x59, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x41, 0x4c, 0x49,
+	0x50, 0x41, 0x59, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x50, 0x41, 0x59, 0x4d, 0x45, 0x4e, 0x54,
+	0x5f, 0x4d, 0x45, 0x54, 0x48, 0x4f, 0x44, 0x5f, 0x57, 0x45, 0x43, 0x48, 0x41, 0x54, 0x5f, 0x50,
+	0x41, 0x59, 0x10, 0x04, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b,
+	0x73, 0x68, 0x6f, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (

+ 11 - 9
proto/base_shopping_service.proto

@@ -158,15 +158,17 @@ message User {
   string email = 5;
   string avatar = 6;
   int64 created_at = 7;
-  int64 updated_at = 8;
-  repeated Address addresses = 9;
-  ShoppingCart shopping_cart = 10;
-  repeated Order orders = 11;
-  repeated UserAuth user_auth = 12;
-  StatusEnum status = 13;
-  repeated base_shopping_service.Base roles = 14;
-  int64 group_id = 15;
-  UserGroup group = 16;
+  string created_by = 8;
+  int64 updated_at = 9;
+  string updated_by = 10;
+  repeated Address addresses = 11;
+  ShoppingCart shopping_cart = 12;
+  repeated Order orders = 13;
+  repeated UserAuth user_auth = 14;
+  StatusEnum status = 15;
+  repeated base_shopping_service.Base roles = 16;
+  int64 group_id = 17;
+  UserGroup group = 18;
 }
 
 message UserGroup {

+ 1 - 1
proto/shopping_role_service.proto

@@ -8,8 +8,8 @@ import "proto/base_shopping_service.proto";
 
 service ShoppingRoleService {
   rpc GetRoleList(GetRoleListRequest) returns (GetRoleListResponse);
-  rpc GetRole(GetRoleRequest) returns (GetRoleResponse);
   rpc GetAllRoles(GetAllRolesRequest) returns(GetAllRolesResponse);
+  rpc GetRole(GetRoleRequest) returns (GetRoleResponse);
   rpc CreateRole(CreateRoleRequest) returns (CreateRoleResponse);
   rpc UpdateRole(UpdateRoleRequest) returns (UpdateRoleResponse);
   rpc DeleteRole(DeleteRoleRequest) returns (DeleteRoleResponse);

文件差异内容过多而无法显示
+ 186 - 500
proto/shopping_user_service.pb.go


+ 8 - 42
proto/shopping_user_service.pb.micro.go

@@ -37,11 +37,9 @@ func NewShoppingUserServiceEndpoints() []*api.Endpoint {
 
 type ShoppingUserService interface {
 	GetUserList(ctx context.Context, in *GetUserListRequest, opts ...client.CallOption) (*GetUserListResponse, error)
-	GetAllUser(ctx context.Context, in *GetAllUserRequest, opts ...client.CallOption) (*GetAllUserResponse, error)
 	GetUser(ctx context.Context, in *GetUserRequest, opts ...client.CallOption) (*GetUserResponse, error)
 	CreateUser(ctx context.Context, in *CreateUserRequest, opts ...client.CallOption) (*CreateUserResponse, error)
-	UpdateUserRoles(ctx context.Context, in *UpdateUserRolesRequest, opts ...client.CallOption) (*UpdateUserRolesResponse, error)
-	UpdateUserPassword(ctx context.Context, in *UpdateUserPasswordRequest, opts ...client.CallOption) (*UpdateUserPasswordResponse, error)
+	UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...client.CallOption) (*UpdateUserResponse, error)
 	DeleteUser(ctx context.Context, in *DeleteUserRequest, opts ...client.CallOption) (*DeleteUserResponse, error)
 	ToggleUser(ctx context.Context, in *ToggleUserRequest, opts ...client.CallOption) (*ToggleUserResponse, error)
 }
@@ -68,16 +66,6 @@ func (c *shoppingUserService) GetUserList(ctx context.Context, in *GetUserListRe
 	return out, nil
 }
 
-func (c *shoppingUserService) GetAllUser(ctx context.Context, in *GetAllUserRequest, opts ...client.CallOption) (*GetAllUserResponse, error) {
-	req := c.c.NewRequest(c.name, "ShoppingUserService.GetAllUser", in)
-	out := new(GetAllUserResponse)
-	err := c.c.Call(ctx, req, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
 func (c *shoppingUserService) GetUser(ctx context.Context, in *GetUserRequest, opts ...client.CallOption) (*GetUserResponse, error) {
 	req := c.c.NewRequest(c.name, "ShoppingUserService.GetUser", in)
 	out := new(GetUserResponse)
@@ -98,19 +86,9 @@ func (c *shoppingUserService) CreateUser(ctx context.Context, in *CreateUserRequ
 	return out, nil
 }
 
-func (c *shoppingUserService) UpdateUserRoles(ctx context.Context, in *UpdateUserRolesRequest, opts ...client.CallOption) (*UpdateUserRolesResponse, error) {
-	req := c.c.NewRequest(c.name, "ShoppingUserService.UpdateUserRoles", in)
-	out := new(UpdateUserRolesResponse)
-	err := c.c.Call(ctx, req, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-func (c *shoppingUserService) UpdateUserPassword(ctx context.Context, in *UpdateUserPasswordRequest, opts ...client.CallOption) (*UpdateUserPasswordResponse, error) {
-	req := c.c.NewRequest(c.name, "ShoppingUserService.UpdateUserPassword", in)
-	out := new(UpdateUserPasswordResponse)
+func (c *shoppingUserService) UpdateUser(ctx context.Context, in *UpdateUserRequest, opts ...client.CallOption) (*UpdateUserResponse, error) {
+	req := c.c.NewRequest(c.name, "ShoppingUserService.UpdateUser", in)
+	out := new(UpdateUserResponse)
 	err := c.c.Call(ctx, req, out, opts...)
 	if err != nil {
 		return nil, err
@@ -142,11 +120,9 @@ func (c *shoppingUserService) ToggleUser(ctx context.Context, in *ToggleUserRequ
 
 type ShoppingUserServiceHandler interface {
 	GetUserList(context.Context, *GetUserListRequest, *GetUserListResponse) error
-	GetAllUser(context.Context, *GetAllUserRequest, *GetAllUserResponse) error
 	GetUser(context.Context, *GetUserRequest, *GetUserResponse) error
 	CreateUser(context.Context, *CreateUserRequest, *CreateUserResponse) error
-	UpdateUserRoles(context.Context, *UpdateUserRolesRequest, *UpdateUserRolesResponse) error
-	UpdateUserPassword(context.Context, *UpdateUserPasswordRequest, *UpdateUserPasswordResponse) error
+	UpdateUser(context.Context, *UpdateUserRequest, *UpdateUserResponse) error
 	DeleteUser(context.Context, *DeleteUserRequest, *DeleteUserResponse) error
 	ToggleUser(context.Context, *ToggleUserRequest, *ToggleUserResponse) error
 }
@@ -154,11 +130,9 @@ type ShoppingUserServiceHandler interface {
 func RegisterShoppingUserServiceHandler(s server.Server, hdlr ShoppingUserServiceHandler, opts ...server.HandlerOption) error {
 	type shoppingUserService interface {
 		GetUserList(ctx context.Context, in *GetUserListRequest, out *GetUserListResponse) error
-		GetAllUser(ctx context.Context, in *GetAllUserRequest, out *GetAllUserResponse) error
 		GetUser(ctx context.Context, in *GetUserRequest, out *GetUserResponse) error
 		CreateUser(ctx context.Context, in *CreateUserRequest, out *CreateUserResponse) error
-		UpdateUserRoles(ctx context.Context, in *UpdateUserRolesRequest, out *UpdateUserRolesResponse) error
-		UpdateUserPassword(ctx context.Context, in *UpdateUserPasswordRequest, out *UpdateUserPasswordResponse) error
+		UpdateUser(ctx context.Context, in *UpdateUserRequest, out *UpdateUserResponse) error
 		DeleteUser(ctx context.Context, in *DeleteUserRequest, out *DeleteUserResponse) error
 		ToggleUser(ctx context.Context, in *ToggleUserRequest, out *ToggleUserResponse) error
 	}
@@ -177,10 +151,6 @@ func (h *shoppingUserServiceHandler) GetUserList(ctx context.Context, in *GetUse
 	return h.ShoppingUserServiceHandler.GetUserList(ctx, in, out)
 }
 
-func (h *shoppingUserServiceHandler) GetAllUser(ctx context.Context, in *GetAllUserRequest, out *GetAllUserResponse) error {
-	return h.ShoppingUserServiceHandler.GetAllUser(ctx, in, out)
-}
-
 func (h *shoppingUserServiceHandler) GetUser(ctx context.Context, in *GetUserRequest, out *GetUserResponse) error {
 	return h.ShoppingUserServiceHandler.GetUser(ctx, in, out)
 }
@@ -189,12 +159,8 @@ func (h *shoppingUserServiceHandler) CreateUser(ctx context.Context, in *CreateU
 	return h.ShoppingUserServiceHandler.CreateUser(ctx, in, out)
 }
 
-func (h *shoppingUserServiceHandler) UpdateUserRoles(ctx context.Context, in *UpdateUserRolesRequest, out *UpdateUserRolesResponse) error {
-	return h.ShoppingUserServiceHandler.UpdateUserRoles(ctx, in, out)
-}
-
-func (h *shoppingUserServiceHandler) UpdateUserPassword(ctx context.Context, in *UpdateUserPasswordRequest, out *UpdateUserPasswordResponse) error {
-	return h.ShoppingUserServiceHandler.UpdateUserPassword(ctx, in, out)
+func (h *shoppingUserServiceHandler) UpdateUser(ctx context.Context, in *UpdateUserRequest, out *UpdateUserResponse) error {
+	return h.ShoppingUserServiceHandler.UpdateUser(ctx, in, out)
 }
 
 func (h *shoppingUserServiceHandler) DeleteUser(ctx context.Context, in *DeleteUserRequest, out *DeleteUserResponse) error {

+ 7 - 25
proto/shopping_user_service.proto

@@ -8,11 +8,9 @@ import "proto/base_shopping_service.proto";
 
 service ShoppingUserService {
   rpc GetUserList(GetUserListRequest) returns(GetUserListResponse);
-  rpc GetAllUser(GetAllUserRequest) returns (GetAllUserResponse);
   rpc GetUser(GetUserRequest) returns(GetUserResponse);
   rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);
-  rpc UpdateUserRoles(UpdateUserRolesRequest) returns(UpdateUserRolesResponse);
-  rpc UpdateUserPassword(UpdateUserPasswordRequest) returns(UpdateUserPasswordResponse);
+  rpc UpdateUser(UpdateUserRequest) returns(UpdateUserResponse);
   rpc DeleteUser(DeleteUserRequest) returns(DeleteUserResponse);
   rpc ToggleUser(ToggleUserRequest) returns(ToggleUserResponse);
 }
@@ -21,7 +19,6 @@ message GetUserListRequest{
   int32 page_size = 2;
   string keyword = 3;
   base_shopping_service.StatusEnum status = 4;
-  string code = 5;
 }
 message GetUserListResponse{
   repeated base_shopping_service.User items = 1;
@@ -35,39 +32,25 @@ message GetUserResponse {
   base_shopping_service.User data = 1;
 }
 
-message GetAllUserRequest{}
-message GetAllUserResponse{
-  repeated base_shopping_service.Base items = 1;
-}
-
 message CreateUserRequest{
   string username = 1;
   string password = 2;
   string phone_number = 3;
   string email = 4;
   string avatar = 5;
-  repeated int64 roles = 6;
-  string code = 7;
-  int64 group_id = 8;
+  string code = 6;
 }
 message CreateUserResponse{}
 
 
-message UpdateUserRolesRequest{
+message UpdateUserRequest{
   int64 user_id = 1;
-  repeated int64 roles = 2;
-  int64 group_id = 3;
+  string phone_number = 2;
+  string email = 3;
+  string avatar = 4;
 }
-message UpdateUserRolesResponse{}
+message UpdateUserResponse{}
 
-// 修改密码
-message UpdateUserPasswordRequest{
-  int64 user_id = 1;
-  string old_password = 2;
-  string new_password = 3;
-  int64 group_id = 4;
-}
-message UpdateUserPasswordResponse{}
 
 message DeleteUserRequest{
   int64 user_id = 1;
@@ -77,6 +60,5 @@ message DeleteUserResponse{}
 message ToggleUserRequest {
   int64 user_id = 1;
   base_shopping_service.StatusEnum status = 2;
-  int64 group_id = 3;
 }
 message ToggleUserResponse{}

+ 4 - 40
test/permission/permission_test.go

@@ -52,55 +52,19 @@ func TestRole(t *testing.T) {
 		items := []*pb.Permission{
 			{
 				Name:        "shoppingservice_wanke",
-				Description: "管理员列表",
-				Endpoint:    "ShoppingAdminUserService.GetAdminUserList",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "所有管理员",
-				Endpoint:    "ShoppingAdminUserService.GetAllAdminUser",
+				Description: "退出",
+				Endpoint:    "ShoppingAuthService.Logout",
 				Status:      pb.StatusEnum_ENABLED,
 			},
 			{
 				Name:        "shoppingservice_wanke",
 				Description: "详情",
-				Endpoint:    "ShoppingAdminUserService.GetAdminUser",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "创建管理员",
-				Endpoint:    "ShoppingAdminUserService.CreateAdminUser",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "更新",
-				Endpoint:    "ShoppingAdminUserService.UpdateAdminUser",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "管理员列表",
-				Endpoint:    "ShoppingAdminUserService.GetAdminUserList",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "删除管理员",
-				Endpoint:    "ShoppingAdminUserService.DeleteAdminUser",
-				Status:      pb.StatusEnum_ENABLED,
-			},
-			{
-				Name:        "shoppingservice_wanke",
-				Description: "更新状态",
-				Endpoint:    "ShoppingAdminUserService.ToggleAdminUser",
+				Endpoint:    "ShoppingAuthService.Profile",
 				Status:      pb.StatusEnum_ENABLED,
 			},
 		}
 		newService.CreateMultiplePermissions(context.Background(), &pb.CreateMultiplePermissionsRequest{
-			Roles: []int64{1, 2},
+			Roles: []int64{1, 2, 3},
 			Items: items,
 		})
 	})

+ 45 - 22
test/user/user_test.go

@@ -6,6 +6,7 @@ import (
 	"gorm.io/gorm"
 	"gorm.io/gorm/logger"
 	"gorm.io/gorm/schema"
+	req "sghgogs.com/micro/shopping-service/domain/model/request"
 	"sghgogs.com/micro/shopping-service/domain/repository"
 	"sghgogs.com/micro/shopping-service/domain/service"
 	pb "sghgogs.com/micro/shopping-service/proto"
@@ -30,33 +31,38 @@ func TestUser(t *testing.T) {
 	})
 	service := service.NewService(repo, "shopping_wenke")
 	t.Run("创建账号", func(t *testing.T) {
-		user := &pb.CreateUserRequest{
-			Username:    "admin",
-			Password:    "123456",
-			PhoneNumber: "13900000000",
-			Email:       "john@example.com",
-			Avatar:      "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
-		}
-		err = service.CreateUser(user)
-		fmt.Println("err", err)
+		// user := &pb.CreateUserRequest{
+		// 	Username:    "admin",
+		// 	Password:    "123456",
+		// 	PhoneNumber: "13900000000",
+		// 	Email:       "john@example.com",
+		// 	Avatar:      "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif",
+		// }
+		// err = service.CreateUser(user)
+		// fmt.Println("err", err)
 	})
 	t.Run("删除", func(t *testing.T) {
-		service.DeleteUser(&pb.DeleteUserRequest{UserId: 7})
+		// service.DeleteUser(&pb.DeleteUserRequest{UserId: 7})
 	})
 	t.Run("更新", func(t *testing.T) {
 	})
 	t.Run("查询User数据", func(t *testing.T) {
-		group, err2 := service.GetUserGroup(&pb.GetUserGroupRequest{GroupId: 2})
-		fmt.Println(group)
-		fmt.Println(err2)
+		// group, err2 := service.GetUserGroup(&pb.GetUserGroupRequest{GroupId: 2})
+		// fmt.Println(group)
+		// fmt.Println(err2)
+		var user []req.User
+		db.Model(&req.User{}).
+			Where("group_id = ?", 2).
+			Order("id desc").Find(&user)
+		fmt.Println(user)
 	})
 	t.Run("删除", func(t *testing.T) {
 	})
 	t.Run("查询详情", func(t *testing.T) {
-		user, err2 := service.GetUser(&pb.GetUserRequest{UserId: 5})
+		user, err2 := service.GetUser(&pb.GetUserRequest{UserId: 1})
 		fmt.Println(user)
-		// db.Preload("ShoppingCart").Where("id = ? AND status = ?", 1, pb.StatusEnum_ENABLED).First(&user)
-		// fmt.Println("user", user.ShoppingCart)
+		// // db.Preload("ShoppingCart").Where("id = ? AND status = ?", 1, pb.StatusEnum_ENABLED).First(&user)
+		// // fmt.Println("user", user.ShoppingCart)
 		fmt.Println(err2)
 	})
 	t.Run("修改手机号", func(t *testing.T) {
@@ -67,10 +73,10 @@ func TestUser(t *testing.T) {
 		// fmt.Println(err2)
 	})
 	t.Run("设置状态", func(t *testing.T) {
-		service.ToggleUser(&pb.ToggleUserRequest{
-			UserId: 1,
-			Status: pb.StatusEnum_ENABLED,
-		})
+		// service.ToggleUser(&pb.ToggleUserRequest{
+		// 	UserId: 1,
+		// 	Status: pb.StatusEnum_ENABLED,
+		// })
 	})
 	t.Run("测试时间", func(t *testing.T) {
 		date := time.Now().AddDate(0, 0, 1)
@@ -78,8 +84,12 @@ func TestUser(t *testing.T) {
 		fmt.Println(time.Now().Before(date))
 	})
 	t.Run("查询", func(t *testing.T) {
-		user, err2 := service.GetAllAdminUser()
-		fmt.Println(user)
+		list, i, err2 := service.GetUserList(&pb.GetUserListRequest{
+			Page:     1,
+			PageSize: 10,
+		})
+		fmt.Println(list)
+		fmt.Println(i)
 		fmt.Println(err2)
 	})
 	t.Run("创建分组", func(t *testing.T) {
@@ -90,5 +100,18 @@ func TestUser(t *testing.T) {
 		})
 		fmt.Println(err2)
 	})
+	t.Run("测试", func(t *testing.T) {
+		// group, err2 := service.GetUserGroup(&pb.GetUserGroupRequest{Code: "17a78673-9762-4e9e-8f87-595a049f75bf"})
+		// fmt.Println(group.Id)
+		// fmt.Println(err2)
+		login, i, err2 := service.Login(&pb.LoginRequest{
+			Username: "admin",
+			Password: "123456",
+			Code:     "17a78673-9762-4e9e-8f87-595a049f75bf",
+		})
+		fmt.Println(login)
+		fmt.Println(i)
+		fmt.Println(err2)
+	})
 	// service.NewService(repo)
 }

+ 15 - 0
utils/utils.go

@@ -12,6 +12,21 @@ import (
 	"time"
 )
 
+var (
+	AdminUserGroupID int64 = 1
+	UserUserGroupID  int64 = 2
+	UserGroup              = []int64{1, 2}
+)
+
+func IsUserGroup(ID int64) bool {
+	for _, value := range UserGroup {
+		if value == ID {
+			return true
+		}
+	}
+	return false
+}
+
 func ConvertTimeToInt64(t time.Time) int64 {
 	return t.Unix()
 }

部分文件因为文件数量过多而无法显示