소스 검색

权限管理调整

huwei 3 주 전
부모
커밋
659e3e366f

+ 1 - 0
.gitignore

@@ -1 +1,2 @@
 /.idea
+/.vscode

+ 32 - 22
server/config/database.go

@@ -1,11 +1,11 @@
 package config
 
 import (
+	"fmt"
 	"log"
 	"os"
 	"time"
 
-	mysql2 "github.com/go-sql-driver/mysql"
 	"github.com/sirupsen/logrus"
 	"gorm.io/driver/mysql"
 	"gorm.io/gorm"
@@ -13,19 +13,44 @@ import (
 )
 
 var (
-	DB       *gorm.DB
-	LDB      *gorm.DB
-	GDB1     *gorm.DB
-	GDBGroup map[int]*gorm.DB
-	AdminDB  *gorm.DB
+	AdminDB    *gorm.DB
+	LogDBGroup map[int32]*gorm.DB
 )
 
 func InitDatabase() {
 	initAdminDB()
+	initLogDBGroup()
 }
 
 func initAdminDB() {
 	connString := os.Getenv("ADMIN_MYSQL_DSN")
+	AdminDB = connDB(connString)
+}
+
+func initLogDBGroup() {
+	LogDBGroup = make(map[int32]*gorm.DB)
+
+	// 游戏服数据库组,新加服务器时往后续就行
+	// 当连续3各数据库都不存在时,停止遍历
+
+	failNum := 0
+	for i := 1; i < 10000; i += 1 {
+		conn := os.Getenv(fmt.Sprintf("LOG%v_MYSQL_DSN", i))
+		if conn == "" {
+			failNum += 1
+			if failNum > 3 {
+				return
+			}
+			//logrus.Warnf("initSingleGraveDB empty index[%v] present, skipped..", index)
+			continue
+		}
+		failNum = 0
+		db := connDB(conn)
+		LogDBGroup[int32(i)] = db
+	}
+}
+
+func connDB(connString string) *gorm.DB {
 	newLogger := logger.New(
 		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
 		logger.Config{
@@ -52,20 +77,5 @@ func initAdminDB() {
 	sqlDB.SetMaxIdleConns(10)
 	sqlDB.SetMaxOpenConns(20)
 	sqlDB.SetConnMaxLifetime(2 * time.Hour)
-	AdminDB = db
-}
-
-// GetDBName 获取数据库库名
-func GetDBName(conn string) string {
-	dsnConf, _ := mysql2.ParseDSN(conn)
-	return dsnConf.DBName
-}
-
-func GetDBId(DB *gorm.DB) int {
-	for k, db := range GDBGroup {
-		if db == DB {
-			return k
-		}
-	}
-	return 0
+	return db
 }

+ 15 - 17
server/config/menu.go

@@ -1,9 +1,7 @@
 package config
 
 import (
-	"context"
 	"gadmin/internal/gorm/model"
-	"gadmin/internal/gorm/query"
 	"github.com/sirupsen/logrus"
 )
 
@@ -86,21 +84,21 @@ var menus = map[string]string{
 	"/api/announcement/del":                     "删除公告",
 }
 
-func GetMenuName(p string) string {
-	q := query.Use(AdminDB).AdminOperation
-	operation, err := q.WithContext(context.Background()).Where(q.API.Eq(p)).First()
-	if err != nil {
-		logrus.Error("GetMenuName", "err", err)
-		return ""
-	}
-	return operation.Name
-
-	//v, ok := menus[p]
-	//if ok {
-	//	return v
-	//}
-	//return ""
-}
+//func GetMenuName(p string) string {
+//	q := query.Use(AdminDB).AdminOperation
+//	operation, err := q.WithContext(context.Background()).Where(q.API.Eq(p)).First()
+//	if err != nil {
+//		logrus.Error("GetMenuName", "err", err)
+//		return ""
+//	}
+//	return operation.Name
+//
+//	//v, ok := menus[p]
+//	//if ok {
+//	//	return v
+//	//}
+//	//return ""
+//}
 
 func GetAllOptions() []*model.AdminOperation {
 	q := AdminDB.Model(&model.AdminOperation{})

+ 23 - 99
server/go.mod

@@ -1,40 +1,24 @@
 module gadmin
 
-go 1.22
-
-toolchain go1.22.6
+go 1.23.9
 
 require (
+	entrance-grpc v0.0.0-00010101000000-000000000000
 	github.com/dgrijalva/jwt-go v3.2.0+incompatible
-	github.com/docker/docker v23.0.1+incompatible
-	github.com/elastic/go-elasticsearch/v8 v8.7.1
 	github.com/gin-gonic/gin v1.7.1
 	github.com/go-redis/redis v6.15.9+incompatible
-	github.com/go-resty/resty/v2 v2.7.0
-	github.com/go-sql-driver/mysql v1.7.0
-	github.com/golang/protobuf v1.5.4
-	github.com/google/btree v1.1.2
-	github.com/google/uuid v1.3.1
-	github.com/gorilla/websocket v1.5.0
-	github.com/jinzhu/copier v0.3.5
+	github.com/google/uuid v1.6.0
 	github.com/jinzhu/now v1.1.5
 	github.com/joho/godotenv v1.3.0
+	github.com/json-iterator/go v1.1.12
 	github.com/larksuite/oapi-sdk-go/v3 v3.4.17
-	github.com/nacos-group/nacos-sdk-go/v2 v2.2.7
 	github.com/nahid/gohttp v0.0.1
-	github.com/nats-io/nats.go v1.37.0
 	github.com/patrickmn/go-cache v2.1.0+incompatible
-	github.com/robfig/cron/v3 v3.0.1
 	github.com/shopspring/decimal v1.3.1
 	github.com/sirupsen/logrus v1.9.0
 	github.com/spf13/cast v1.5.0
-	github.com/spf13/cobra v1.5.0
-	github.com/spf13/viper v1.12.0
-	github.com/tencentyun/cos-go-sdk-v5 v0.7.55
-	github.com/xujiajun/nutsdb v0.9.0
-	github.com/xuri/excelize/v2 v2.6.0
-	go.etcd.io/etcd/client/v3 v3.5.17
-	golang.org/x/crypto v0.28.0
+	golang.org/x/crypto v0.39.0
+	google.golang.org/grpc v1.73.0
 	gopkg.in/go-playground/validator.v8 v8.18.2
 	gopkg.in/natefinch/lumberjack.v2 v2.2.1
 	gopkg.in/yaml.v2 v2.4.0
@@ -46,103 +30,43 @@ require (
 )
 
 require (
-	github.com/Microsoft/go-winio v0.6.0 // indirect
-	github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
-	github.com/alibabacloud-go/tea v1.1.17 // indirect
-	github.com/alibabacloud-go/tea-utils v1.4.4 // indirect
-	github.com/aliyun/alibaba-cloud-sdk-go v1.61.1800 // indirect
-	github.com/aliyun/alibabacloud-dkms-gcs-go-sdk v0.2.2 // indirect
-	github.com/aliyun/alibabacloud-dkms-transfer-go-sdk v0.1.7 // indirect
-	github.com/beorn7/perks v1.0.1 // indirect
-	github.com/buger/jsonparser v1.1.1 // indirect
-	github.com/bwmarrin/snowflake v0.3.0 // indirect
-	github.com/cespare/xxhash/v2 v2.2.0 // indirect
-	github.com/clbanning/mxj v1.8.4 // indirect
-	github.com/coreos/go-semver v0.3.0 // indirect
-	github.com/coreos/go-systemd/v22 v22.3.2 // indirect
-	github.com/docker/distribution v2.8.1+incompatible // indirect
-	github.com/docker/go-connections v0.4.0 // indirect
-	github.com/docker/go-units v0.5.0 // indirect
-	github.com/elastic/elastic-transport-go/v8 v8.2.0 // indirect
 	github.com/fsnotify/fsnotify v1.5.4 // indirect
 	github.com/gin-contrib/sse v0.1.0 // indirect
 	github.com/go-playground/locales v0.13.0 // indirect
 	github.com/go-playground/universal-translator v0.17.0 // indirect
 	github.com/go-playground/validator/v10 v10.4.1 // indirect
-	github.com/goccy/go-json v0.8.1 // indirect
-	github.com/gogo/protobuf v1.3.2 // indirect
-	github.com/golang/mock v1.6.0 // indirect
-	github.com/golang/snappy v0.0.4 // indirect
-	github.com/google/go-querystring v1.0.0 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
-	github.com/inconshreveable/mousetrap v1.0.0 // indirect
+	github.com/go-sql-driver/mysql v1.7.0 // indirect
+	github.com/golang/protobuf v1.5.4 // indirect
+	github.com/jackc/pgx/v4 v4.18.0 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
-	github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
-	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/klauspost/compress v1.17.11 // indirect
 	github.com/leodido/go-urn v1.2.0 // indirect
-	github.com/magiconair/properties v1.8.6 // indirect
 	github.com/mattn/go-isatty v0.0.16 // indirect
-	github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
-	github.com/mitchellh/mapstructure v1.5.0 // indirect
-	github.com/moby/term v0.0.0-20221205130635-1aeaba878587 // indirect
+	github.com/mattn/go-sqlite3 v1.14.16 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
-	github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
-	github.com/morikuni/aec v1.0.0 // indirect
-	github.com/mozillazg/go-httpheader v0.2.1 // indirect
-	github.com/nats-io/nkeys v0.4.7 // indirect
-	github.com/nats-io/nuid v1.0.1 // indirect
 	github.com/onsi/ginkgo v1.16.2 // indirect
 	github.com/onsi/gomega v1.12.0 // indirect
-	github.com/opencontainers/go-digest v1.0.0 // indirect
-	github.com/opencontainers/image-spec v1.0.2 // indirect
-	github.com/pelletier/go-toml v1.9.5 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.1 // indirect
-	github.com/pkg/errors v0.9.1 // indirect
-	github.com/prometheus/client_golang v1.12.2 // indirect
-	github.com/prometheus/client_model v0.2.0 // indirect
-	github.com/prometheus/common v0.32.1 // indirect
-	github.com/prometheus/procfs v0.7.3 // indirect
-	github.com/richardlehane/mscfb v1.0.4 // indirect
-	github.com/richardlehane/msoleps v1.0.1 // indirect
-	github.com/spf13/afero v1.8.2 // indirect
-	github.com/spf13/jwalterweatherman v1.1.0 // indirect
-	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/subosito/gotenv v1.3.0 // indirect
-	github.com/syndtr/goleveldb v1.0.0 // indirect
 	github.com/ugorji/go/codec v1.1.7 // indirect
-	github.com/xujiajun/mmap-go v1.0.1 // indirect
-	github.com/xujiajun/utils v0.0.0-20190123093513-8bf096c4f53b // indirect
-	github.com/xuri/efp v0.0.0-20220407160117-ad0f7a785be8 // indirect
-	github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
-	go.etcd.io/etcd/api/v3 v3.5.17 // indirect
-	go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect
 	go.uber.org/atomic v1.7.0 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
 	go.uber.org/zap v1.21.0 // indirect
-	golang.org/x/mod v0.17.0 // indirect
-	golang.org/x/net v0.25.0 // indirect
-	golang.org/x/sync v0.8.0 // indirect
-	golang.org/x/sys v0.26.0 // indirect
-	golang.org/x/text v0.19.0 // indirect
-	golang.org/x/time v0.7.0 // indirect
-	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
-	google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
-	google.golang.org/grpc v1.59.0 // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
+	golang.org/x/mod v0.25.0 // indirect
+	golang.org/x/net v0.41.0 // indirect
+	golang.org/x/sync v0.15.0 // indirect
+	golang.org/x/sys v0.33.0 // indirect
+	golang.org/x/text v0.26.0 // indirect
+	golang.org/x/tools v0.33.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+	google.golang.org/protobuf v1.36.6 // indirect
+	gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
 	gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
-	gopkg.in/ini.v1 v1.66.4 // indirect
-	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gorm.io/datatypes v1.0.7 // indirect
 	gorm.io/hints v1.1.0 // indirect
-	gotest.tools/v3 v3.4.0 // indirect
-	xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
-	xorm.io/xorm v1.3.9 // indirect
 )
 
-replace leafstalk => ./package/graveserver/leafstalk
+replace (
+	entrance-grpc => ./package/entrance-grpc
+	leafstalk => ./package/graveserver/leafstalk
+)
 
 //replace google.golang.org/grpc => google.golang.org/grpc@v1.26.0

+ 39 - 22
server/internal/admin/api/admin_role.go

@@ -26,30 +26,47 @@ func AdminRoleList(c *gin.Context) {
 }
 
 func AdminRoleAuthOption(c *gin.Context) {
-	var (
-		//keys  []int
-		lists []*forms.Option
-	)
-	//permissions, err := config.GetAllPermissions()
-	permissions := config.GetAllOptions()
-
-	//if err != nil {
-	//	c.JSON(200, ErrorResponse(err))
-	//	return
-	//}
-
-	//for k, _ := range config.AuthNameMap {
-	//	keys = append(keys, k)
+	//var (
+	//	lists []*forms.Option
+	//)
+	//permissions := config.GetAllOptions()
+	//for _, v := range permissions {
+	//	lists = append(lists, &forms.Option{
+	//		Value: v.ID,
+	//		Label: v.Name,
+	//		Name:  v.Name,
+	//	})
 	//}
-	//
-	//sort.Ints(keys)
 
-	for _, v := range permissions {
-		lists = append(lists, &forms.Option{
-			Value: v.ID,
-			Label: v.Name,
-			Name:  v.Name,
-		})
+	systems, err := service.AdminRole.GetAllSystem()
+	if err != nil {
+		c.JSON(200, ErrorResponse(err))
+		return
+	}
+	lists := make(map[int32][]*forms.Option)
+	for _, sys := range systems {
+		operations, err := service.AdminRole.GetOperation(sys.ID)
+		if err != nil {
+			c.JSON(200, ErrorResponse(err))
+			return
+		}
+		for _, it := range operations {
+			if _, ok := lists[sys.ID]; !ok {
+				lists[sys.ID] = []*forms.Option{
+					{
+						Value: it.ID,
+						Label: it.Name,
+						Name:  it.Name,
+					},
+				}
+			} else {
+				lists[sys.ID] = append(lists[sys.ID], &forms.Option{
+					Value: it.ID,
+					Label: it.Name,
+					Name:  it.Name,
+				})
+			}
+		}
 	}
 
 	c.JSON(200, serializer.Suc(lists))

+ 112 - 58
server/internal/admin/api/admin_user.go

@@ -1,12 +1,11 @@
 package api
 
 import (
-	"gadmin/config"
+	"context"
+	"entrance-grpc/iam"
 	"gadmin/internal/admin/forms"
 	"gadmin/internal/admin/service"
-	"gadmin/internal/gorm/query"
 	"gadmin/utility/serializer"
-	"gadmin/utility/token"
 	"github.com/gin-gonic/gin"
 )
 
@@ -21,61 +20,61 @@ func UserLogin(c *gin.Context) {
 	}
 }
 
-func UserMe(c *gin.Context) {
-	var (
-		user = token.CurrentUser(c)
-	)
-	permissions := make([]forms.UserLoginPermissions, 0)
-	permissions = append(permissions, forms.UserLoginPermissions{
-		Label: "控制台",
-		Value: "value",
-	})
-	//获取用户角色权限
-	roleInfo, err := service.AdminRole.GetRole(c, forms.AdminRoleReq{ID: user.RoleId})
-	if err != nil || roleInfo == nil {
-		c.JSON(200, ErrorResponse(err))
-		return
-	}
-	if roleInfo.Key == "super" {
-		for k, _ := range config.AuthMenuMap {
-			permissions = append(permissions, forms.UserLoginPermissions{
-				Label: config.AuthNameMap[k],
-				Value: config.AuthMenuMap[k],
-			})
-		}
-	} else {
-		rpdb := query.Use(config.AdminDB).AdminRolePermission
-		rolePermission := make([]int, 0)
-		err = rpdb.Where(rpdb.SystemID.Eq(user.SystemId)).Pluck(rpdb.PermissionID, &rolePermission)
-		//err = json.Unmarshal([]byte(roleInfo.Permissions), &rolePermission)
-		if err != nil {
-			c.JSON(200, ErrorResponse(err))
-			return
-		}
-		for _, v := range rolePermission {
-			if _, ok := config.AuthMenuMap[v]; ok {
-				permissions = append(permissions, forms.UserLoginPermissions{
-					Label: config.AuthNameMap[v],
-					Value: config.AuthMenuMap[v],
-				})
-			}
-		}
-	}
-
-	//将权限赋值给permission
-
-	info := forms.UserMeReq{
-		ID:          user.ID,
-		UserName:    user.UserName,
-		RoleId:      user.RoleId,
-		Avatar:      user.Avatar,
-		Nickname:    user.Nickname,
-		Permissions: permissions,
-		IsSuper:     user.UserName == "admin",
-	}
-
-	c.JSON(200, serializer.Suc(info, "获取成功"))
-}
+//func UserMe(c *gin.Context) {
+//	var (
+//		user = token.CurrentUser(c)
+//	)
+//	permissions := make([]forms.UserLoginPermissions, 0)
+//	permissions = append(permissions, forms.UserLoginPermissions{
+//		Label: "控制台",
+//		Value: "value",
+//	})
+//	//获取用户角色权限
+//	roleInfo, err := service.AdminRole.GetRole(c, forms.AdminRoleReq{ID: user.RoleId})
+//	if err != nil || roleInfo == nil {
+//		c.JSON(200, ErrorResponse(err))
+//		return
+//	}
+//	if roleInfo.Key == "super" {
+//		for k, _ := range config.AuthMenuMap {
+//			permissions = append(permissions, forms.UserLoginPermissions{
+//				Label: config.AuthNameMap[k],
+//				Value: config.AuthMenuMap[k],
+//			})
+//		}
+//	} else {
+//		rpdb := query.Use(config.AdminDB).AdminRolePermission
+//		rolePermission := make([]int, 0)
+//		err = rpdb.Where(rpdb.SystemID.Eq(user.SystemId)).Pluck(rpdb.PermissionID, &rolePermission)
+//		//err = json.Unmarshal([]byte(roleInfo.Permissions), &rolePermission)
+//		if err != nil {
+//			c.JSON(200, ErrorResponse(err))
+//			return
+//		}
+//		for _, v := range rolePermission {
+//			if _, ok := config.AuthMenuMap[v]; ok {
+//				permissions = append(permissions, forms.UserLoginPermissions{
+//					Label: config.AuthNameMap[v],
+//					Value: config.AuthMenuMap[v],
+//				})
+//			}
+//		}
+//	}
+//
+//	//将权限赋值给permission
+//
+//	info := forms.UserMeReq{
+//		ID:          user.ID,
+//		UserName:    user.UserName,
+//		RoleId:      user.RoleId,
+//		Avatar:      user.Avatar,
+//		Nickname:    user.Nickname,
+//		Permissions: permissions,
+//		IsSuper:     user.UserName == "admin",
+//	}
+//
+//	c.JSON(200, serializer.Suc(info, "获取成功"))
+//}
 
 func AdminUserList(c *gin.Context) {
 	var req forms.AdminUserListReq
@@ -113,3 +112,58 @@ func RolePermission(c *gin.Context) {
 	}
 	c.JSON(200, serializer.Suc(is, "获取成功"))
 }
+
+type AdminIamServer struct {
+	iam.UnimplementedIamServer
+}
+
+func (s *AdminIamServer) GetAdminUserByID(ctx context.Context, req *iam.GetAdminUserByIDReq) (*iam.GetAdminUserByIDResp, error) {
+	user, err := service.User.GetUserInfoByID(ctx, req.GetUID())
+	resp := &iam.GetAdminUserByIDResp{}
+	if err != nil {
+		resp.Code = 1
+		resp.Msg = err.Error()
+	}
+	resp.Data = user
+	return resp, nil
+}
+
+func (s *AdminIamServer) BatchGetAdminUser(ctx context.Context, req *iam.BatchGetAdminUserReq) (*iam.BatchGetAdminUserResp, error) {
+	users, err := service.User.BatchGetUsers(ctx, req.GetUIds())
+
+	resp := &iam.BatchGetAdminUserResp{}
+
+	if err != nil {
+		resp.Code = 1
+		resp.Msg = err.Error()
+	} else {
+		resp.Data = users
+	}
+	return resp, nil
+}
+
+func (s *AdminIamServer) GetAdminUserByNickName(ctx context.Context, req *iam.GetAdminUserByNickNameReq) (*iam.GetAdminUserByNickNameResp, error) {
+	resp := &iam.GetAdminUserByNickNameResp{}
+
+	user, err := service.User.GetUserByNickName(ctx, req.GetNickName())
+	if err != nil {
+		resp.Code = 1
+		resp.Msg = err.Error()
+	} else {
+		resp.Data = user
+	}
+
+	return resp, nil
+}
+
+func (s *AdminIamServer) GetRoleSystems(ctx context.Context, req *iam.GetRoleSystemsReq) (*iam.GetRoleSystemsResp, error) {
+	resp := &iam.GetRoleSystemsResp{}
+	systems, err := service.User.GetRoleSystems(ctx, req.GetRoleID())
+	if err != nil {
+		resp.Code = 1
+		resp.Msg = err.Error()
+	} else {
+		resp.Data = systems
+	}
+	return resp, nil
+}

+ 884 - 888
server/internal/admin/api/menu.go

@@ -1,31 +1,27 @@
 package api
 
 import (
-	"gadmin/config"
 	"gadmin/internal/admin/forms"
 	"gadmin/internal/admin/service"
-	"gadmin/utility/serializer"
-	"gadmin/utility/token"
 	"github.com/gin-gonic/gin"
-	"os"
 )
 
 type (
 	Map = map[string]interface{}
 )
 
-func MenuDynamic(c *gin.Context) {
-	systemId := token.GetSystemId(c)
-	t := c.GetHeader("authorization")
-	roleId, _ := c.Get("admin_role_id")
-	list, err := service.Menu.GetRoleMenuList(systemId, roleId.(int64), t)
-	if err != nil {
-		c.JSON(200, ErrorResponse(err))
-		return
-	}
-	c.JSON(200, serializer.Suc(list, "获取成功"))
-	return
-}
+//func MenuDynamic(c *gin.Context) {
+//	systemId := token.GetSystemId(c)
+//	t := c.GetHeader("authorization")
+//	roleId, _ := c.Get("admin_role_id")
+//	list, err := service.Menu.GetRoleMenuList(systemId, roleId.(int64), t)
+//	if err != nil {
+//		c.JSON(200, ErrorResponse(err))
+//		return
+//	}
+//	c.JSON(200, serializer.Suc(list, "获取成功"))
+//	return
+//}
 
 func GetAllMenuList(c *gin.Context) (map[int32][]*forms.Menu, error) {
 	systems, err := service.AdminRole.GetAllSystem()
@@ -46,875 +42,875 @@ func GetAllMenuList(c *gin.Context) (map[int32][]*forms.Menu, error) {
 	return systemMap, nil
 }
 
-func GetMenuList(c *gin.Context) []Map {
-	var (
-		lists       []Map
-		localHidden = true // 本地显示的菜单
-	)
-
-	if os.Getenv("ADMIN_IS_LOCAL") == "1" {
-		localHidden = false
-	}
-
-	// 控制台
-	lists = append(lists, Map{
-		"id":        1,
-		"path":      "/dashboard",
-		"name":      "Dashboard",
-		"component": "LAYOUT",
-		"redirect":  "/dashboard/console",
-		"meta": Map{
-			"title": "Dashboard",
-			"icon":  "DashboardOutlined",
-		},
-		"children": []Map{
-			{
-				"id":        1001,
-				"path":      "console",
-				"name":      "dashboard_console",
-				"component": "/dashboard/console/console",
-				"meta": Map{
-					"title": "主控台",
-				},
-			},
-		},
-	})
-
-	// 玩家管理
-	lists = append(lists, Map{
-		"id":        2,
-		"path":      "/account",
-		"name":      "Account",
-		"component": "LAYOUT",
-		"redirect":  "/account/account-list",
-		"meta": Map{
-			"icon":  "UserOutlined",
-			"title": "玩家管理",
-			"sort":  2,
-		},
-		"children": []Map{
-			{
-				"id":        2001,
-				"path":      "account-list",
-				"name":      "account-list",
-				"component": "/account/accountList/index",
-				"meta": Map{
-					"title": "玩家列表",
-				},
-			},
-			{
-				"id":        2002,
-				"path":      "account-info/:id?",
-				"name":      "account-info",
-				"component": "/account/accountList/info",
-				"meta": Map{
-					"title":      "基础详情",
-					"hidden":     true,
-					"activeMenu": "account-list",
-				},
-			},
-			{
-				"id":        2003,
-				"path":      "account-search",
-				"name":      "account-search",
-				"component": "/account/accountList/search",
-				"meta": Map{
-					"title": "全服查找",
-				},
-			},
-			/*{
-				"path":      "account-banLogs",
-				"name":      "account-banLogs",
-				"component": "/account/accountList/banLogs",
-				"meta": Map{
-					"title": "拉黑记录",
-				},
-			},
-			{
-				"path":      "retrofit-list",
-				"name":      "retrofit-list",
-				"component": "/retrofit/index",
-				"meta": Map{
-					"title": "配装模板",
-				},
-			},
-			{
-				"path":      "consumption-details",
-				"name":      "consumption-details",
-				"component": "/recharge/consumption/index",
-				"meta": Map{
-					"title": "消费变动记录",
-				},
-			},
-			{
-				"path":      "consumption-statistics",
-				"name":      "consumption-statistics",
-				"component": "/recharge/consumptionStatistics/index",
-				"meta": Map{
-					"title": "消费统计",
-				},
-			},
-			{
-				"path":      "game-data-alarm",
-				"name":      "game-data-alarm",
-				"component": "/account/gameDataAlarm/index",
-				"meta": Map{
-					"title": "游戏异常",
-				},
-			},
-			{
-				"path":      "game-cheating-alarm",
-				"name":      "game-cheating-alarm",
-				"component": "/account/gameCheatingAlarm/index",
-				"meta": Map{
-					"title": "作弊数据筛选",
-				},
-			},
-			{
-				"path":      "chat-report-list",
-				"name":      "chat-report-list",
-				"component": "/account/chatReportList/index",
-				"meta": Map{
-					"title": "聊天举报记录",
-				},
-			},
-			{
-				"path":      "chat-log-list",
-				"name":      "chat-log-list",
-				"component": "/account/chatLogList/index",
-				"meta": Map{
-					"title": "聊天记录",
-				},
-			},*/
-		},
-	})
-
-	if config.IsSuperRole(service.User.GetUserRoleId(c)) {
-		// 权限管理
-		lists = append(lists, Map{
-			"id":        3,
-			"path":      "/permission",
-			"name":      "Permission",
-			"component": "LAYOUT",
-			"redirect":  "/permission/menu",
-			"meta": Map{
-				"icon":  "SafetyCertificateOutlined",
-				"title": "权限管理",
-				"sort":  1,
-			},
-			"children": []Map{
-				{
-					"id":        3003,
-					"path":      "menu",
-					"name":      "permission_menu",
-					"component": "/permission/menu/menu",
-					"meta": Map{
-						"title": "菜单权限",
-					},
-				},
-				{
-					"id":        3001,
-					"path":      "user",
-					"name":      "permission_user",
-					"component": "/permission/user/user",
-					"meta": Map{
-						"title": "后台用户",
-					},
-				},
-				{
-					"id":        3002,
-					"path":      "role",
-					"name":      "permission_role",
-					"component": "/permission/role/role",
-					"meta": Map{
-						"title": "角色管理",
-					},
-				},
-			},
-		})
-	}
-
-	// 充值管理
-	/*lists = append(lists, Map{
-		"id":        4,
-		"path":      "/recharge",
-		"name":      "Recharge",
-		"component": "LAYOUT",
-		"redirect":  "/recharge/recharge-list",
-		"meta": Map{
-			"icon":  "PayCircleOutlined",
-			"title": "充值订单",
-			"sort":  2,
-		},
-		"children": []Map{
-			{
-				"id":        4001,
-				"path":      "recharge-list",
-				"name":      "recharge-list",
-				"component": "/recharge/rechargeList/index",
-				"meta": Map{
-					"title": "订单记录",
-				},
-			},
-			{
-				"id":        4002,
-				"path":      "recharge-dailyStatistics",
-				"name":      "recharge-dailyStatistics",
-				"component": "/recharge/dailyStatistics/index",
-				"meta": Map{
-					"title": "每日统计",
-				},
-			},
-			{
-				"id":        4003,
-				"path":      "recharge-ordersSettle",
-				"name":      "recharge-ordersSettle",
-				"component": "/recharge/ordersSettle/index",
-				"meta": Map{
-					"title":     "余额平账",
-					"keepAlive": true,
-				},
-			},
-			{
-				"id":        4004,
-				"path":      "recharge-abnormalOrder",
-				"name":      "recharge-abnormalOrder",
-				"component": "/recharge/abnormalOrder/index",
-				"meta": Map{
-					"title":     "异常订单",
-					"keepAlive": true,
-				},
-			},
-		},
-	})*/
-
-	// 排行榜
-	/*lists = append(lists, Map{
-		"id":        5,
-		"path":      "/ranking",
-		"name":      "Ranking",
-		"component": "LAYOUT",
-		"redirect":  "/ranking/index",
-		"meta": Map{
-			"icon":  "CellularOutline",
-			"title": "排行榜",
-			"sort":  2,
-		},
-		"children": []Map{
-			{
-				"id":        5001,
-				"path":      "recharge-ranking",
-				"name":      "recharge-ranking",
-				"component": "/ranking/recharge/index",
-				"meta": Map{
-					"title": "充值排行",
-				},
-			},
-			{
-				"id":        5002,
-				"path":      "diamond-ranking",
-				"name":      "diamond-ranking",
-				"component": "/ranking/diamond/index",
-				"meta": Map{
-					"title": "消费排行",
-				},
-			},
-			{
-				"id":        5003,
-				"path":      "level-ranking",
-				"name":      "level-ranking",
-				"component": "/ranking/level/index",
-				"meta": Map{
-					"title": "等级排行",
-				},
-			},
-			{
-				"id":        5004,
-				"path":      "elrank-ranking",
-				"name":      "elrank-ranking",
-				"component": "/ranking/elrank/index",
-				"meta": Map{
-					"title": "无尽排行",
-				},
-			},
-			{
-				"id":        5005,
-				"path":      "duel-ranking",
-				"name":      "duel-ranking",
-				"component": "/ranking/duel/index",
-				"meta": Map{
-					"title": "狭路排行",
-				},
-			},
-			{
-				"id":        5006,
-				"path":      "gudong-ranking",
-				"name":      "gudong-ranking",
-				"component": "/ranking/gudong/index",
-				"meta": Map{
-					"title": "古玩排行",
-				},
-			},
-			{
-				"id":        5007,
-				"path":      "idiom-ranking",
-				"name":      "idiom-ranking",
-				"component": "/ranking/idiom/index",
-				"meta": Map{
-					"title": "金榜题名",
-				},
-			},
-			{
-				"id":        5008,
-				"path":      "boss-ranking",
-				"name":      "boss-ranking",
-				"component": "/ranking/boss/index",
-				"meta": Map{
-					"title": "暗影突袭",
-				},
-			},
-			{
-				"id":        5009,
-				"path":      "adv-ranking",
-				"name":      "adv-ranking",
-				"component": "/ranking/adv/index",
-				"meta": Map{
-					"title": "看广告排行",
-				},
-			},
-			{
-				"id":        5010,
-				"path":      "login-ranking",
-				"name":      "login-ranking",
-				"component": "/ranking/login/index",
-				"meta": Map{
-					"title": "登录排行",
-				},
-			},
-		},
-	})*/
-
-	// 数据统计
-	/*lists = append(lists, Map{
-		"id":        6,
-		"path":      "/echarts",
-		"name":      "Echarts",
-		"component": "LAYOUT",
-		"redirect":  "/echarts/index",
-		"meta": Map{
-			"icon":  "BarChartOutline",
-			"title": "数据统计",
-			"sort":  2,
-		},
-		"children": []Map{
-			{
-				"id":        6001,
-				"path":      "login-echarts",
-				"name":      "login-echarts",
-				"component": "/echarts/login/index",
-				"meta": Map{
-					"title": "登录数据",
-				},
-			},
-			{
-				"id":        6002,
-				"path":      "chapter-echarts",
-				"name":      "chapter-echarts",
-				"component": "/echarts/chapter/index",
-				"meta": Map{
-					"title": "关卡数据",
-				},
-			},
-			{
-				"id":        6003,
-				"path":      "basic-echarts",
-				"name":      "basic-echarts",
-				"component": "/echarts/basic/index",
-				"meta": Map{
-					"title": "基础数据",
-				},
-			},
-			{
-				"id":        6004,
-				"path":      "adv-echarts",
-				"name":      "adv-echarts",
-				"component": "/echarts/adv/index",
-				"meta": Map{
-					"title": "广告数据",
-				},
-			},
-			{
-				"id":        6005,
-				"path":      "echarts-tests",
-				"name":      "echarts-tests",
-				"component": "/echarts/adv/index2",
-				"meta": Map{
-					"hidden": localHidden,
-					"title":  "图表测试",
-				},
-			},
-			{
-				"id":        6006,
-				"path":      "goods-echarts",
-				"name":      "goods-echarts",
-				"component": "/echarts/goods/index",
-				"meta": Map{
-					"title": "商品数据",
-				},
-			},
-			{
-				"id":        6007,
-				"path":      "gudong-echarts",
-				"name":      "gudong-echarts",
-				"component": "/echarts/gudong/index",
-				"meta": Map{
-					"title": "古玩数据",
-				},
-			},
-			{
-				"id":        6008,
-				"path":      "duel-echarts",
-				"name":      "duel-echarts",
-				"component": "/echarts/duel/index",
-				"meta": Map{
-					"title": "狭路对决",
-				},
-			},
-			{
-				"id":        6009,
-				"path":      "expedition-echarts",
-				"name":      "expedition-echarts",
-				"component": "/echarts/expedition/index",
-				"meta": Map{
-					"title": "远征数据",
-				},
-			},
-			{
-				"id":        6010,
-				"path":      "idiom-echarts",
-				"name":      "idiom-echarts",
-				"component": "/echarts/idiom/index",
-				"meta": Map{
-					"title": "金榜题名",
-				},
-			},
-			{
-				"id":        6011,
-				"path":      "boss-echarts",
-				"name":      "boss-echarts",
-				"component": "/echarts/boss/index",
-				"meta": Map{
-					"title": "暗影突袭",
-				},
-			},
-			{
-				"id":        6012,
-				"path":      "seven-echarts",
-				"name":      "seven-echarts",
-				"component": "/echarts/seven/index",
-				"meta": Map{
-					"title": "七日任务",
-				},
-			},
-			{
-				"id":        6013,
-				"path":      "disconnect-echarts",
-				"name":      "disconnect-echarts",
-				"component": "/echarts/disconnect/index",
-				"meta": Map{
-					"title": "重连数据",
-				},
-			},
-			{
-				"id":        6014,
-				"path":      "gem-echarts",
-				"name":      "gem-echarts",
-				"component": "/echarts/gem/index",
-				"meta": Map{
-					"title": "宝石数据",
-				},
-			},
-			{
-				"id":        6015,
-				"path":      "limitgift-echarts",
-				"name":      "limitgift-echarts",
-				"component": "/echarts/limitgift/index",
-				"meta": Map{
-					"title": "限时礼包",
-				},
-			},
-			{
-				"id":        6016,
-				"path":      "treasure-echarts",
-				"name":      "treasure-echarts",
-				"component": "/echarts/treasure/index",
-				"meta": Map{
-					"title": "宝物数据",
-				},
-			},
-			{
-				"id":        6017,
-				"path":      "grandmaster-echarts",
-				"name":      "grandmaster-echarts",
-				"component": "/echarts/grandmaster/index",
-				"meta": Map{
-					"title": "最强王者",
-				},
-			},
-			{
-				"id":        6018,
-				"path":      "gradeDistribution-echarts",
-				"name":      "gradeDistribution-echarts",
-				"component": "/echarts/gradeDistribution/index",
-				"meta": Map{
-					"title": "玩家等级分布",
-				},
-			},
-			{
-				"id":        6019,
-				"path":      "roles-echarts",
-				"name":      "roles-echarts",
-				"component": "/echarts/roles/index",
-				"meta": Map{
-					"title": "玩家拥有角色",
-				},
-			},
-			{
-				"id":        6020,
-				"path":      "heroLevelDistribution-echarts",
-				"name":      "heroLevelDistribution-echarts",
-				"component": "/echarts/heroLevelDistribution/index",
-				"meta": Map{
-					"title": "角色等级分布",
-				},
-			},
-			{
-				"id":        6021,
-				"path":      "levelOutput-echarts",
-				"name":      "levelOutput-echarts",
-				"component": "/echarts/levelOutput/index",
-				"meta": Map{
-					"title": "玩家等级产出",
-				},
-			},
-		},
-	})*/
-
-	gameToolMap := make([]Map, 0)
-	gameToolMap = append(gameToolMap, Map{
-		"id":        7001,
-		"path":      "config",
-		"name":      "system_config",
-		"component": "/system/config/config",
-		"meta": Map{
-			"title": "服务配置",
-		},
-	}, Map{
-		"id":        7002,
-		"path":      "deploy",
-		"name":      "system_deploy",
-		"component": "/deploy/index",
-		"meta": Map{
-			"title": "服务部署",
-		},
-	})
-
-	//// 非正式环境加载工具库
-	//if os.Getenv("GIN_MODE") != "release" && os.Getenv("GIN_MODE") != "" {
-	//	gameToolMap = append(gameToolMap, Map{
-	//		"path":      "reboot",
-	//		"name":      "system_reboot",
-	//		"component": "/system/reboot/index",
-	//		"meta": Map{
-	//			"title": "重启服务",
-	//		}})
-	//}
-
-	/*gameToolMap = append(gameToolMap, Map{
-		"path":      "activity-tool",
-		"name":      "activity-tool",
-		"component": "/tool/activity/index",
-		"meta": Map{
-			"title": "活动查询",
-		},
-	})*/
-
-	// 游戏工具
-	lists = append(lists, Map{
-		"id":        7,
-		"path":      "/tool",
-		"name":      "Tool",
-		"component": "LAYOUT",
-		"redirect":  "/tool/index",
-		"meta": Map{
-			"icon":  "ToolOutlined",
-			"title": "游戏工具",
-			"sort":  5,
-		},
-		"children": gameToolMap,
-	})
-
-	// 邮件通知
-	/*lists = append(lists, Map{
-		"id":        8,
-		"path":      "/email",
-		"name":      "email",
-		"component": "LAYOUT",
-		//"redirect":  "/frame/docs",
-		"meta": Map{
-			"icon":       "MailOutlined",
-			"sort":       10,
-			"isRoot":     true,
-			"activeMenu": "email_index",
-		},
-		"children": []Map{
-			{
-				"id":        8001,
-				"path":      "index",
-				"name":      "email_index",
-				"component": "/email/index",
-				"meta": Map{
-					"title":      "邮件通知",
-					"activeMenu": "email_index",
-				},
-			}},
-	})*/
-
-	// 邮件通知
-	/*lists = append(lists, Map{
-		"id":        9,
-		"path":      "/Mail",
-		"name":      "mail",
-		"component": "LAYOUT",
-		//"redirect":  "/frame/docs",
-		"meta": Map{
-			"icon":       "MailOutlined",
-			"sort":       10,
-			"isRoot":     true,
-			"activeMenu": "mail_index",
-		},
-		"children": []Map{
-			{
-				"id":        9001,
-				"path":      "index",
-				"name":      "mail_index",
-				"component": "/mail/index",
-				"meta": Map{
-					"title":      "邮件通知(旧)",
-					"activeMenu": "mail_index",
-				},
-			}},
-	})*/
-
-	// 广播通知
-	/*lists = append(lists, Map{
-		"id":        10,
-		"path":      "/notice",
-		"name":      "notice",
-		"component": "LAYOUT",
-		//"redirect":  "/frame/docs",
-		"meta": Map{
-			"icon":  "MegaphoneOutline",
-			"sort":  10,
-			"title": "广播管理",
-			//"isRoot": true,
-			//"activeMenu": "noticev2_index",
-		},
-		"children": []Map{
-			{
-				"id":        10001,
-				"path":      "noticev2_index", // ?
-				"name":      "noticev2_index",
-				"component": "/noticev2/index",
-				"meta": Map{
-					"title": "广播通知",
-					//"activeMenu": "noticev2_index",
-				},
-			},
-			//{
-			//	"path":      "index",
-			//	"name":      "notice_index",
-			//	"component": "/notice/index",
-			//	"meta": Map{
-			//		"title": "广播通知(旧)",
-			//		//"activeMenu": "notice_index",
-			//	},
-			//},
-		},
-	})*/
-	// 客服记录
-	/*lists = append(lists, Map{
-		"id":        11,
-		"path":      "/chatLog",
-		"name":      "ChatLog",
-		"component": "LAYOUT",
-		"meta": Map{
-			"icon":        "ChatboxEllipsesOutline",
-			"sort":        10,
-			"title":       "客服记录",
-			"permissions": "ChatLog",
-		},
-		"children": []Map{
-			{
-				"id":        11001,
-				"path":      "chatLog-index",
-				"name":      "chatLog-index",
-				"component": "/chatLog/index",
-				"meta": Map{
-					"title": "客服记录",
-				},
-			},
-		},
-	})*/
-	// 兑换码
-	/*lists = append(lists, Map{
-		"id":        12,
-		"path":      "/cdk",
-		"name":      "cdk",
-		"component": "LAYOUT",
-		//"redirect":  "/frame/docs",
-		"meta": Map{
-			"icon": "TicketOutline",
-			"sort": 10,
-			//"isRoot": true,
-			//"activeMenu": "cdk_index",
-			"title": "兑换码管理",
-		},
-		"children": []Map{
-			{
-				"id":        12001,
-				"path":      "index",
-				"name":      "cdk_index",
-				"component": "/cdk/index",
-				"meta": Map{
-					"title":      "批次列表",
-					"activeMenu": "cdk_index",
-				},
-			},
-			{
-				"id":        12002,
-				"path":      "cdk-redeemCodeList/:sn?",
-				"name":      "cdk-redeemCodeList",
-				"component": "/cdk/redeemCodeList",
-				"meta": Map{
-					"title": "兑换码列表",
-					//"hidden":     true,
-					//"activeMenu": "cdk_index",
-				},
-			},
-		},
-	})*/
-
-	// 设置页面
-	lists = append(lists, Map{
-		"id":        13,
-		"path":      "/setting",
-		"name":      "Setting",
-		"component": "LAYOUT",
-		"redirect":  "/setting/account",
-		"meta": Map{
-			"icon":  "SettingOutlined",
-			"title": "账户设置",
-			"sort":  20,
-		},
-		"hidden": false,
-		"children": []Map{
-			{
-				"id":        13001,
-				"path":      "account",
-				"name":      "setting-account",
-				"component": "/setting/account/account",
-				"meta": Map{
-					"title": "个人信息",
-				},
-			},
-			//{
-			//	"path":      "info",
-			//	"name":      "result-info",
-			//	"component": "/setting/system/system",
-			//	"meta": Map{
-			//		"title": "信息页",
-			//	},
-			//},
-			{
-				"id":        13002,
-				"path":      "log",
-				"name":      "log-index",
-				"component": "/log/index",
-				"meta": Map{
-					"title": "操作日志",
-				},
-			},
-			{
-				"id":        13003,
-				"path":      "log-view/:id?",
-				"name":      "log-view",
-				"component": "/log/view",
-				"meta": Map{
-					"title":      "日志详情",
-					"hidden":     true,
-					"activeMenu": "log-index",
-				},
-			},
-		},
-	})
-	t := c.GetHeader("authorization")
-	// 管理后台切换
-	lists = append(lists, Map{
-		"id":        14,
-		"path":      "/server_select",
-		"name":      "ServerSelect",
-		"component": "LAYOUT",
-		"meta": Map{
-			"icon":  "ServerOutline",
-			"title": "管理后台切换",
-			"sort":  5,
-		},
-		"children": []Map{
-			{
-				"id":        14001,
-				"path":      "/redirect",
-				"name":      "http://101.43.249.6:7004/gadmin/?access-token=%s" + t,
-				"component": "LAYOUT",
-				"meta": Map{
-					"title": "魔君测试服",
-				},
-			},
-			{
-				"id":        14002,
-				"path":      "/redirect",
-				"name":      "http://101.43.249.6:7006/cadmin/?access-token=" + t,
-				"component": "LAYOUT",
-				"meta": Map{
-					"title": "空之契约测试服",
-				},
-			},
-			{
-				"id":        14003,
-				"path":      "/redirect",
-				"name":      "http://192.168.0.186:8253/gadmin/?access-token=" + t,
-				"component": "LAYOUT",
-				"meta": Map{
-					"title": "魔君本地",
-				},
-			},
-		},
-	})
-
-	// 文档
-	if localHidden == false {
-		lists = append(lists, Map{
-			"id":        15,
-			"path":      "/external",
-			"name":      "https://www.naiveui.com",
-			"component": "LAYOUT",
-			"meta": Map{
-				"icon":  "DocumentTextOutline",
-				"title": "NaiveUi文档",
-				"sort":  99,
-			},
-			"children": []Map{},
-		})
-	}
-	return lists
-}
+//func GetMenuList(c *gin.Context) []Map {
+//	var (
+//		lists       []Map
+//		localHidden = true // 本地显示的菜单
+//	)
+//
+//	if os.Getenv("ADMIN_IS_LOCAL") == "1" {
+//		localHidden = false
+//	}
+//
+//	// 控制台
+//	lists = append(lists, Map{
+//		"id":        1,
+//		"path":      "/dashboard",
+//		"name":      "Dashboard",
+//		"component": "LAYOUT",
+//		"redirect":  "/dashboard/console",
+//		"meta": Map{
+//			"title": "Dashboard",
+//			"icon":  "DashboardOutlined",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        1001,
+//				"path":      "console",
+//				"name":      "dashboard_console",
+//				"component": "/dashboard/console/console",
+//				"meta": Map{
+//					"title": "主控台",
+//				},
+//			},
+//		},
+//	})
+//
+//	// 玩家管理
+//	lists = append(lists, Map{
+//		"id":        2,
+//		"path":      "/account",
+//		"name":      "Account",
+//		"component": "LAYOUT",
+//		"redirect":  "/account/account-list",
+//		"meta": Map{
+//			"icon":  "UserOutlined",
+//			"title": "玩家管理",
+//			"sort":  2,
+//		},
+//		"children": []Map{
+//			{
+//				"id":        2001,
+//				"path":      "account-list",
+//				"name":      "account-list",
+//				"component": "/account/accountList/index",
+//				"meta": Map{
+//					"title": "玩家列表",
+//				},
+//			},
+//			{
+//				"id":        2002,
+//				"path":      "account-info/:id?",
+//				"name":      "account-info",
+//				"component": "/account/accountList/info",
+//				"meta": Map{
+//					"title":      "基础详情",
+//					"hidden":     true,
+//					"activeMenu": "account-list",
+//				},
+//			},
+//			{
+//				"id":        2003,
+//				"path":      "account-search",
+//				"name":      "account-search",
+//				"component": "/account/accountList/search",
+//				"meta": Map{
+//					"title": "全服查找",
+//				},
+//			},
+//			/*{
+//				"path":      "account-banLogs",
+//				"name":      "account-banLogs",
+//				"component": "/account/accountList/banLogs",
+//				"meta": Map{
+//					"title": "拉黑记录",
+//				},
+//			},
+//			{
+//				"path":      "retrofit-list",
+//				"name":      "retrofit-list",
+//				"component": "/retrofit/index",
+//				"meta": Map{
+//					"title": "配装模板",
+//				},
+//			},
+//			{
+//				"path":      "consumption-details",
+//				"name":      "consumption-details",
+//				"component": "/recharge/consumption/index",
+//				"meta": Map{
+//					"title": "消费变动记录",
+//				},
+//			},
+//			{
+//				"path":      "consumption-statistics",
+//				"name":      "consumption-statistics",
+//				"component": "/recharge/consumptionStatistics/index",
+//				"meta": Map{
+//					"title": "消费统计",
+//				},
+//			},
+//			{
+//				"path":      "game-data-alarm",
+//				"name":      "game-data-alarm",
+//				"component": "/account/gameDataAlarm/index",
+//				"meta": Map{
+//					"title": "游戏异常",
+//				},
+//			},
+//			{
+//				"path":      "game-cheating-alarm",
+//				"name":      "game-cheating-alarm",
+//				"component": "/account/gameCheatingAlarm/index",
+//				"meta": Map{
+//					"title": "作弊数据筛选",
+//				},
+//			},
+//			{
+//				"path":      "chat-report-list",
+//				"name":      "chat-report-list",
+//				"component": "/account/chatReportList/index",
+//				"meta": Map{
+//					"title": "聊天举报记录",
+//				},
+//			},
+//			{
+//				"path":      "chat-log-list",
+//				"name":      "chat-log-list",
+//				"component": "/account/chatLogList/index",
+//				"meta": Map{
+//					"title": "聊天记录",
+//				},
+//			},*/
+//		},
+//	})
+//
+//	if config.IsSuperRole(service.User.GetUserRoleId(c)) {
+//		// 权限管理
+//		lists = append(lists, Map{
+//			"id":        3,
+//			"path":      "/permission",
+//			"name":      "Permission",
+//			"component": "LAYOUT",
+//			"redirect":  "/permission/menu",
+//			"meta": Map{
+//				"icon":  "SafetyCertificateOutlined",
+//				"title": "权限管理",
+//				"sort":  1,
+//			},
+//			"children": []Map{
+//				{
+//					"id":        3003,
+//					"path":      "menu",
+//					"name":      "permission_menu",
+//					"component": "/permission/menu/menu",
+//					"meta": Map{
+//						"title": "菜单权限",
+//					},
+//				},
+//				{
+//					"id":        3001,
+//					"path":      "user",
+//					"name":      "permission_user",
+//					"component": "/permission/user/user",
+//					"meta": Map{
+//						"title": "后台用户",
+//					},
+//				},
+//				{
+//					"id":        3002,
+//					"path":      "role",
+//					"name":      "permission_role",
+//					"component": "/permission/role/role",
+//					"meta": Map{
+//						"title": "角色管理",
+//					},
+//				},
+//			},
+//		})
+//	}
+//
+//	// 充值管理
+//	/*lists = append(lists, Map{
+//		"id":        4,
+//		"path":      "/recharge",
+//		"name":      "Recharge",
+//		"component": "LAYOUT",
+//		"redirect":  "/recharge/recharge-list",
+//		"meta": Map{
+//			"icon":  "PayCircleOutlined",
+//			"title": "充值订单",
+//			"sort":  2,
+//		},
+//		"children": []Map{
+//			{
+//				"id":        4001,
+//				"path":      "recharge-list",
+//				"name":      "recharge-list",
+//				"component": "/recharge/rechargeList/index",
+//				"meta": Map{
+//					"title": "订单记录",
+//				},
+//			},
+//			{
+//				"id":        4002,
+//				"path":      "recharge-dailyStatistics",
+//				"name":      "recharge-dailyStatistics",
+//				"component": "/recharge/dailyStatistics/index",
+//				"meta": Map{
+//					"title": "每日统计",
+//				},
+//			},
+//			{
+//				"id":        4003,
+//				"path":      "recharge-ordersSettle",
+//				"name":      "recharge-ordersSettle",
+//				"component": "/recharge/ordersSettle/index",
+//				"meta": Map{
+//					"title":     "余额平账",
+//					"keepAlive": true,
+//				},
+//			},
+//			{
+//				"id":        4004,
+//				"path":      "recharge-abnormalOrder",
+//				"name":      "recharge-abnormalOrder",
+//				"component": "/recharge/abnormalOrder/index",
+//				"meta": Map{
+//					"title":     "异常订单",
+//					"keepAlive": true,
+//				},
+//			},
+//		},
+//	})*/
+//
+//	// 排行榜
+//	/*lists = append(lists, Map{
+//		"id":        5,
+//		"path":      "/ranking",
+//		"name":      "Ranking",
+//		"component": "LAYOUT",
+//		"redirect":  "/ranking/index",
+//		"meta": Map{
+//			"icon":  "CellularOutline",
+//			"title": "排行榜",
+//			"sort":  2,
+//		},
+//		"children": []Map{
+//			{
+//				"id":        5001,
+//				"path":      "recharge-ranking",
+//				"name":      "recharge-ranking",
+//				"component": "/ranking/recharge/index",
+//				"meta": Map{
+//					"title": "充值排行",
+//				},
+//			},
+//			{
+//				"id":        5002,
+//				"path":      "diamond-ranking",
+//				"name":      "diamond-ranking",
+//				"component": "/ranking/diamond/index",
+//				"meta": Map{
+//					"title": "消费排行",
+//				},
+//			},
+//			{
+//				"id":        5003,
+//				"path":      "level-ranking",
+//				"name":      "level-ranking",
+//				"component": "/ranking/level/index",
+//				"meta": Map{
+//					"title": "等级排行",
+//				},
+//			},
+//			{
+//				"id":        5004,
+//				"path":      "elrank-ranking",
+//				"name":      "elrank-ranking",
+//				"component": "/ranking/elrank/index",
+//				"meta": Map{
+//					"title": "无尽排行",
+//				},
+//			},
+//			{
+//				"id":        5005,
+//				"path":      "duel-ranking",
+//				"name":      "duel-ranking",
+//				"component": "/ranking/duel/index",
+//				"meta": Map{
+//					"title": "狭路排行",
+//				},
+//			},
+//			{
+//				"id":        5006,
+//				"path":      "gudong-ranking",
+//				"name":      "gudong-ranking",
+//				"component": "/ranking/gudong/index",
+//				"meta": Map{
+//					"title": "古玩排行",
+//				},
+//			},
+//			{
+//				"id":        5007,
+//				"path":      "idiom-ranking",
+//				"name":      "idiom-ranking",
+//				"component": "/ranking/idiom/index",
+//				"meta": Map{
+//					"title": "金榜题名",
+//				},
+//			},
+//			{
+//				"id":        5008,
+//				"path":      "boss-ranking",
+//				"name":      "boss-ranking",
+//				"component": "/ranking/boss/index",
+//				"meta": Map{
+//					"title": "暗影突袭",
+//				},
+//			},
+//			{
+//				"id":        5009,
+//				"path":      "adv-ranking",
+//				"name":      "adv-ranking",
+//				"component": "/ranking/adv/index",
+//				"meta": Map{
+//					"title": "看广告排行",
+//				},
+//			},
+//			{
+//				"id":        5010,
+//				"path":      "login-ranking",
+//				"name":      "login-ranking",
+//				"component": "/ranking/login/index",
+//				"meta": Map{
+//					"title": "登录排行",
+//				},
+//			},
+//		},
+//	})*/
+//
+//	// 数据统计
+//	/*lists = append(lists, Map{
+//		"id":        6,
+//		"path":      "/echarts",
+//		"name":      "Echarts",
+//		"component": "LAYOUT",
+//		"redirect":  "/echarts/index",
+//		"meta": Map{
+//			"icon":  "BarChartOutline",
+//			"title": "数据统计",
+//			"sort":  2,
+//		},
+//		"children": []Map{
+//			{
+//				"id":        6001,
+//				"path":      "login-echarts",
+//				"name":      "login-echarts",
+//				"component": "/echarts/login/index",
+//				"meta": Map{
+//					"title": "登录数据",
+//				},
+//			},
+//			{
+//				"id":        6002,
+//				"path":      "chapter-echarts",
+//				"name":      "chapter-echarts",
+//				"component": "/echarts/chapter/index",
+//				"meta": Map{
+//					"title": "关卡数据",
+//				},
+//			},
+//			{
+//				"id":        6003,
+//				"path":      "basic-echarts",
+//				"name":      "basic-echarts",
+//				"component": "/echarts/basic/index",
+//				"meta": Map{
+//					"title": "基础数据",
+//				},
+//			},
+//			{
+//				"id":        6004,
+//				"path":      "adv-echarts",
+//				"name":      "adv-echarts",
+//				"component": "/echarts/adv/index",
+//				"meta": Map{
+//					"title": "广告数据",
+//				},
+//			},
+//			{
+//				"id":        6005,
+//				"path":      "echarts-tests",
+//				"name":      "echarts-tests",
+//				"component": "/echarts/adv/index2",
+//				"meta": Map{
+//					"hidden": localHidden,
+//					"title":  "图表测试",
+//				},
+//			},
+//			{
+//				"id":        6006,
+//				"path":      "goods-echarts",
+//				"name":      "goods-echarts",
+//				"component": "/echarts/goods/index",
+//				"meta": Map{
+//					"title": "商品数据",
+//				},
+//			},
+//			{
+//				"id":        6007,
+//				"path":      "gudong-echarts",
+//				"name":      "gudong-echarts",
+//				"component": "/echarts/gudong/index",
+//				"meta": Map{
+//					"title": "古玩数据",
+//				},
+//			},
+//			{
+//				"id":        6008,
+//				"path":      "duel-echarts",
+//				"name":      "duel-echarts",
+//				"component": "/echarts/duel/index",
+//				"meta": Map{
+//					"title": "狭路对决",
+//				},
+//			},
+//			{
+//				"id":        6009,
+//				"path":      "expedition-echarts",
+//				"name":      "expedition-echarts",
+//				"component": "/echarts/expedition/index",
+//				"meta": Map{
+//					"title": "远征数据",
+//				},
+//			},
+//			{
+//				"id":        6010,
+//				"path":      "idiom-echarts",
+//				"name":      "idiom-echarts",
+//				"component": "/echarts/idiom/index",
+//				"meta": Map{
+//					"title": "金榜题名",
+//				},
+//			},
+//			{
+//				"id":        6011,
+//				"path":      "boss-echarts",
+//				"name":      "boss-echarts",
+//				"component": "/echarts/boss/index",
+//				"meta": Map{
+//					"title": "暗影突袭",
+//				},
+//			},
+//			{
+//				"id":        6012,
+//				"path":      "seven-echarts",
+//				"name":      "seven-echarts",
+//				"component": "/echarts/seven/index",
+//				"meta": Map{
+//					"title": "七日任务",
+//				},
+//			},
+//			{
+//				"id":        6013,
+//				"path":      "disconnect-echarts",
+//				"name":      "disconnect-echarts",
+//				"component": "/echarts/disconnect/index",
+//				"meta": Map{
+//					"title": "重连数据",
+//				},
+//			},
+//			{
+//				"id":        6014,
+//				"path":      "gem-echarts",
+//				"name":      "gem-echarts",
+//				"component": "/echarts/gem/index",
+//				"meta": Map{
+//					"title": "宝石数据",
+//				},
+//			},
+//			{
+//				"id":        6015,
+//				"path":      "limitgift-echarts",
+//				"name":      "limitgift-echarts",
+//				"component": "/echarts/limitgift/index",
+//				"meta": Map{
+//					"title": "限时礼包",
+//				},
+//			},
+//			{
+//				"id":        6016,
+//				"path":      "treasure-echarts",
+//				"name":      "treasure-echarts",
+//				"component": "/echarts/treasure/index",
+//				"meta": Map{
+//					"title": "宝物数据",
+//				},
+//			},
+//			{
+//				"id":        6017,
+//				"path":      "grandmaster-echarts",
+//				"name":      "grandmaster-echarts",
+//				"component": "/echarts/grandmaster/index",
+//				"meta": Map{
+//					"title": "最强王者",
+//				},
+//			},
+//			{
+//				"id":        6018,
+//				"path":      "gradeDistribution-echarts",
+//				"name":      "gradeDistribution-echarts",
+//				"component": "/echarts/gradeDistribution/index",
+//				"meta": Map{
+//					"title": "玩家等级分布",
+//				},
+//			},
+//			{
+//				"id":        6019,
+//				"path":      "roles-echarts",
+//				"name":      "roles-echarts",
+//				"component": "/echarts/roles/index",
+//				"meta": Map{
+//					"title": "玩家拥有角色",
+//				},
+//			},
+//			{
+//				"id":        6020,
+//				"path":      "heroLevelDistribution-echarts",
+//				"name":      "heroLevelDistribution-echarts",
+//				"component": "/echarts/heroLevelDistribution/index",
+//				"meta": Map{
+//					"title": "角色等级分布",
+//				},
+//			},
+//			{
+//				"id":        6021,
+//				"path":      "levelOutput-echarts",
+//				"name":      "levelOutput-echarts",
+//				"component": "/echarts/levelOutput/index",
+//				"meta": Map{
+//					"title": "玩家等级产出",
+//				},
+//			},
+//		},
+//	})*/
+//
+//	gameToolMap := make([]Map, 0)
+//	gameToolMap = append(gameToolMap, Map{
+//		"id":        7001,
+//		"path":      "config",
+//		"name":      "system_config",
+//		"component": "/system/config/config",
+//		"meta": Map{
+//			"title": "服务配置",
+//		},
+//	}, Map{
+//		"id":        7002,
+//		"path":      "deploy",
+//		"name":      "system_deploy",
+//		"component": "/deploy/index",
+//		"meta": Map{
+//			"title": "服务部署",
+//		},
+//	})
+//
+//	//// 非正式环境加载工具库
+//	//if os.Getenv("GIN_MODE") != "release" && os.Getenv("GIN_MODE") != "" {
+//	//	gameToolMap = append(gameToolMap, Map{
+//	//		"path":      "reboot",
+//	//		"name":      "system_reboot",
+//	//		"component": "/system/reboot/index",
+//	//		"meta": Map{
+//	//			"title": "重启服务",
+//	//		}})
+//	//}
+//
+//	/*gameToolMap = append(gameToolMap, Map{
+//		"path":      "activity-tool",
+//		"name":      "activity-tool",
+//		"component": "/tool/activity/index",
+//		"meta": Map{
+//			"title": "活动查询",
+//		},
+//	})*/
+//
+//	// 游戏工具
+//	lists = append(lists, Map{
+//		"id":        7,
+//		"path":      "/tool",
+//		"name":      "Tool",
+//		"component": "LAYOUT",
+//		"redirect":  "/tool/index",
+//		"meta": Map{
+//			"icon":  "ToolOutlined",
+//			"title": "游戏工具",
+//			"sort":  5,
+//		},
+//		"children": gameToolMap,
+//	})
+//
+//	// 邮件通知
+//	/*lists = append(lists, Map{
+//		"id":        8,
+//		"path":      "/email",
+//		"name":      "email",
+//		"component": "LAYOUT",
+//		//"redirect":  "/frame/docs",
+//		"meta": Map{
+//			"icon":       "MailOutlined",
+//			"sort":       10,
+//			"isRoot":     true,
+//			"activeMenu": "email_index",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        8001,
+//				"path":      "index",
+//				"name":      "email_index",
+//				"component": "/email/index",
+//				"meta": Map{
+//					"title":      "邮件通知",
+//					"activeMenu": "email_index",
+//				},
+//			}},
+//	})*/
+//
+//	// 邮件通知
+//	/*lists = append(lists, Map{
+//		"id":        9,
+//		"path":      "/Mail",
+//		"name":      "mail",
+//		"component": "LAYOUT",
+//		//"redirect":  "/frame/docs",
+//		"meta": Map{
+//			"icon":       "MailOutlined",
+//			"sort":       10,
+//			"isRoot":     true,
+//			"activeMenu": "mail_index",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        9001,
+//				"path":      "index",
+//				"name":      "mail_index",
+//				"component": "/mail/index",
+//				"meta": Map{
+//					"title":      "邮件通知(旧)",
+//					"activeMenu": "mail_index",
+//				},
+//			}},
+//	})*/
+//
+//	// 广播通知
+//	/*lists = append(lists, Map{
+//		"id":        10,
+//		"path":      "/notice",
+//		"name":      "notice",
+//		"component": "LAYOUT",
+//		//"redirect":  "/frame/docs",
+//		"meta": Map{
+//			"icon":  "MegaphoneOutline",
+//			"sort":  10,
+//			"title": "广播管理",
+//			//"isRoot": true,
+//			//"activeMenu": "noticev2_index",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        10001,
+//				"path":      "noticev2_index", // ?
+//				"name":      "noticev2_index",
+//				"component": "/noticev2/index",
+//				"meta": Map{
+//					"title": "广播通知",
+//					//"activeMenu": "noticev2_index",
+//				},
+//			},
+//			//{
+//			//	"path":      "index",
+//			//	"name":      "notice_index",
+//			//	"component": "/notice/index",
+//			//	"meta": Map{
+//			//		"title": "广播通知(旧)",
+//			//		//"activeMenu": "notice_index",
+//			//	},
+//			//},
+//		},
+//	})*/
+//	// 客服记录
+//	/*lists = append(lists, Map{
+//		"id":        11,
+//		"path":      "/chatLog",
+//		"name":      "ChatLog",
+//		"component": "LAYOUT",
+//		"meta": Map{
+//			"icon":        "ChatboxEllipsesOutline",
+//			"sort":        10,
+//			"title":       "客服记录",
+//			"permissions": "ChatLog",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        11001,
+//				"path":      "chatLog-index",
+//				"name":      "chatLog-index",
+//				"component": "/chatLog/index",
+//				"meta": Map{
+//					"title": "客服记录",
+//				},
+//			},
+//		},
+//	})*/
+//	// 兑换码
+//	/*lists = append(lists, Map{
+//		"id":        12,
+//		"path":      "/cdk",
+//		"name":      "cdk",
+//		"component": "LAYOUT",
+//		//"redirect":  "/frame/docs",
+//		"meta": Map{
+//			"icon": "TicketOutline",
+//			"sort": 10,
+//			//"isRoot": true,
+//			//"activeMenu": "cdk_index",
+//			"title": "兑换码管理",
+//		},
+//		"children": []Map{
+//			{
+//				"id":        12001,
+//				"path":      "index",
+//				"name":      "cdk_index",
+//				"component": "/cdk/index",
+//				"meta": Map{
+//					"title":      "批次列表",
+//					"activeMenu": "cdk_index",
+//				},
+//			},
+//			{
+//				"id":        12002,
+//				"path":      "cdk-redeemCodeList/:sn?",
+//				"name":      "cdk-redeemCodeList",
+//				"component": "/cdk/redeemCodeList",
+//				"meta": Map{
+//					"title": "兑换码列表",
+//					//"hidden":     true,
+//					//"activeMenu": "cdk_index",
+//				},
+//			},
+//		},
+//	})*/
+//
+//	// 设置页面
+//	lists = append(lists, Map{
+//		"id":        13,
+//		"path":      "/setting",
+//		"name":      "Setting",
+//		"component": "LAYOUT",
+//		"redirect":  "/setting/account",
+//		"meta": Map{
+//			"icon":  "SettingOutlined",
+//			"title": "账户设置",
+//			"sort":  20,
+//		},
+//		"hidden": false,
+//		"children": []Map{
+//			{
+//				"id":        13001,
+//				"path":      "account",
+//				"name":      "setting-account",
+//				"component": "/setting/account/account",
+//				"meta": Map{
+//					"title": "个人信息",
+//				},
+//			},
+//			//{
+//			//	"path":      "info",
+//			//	"name":      "result-info",
+//			//	"component": "/setting/system/system",
+//			//	"meta": Map{
+//			//		"title": "信息页",
+//			//	},
+//			//},
+//			{
+//				"id":        13002,
+//				"path":      "log",
+//				"name":      "log-index",
+//				"component": "/log/index",
+//				"meta": Map{
+//					"title": "操作日志",
+//				},
+//			},
+//			{
+//				"id":        13003,
+//				"path":      "log-view/:id?",
+//				"name":      "log-view",
+//				"component": "/log/view",
+//				"meta": Map{
+//					"title":      "日志详情",
+//					"hidden":     true,
+//					"activeMenu": "log-index",
+//				},
+//			},
+//		},
+//	})
+//	t := c.GetHeader("authorization")
+//	// 管理后台切换
+//	lists = append(lists, Map{
+//		"id":        14,
+//		"path":      "/server_select",
+//		"name":      "ServerSelect",
+//		"component": "LAYOUT",
+//		"meta": Map{
+//			"icon":  "ServerOutline",
+//			"title": "管理后台切换",
+//			"sort":  5,
+//		},
+//		"children": []Map{
+//			{
+//				"id":        14001,
+//				"path":      "/redirect",
+//				"name":      "http://101.43.249.6:7004/gadmin/?access-token=%s" + t,
+//				"component": "LAYOUT",
+//				"meta": Map{
+//					"title": "魔君测试服",
+//				},
+//			},
+//			{
+//				"id":        14002,
+//				"path":      "/redirect",
+//				"name":      "http://101.43.249.6:7006/cadmin/?access-token=" + t,
+//				"component": "LAYOUT",
+//				"meta": Map{
+//					"title": "空之契约测试服",
+//				},
+//			},
+//			{
+//				"id":        14003,
+//				"path":      "/redirect",
+//				"name":      "http://192.168.0.186:8253/gadmin/?access-token=" + t,
+//				"component": "LAYOUT",
+//				"meta": Map{
+//					"title": "魔君本地",
+//				},
+//			},
+//		},
+//	})
+//
+//	// 文档
+//	if localHidden == false {
+//		lists = append(lists, Map{
+//			"id":        15,
+//			"path":      "/external",
+//			"name":      "https://www.naiveui.com",
+//			"component": "LAYOUT",
+//			"meta": Map{
+//				"icon":  "DocumentTextOutline",
+//				"title": "NaiveUi文档",
+//				"sort":  99,
+//			},
+//			"children": []Map{},
+//		})
+//	}
+//	return lists
+//}

+ 16 - 6
server/internal/admin/server/router.go

@@ -1,13 +1,14 @@
 package server
 
 import (
+	"entrance-grpc/iam"
 	"gadmin/config"
 	"gadmin/internal/admin/api"
 	"gadmin/internal/admin/middleware"
 	"github.com/gin-gonic/gin"
 	"github.com/sirupsen/logrus"
+	"google.golang.org/grpc"
 	"net/http"
-	"strings"
 )
 
 // NewEngine 路由配置
@@ -33,8 +34,8 @@ func NewEngine() *gin.Engine {
 	// 路由
 	group := r.Group("/entrance/api")
 	{
-		group.GET("ping", api.Ping)             // ping
-		group.POST("user/login", api.UserLogin) // 用户登录
+		group.GET("ping", api.Ping) // ping
+		//group.POST("user/login", api.UserLogin) // 用户登录
 
 		feishu := group.Group("feishu")
 		//feishu.Use(middleware.ApiToken())
@@ -55,7 +56,7 @@ func NewEngine() *gin.Engine {
 		{
 			// 管理员操作
 			admin := auth.Group("admin")
-			auth.GET("user/me", api.UserMe)                      // 用户信息
+			//auth.GET("user/me", api.UserMe)                      // 用户信息
 			admin.GET("roleList", api.AdminRoleList)             // 角色列表
 			admin.GET("roleAuthOption", api.AdminRoleAuthOption) // 角色权限选项
 			admin.GET("rolePageOption", api.AdminRolePageOption) // 角色可查看页面选项
@@ -67,11 +68,20 @@ func NewEngine() *gin.Engine {
 	}
 
 	for _, info := range r.Routes() {
-		path := strings.TrimPrefix(info.Path, "/entrance")
-		if info.Method == http.MethodPost && !config.HasMenu(path) {
+
+		if info.Method == http.MethodPost && !config.HasMenu(info.Path) {
 			logrus.Panicf("菜单未绑定名称:%v", info.Path)
 		}
 	}
 
 	return r
 }
+
+func RegisterGrpcServer() *grpc.Server {
+	opts := []grpc.ServerOption{}
+	s := grpc.NewServer(opts...)
+
+	iam.RegisterIamServer(s, &api.AdminIamServer{})
+
+	return s
+}

+ 14 - 0
server/internal/admin/server/start.go

@@ -3,6 +3,7 @@ package server
 import (
 	"flag"
 	"gadmin/config"
+	"net"
 	"os"
 	"os/signal"
 	"syscall"
@@ -36,6 +37,19 @@ func Start() {
 		}
 	}()
 
+	// 启动grpc服务
+	go func() {
+		lis, err := net.Listen("tcp", os.Getenv("ADMIN_GRPC_SERVER_PORT"))
+		if err != nil {
+			logrus.Fatalf("failed to listen: %v", err)
+		}
+		s := RegisterGrpcServer()
+		logrus.Printf("server listening at %v", lis.Addr())
+		if err := s.Serve(lis); err != nil {
+			logrus.Fatalf("failed to serve: %v", err)
+		}
+	}()
+
 	after()
 }
 

+ 8 - 2
server/internal/admin/service/admin_menu.go

@@ -22,9 +22,15 @@ func NewAMenu() *aMenu {
 }
 
 func (s *aMenu) GetMenuList(systemId int32) ([]*forms.Menu, error) {
-	q := query.Use(config.AdminDB).AdminMenu
+	if _, ok := config.LogDBGroup[systemId]; !ok {
+		return []*forms.Menu{}, nil
+	}
+	q := query.Use(config.LogDBGroup[systemId]).AdminMenu
+
+	//q := query.Use(config.AdminDB).AdminMenu
 	m := q.WithContext(context.Background())
-	m = m.Where(q.Disable.Eq(0), q.SystemID.Eq(systemId)).Order(q.Sort)
+	//m = m.Where(q.Disable.Eq(0), q.SystemID.Eq(systemId)).Order(q.Sort)
+	m = m.Where(q.Disable.Eq(0)).Order(q.Sort)
 	if os.Getenv("ADMIN_IS_LOCAL") != "1" {
 		m = m.Where(q.LocalShow.Eq(0))
 	}

+ 128 - 73
server/internal/admin/service/admin_role.go

@@ -1,6 +1,7 @@
 package service
 
 import (
+	"context"
 	"encoding/json"
 	"errors"
 	"gadmin/config"
@@ -25,8 +26,6 @@ func (s *sAdminRole) List(ctx *gin.Context, req forms.AdminRoleListReq) serializ
 	var (
 		q            = query.Use(config.AdminDB).AdminRole
 		m            = q.WithContext(ctx)
-		mq           = query.Use(config.AdminDB).AdminRoleMenu
-		pq           = query.Use(config.AdminDB).AdminRolePermission
 		offset int64 = 0
 		models forms.UserAccountListRes
 		lists  []*forms.AdminRoleListModel
@@ -48,36 +47,42 @@ func (s *sAdminRole) List(ctx *gin.Context, req forms.AdminRoleListReq) serializ
 	}
 
 	for _, v := range lists {
-		if err := json.Unmarshal([]byte(cast.ToString(v.Systems)), &v.Systems); err != nil {
+		systemIds := make([]int32, 0)
+		if err := json.Unmarshal([]byte(cast.ToString(v.Systems)), &systemIds); err != nil {
 			return serializer.Err(consts.CodeParamErr, "格式化出错 Systems", err)
 		}
-
-		permissionsModels, err := pq.Where(pq.RoleID.Eq(int32(v.ID))).Find()
-		if err != nil {
-			return serializer.Err(consts.CodeParamErr, "查询出错 permissionsModels", err)
-		}
+		v.Systems = systemIds
 		permissionsMap := make(map[int32][]int32)
-		for _, item := range permissionsModels {
-			if _, ok := permissionsMap[item.SystemID]; ok {
-				permissionsMap[item.SystemID] = append(permissionsMap[item.SystemID], item.PermissionID)
+		pagesMap := make(map[int32][]int32)
+		for _, sid := range systemIds {
+			if _, ok := config.LogDBGroup[sid]; !ok {
+				continue
+			}
+			logDB := query.Use(config.LogDBGroup[sid])
+			pq := logDB.AdminRolePermission
+			mq := logDB.AdminRoleMenu
+			// 查询该角色各系统下的权限
+			permissionIds := make([]int32, 0)
+			if err := pq.Where(pq.RoleID.Eq(int32(v.ID))).Pluck(pq.PermissionID, &permissionIds); err != nil {
+				return serializer.Err(consts.CodeParamErr, "查询出错 permissionsModels", err)
+			}
+			if _, ok := permissionsMap[sid]; ok {
+				permissionsMap[sid] = append(permissionsMap[sid], permissionIds...)
 			} else {
-				permissionsMap[item.SystemID] = []int32{item.PermissionID}
+				permissionsMap[sid] = permissionIds
 			}
-		}
-		v.Permissions = permissionsMap
-
-		pagesModels, err := mq.Where(mq.RoleID.Eq(int32(v.ID))).Find()
-		if err != nil {
-			return serializer.Err(consts.CodeParamErr, "查询出错 pagesModels", err)
-		}
-		pagesMap := make(map[int32][]int32)
-		for _, item := range pagesModels {
-			if _, ok := pagesMap[item.SystemID]; ok {
-				pagesMap[item.SystemID] = append(pagesMap[item.SystemID], item.PageID)
+			// 查询该角色各系统下的页面
+			pageIds := make([]int32, 0)
+			if err := mq.Where(mq.RoleID.Eq(int32(v.ID))).Pluck(mq.PageID, &pageIds); err != nil {
+				return serializer.Response{}
+			}
+			if _, ok := pagesMap[sid]; ok {
+				pagesMap[sid] = append(pagesMap[sid], pageIds...)
 			} else {
-				pagesMap[item.SystemID] = []int32{item.PageID}
+				pagesMap[sid] = pageIds
 			}
 		}
+		v.Permissions = permissionsMap
 		v.Pages = pagesMap
 	}
 
@@ -92,26 +97,41 @@ func (s *sAdminRole) List(ctx *gin.Context, req forms.AdminRoleListReq) serializ
 func (s *sAdminRole) Edit(ctx *gin.Context, req forms.AdminRoleEditReq) serializer.Response {
 
 	q := query.Use(config.AdminDB).AdminRole
-	mq := query.Use(config.AdminDB).AdminRoleMenu
-	pq := query.Use(config.AdminDB).AdminRolePermission
 	uq := query.Use(config.AdminDB).AdminUser
 
 	logrus.Warnf("req:%+v", req)
 
-	menusModel := make([]*model.AdminRoleMenu, 0)
+	type systemOperation struct {
+		Permissions []*model.AdminRolePermission
+		Pages       []*model.AdminRoleMenu
+	}
+	systemOperations := make(map[int32]*systemOperation)
+
 	for sysId, menus := range req.Pages {
+		if _, ok := systemOperations[sysId]; !ok {
+			systemOperations[sysId] = &systemOperation{
+				Permissions: make([]*model.AdminRolePermission, 0),
+				Pages:       make([]*model.AdminRoleMenu, 0),
+			}
+		}
 		for _, menu := range menus {
-			menusModel = append(menusModel, &model.AdminRoleMenu{
+			systemOperations[sysId].Pages = append(systemOperations[sysId].Pages, &model.AdminRoleMenu{
 				SystemID: sysId,
 				RoleID:   int32(req.ID),
 				PageID:   menu,
 			})
 		}
 	}
-	permissionsModel := make([]*model.AdminRolePermission, 0)
+
 	for sysId, permissions := range req.Permissions {
+		if _, ok := systemOperations[sysId]; !ok {
+			systemOperations[sysId] = &systemOperation{
+				Permissions: make([]*model.AdminRolePermission, 0),
+				Pages:       make([]*model.AdminRoleMenu, 0),
+			}
+		}
 		for _, id := range permissions {
-			permissionsModel = append(permissionsModel, &model.AdminRolePermission{
+			systemOperations[sysId].Permissions = append(systemOperations[sysId].Permissions, &model.AdminRolePermission{
 				SystemID:     sysId,
 				RoleID:       int32(req.ID),
 				PermissionID: id,
@@ -134,33 +154,43 @@ func (s *sAdminRole) Edit(ctx *gin.Context, req forms.AdminRoleEditReq) serializ
 			Systems:   string(systems),
 			UpdatedAt: time.Now(),
 		}
-		queryTx := query.Use(config.AdminDB).Begin()
-		_, err := queryTx.AdminRole.Where(q.ID.Eq(req.ID)).Updates(update)
+		// 修改角色基本信息
+		_, err := q.Where(q.ID.Eq(req.ID)).Updates(update)
 		if err != nil {
-			queryTx.Rollback()
-			return serializer.Err(consts.CodeDBError, "更新出错", err)
-		}
-		// 删除旧的菜单权限
-		if _, err := queryTx.AdminRoleMenu.Where(mq.RoleID.Eq(int32(req.ID))).Delete(); err != nil {
-			queryTx.Rollback()
 			return serializer.Err(consts.CodeDBError, "更新出错", err)
 		}
-		// 插入新的菜单权限
-		if err := queryTx.AdminRoleMenu.Create(menusModel...); err != nil {
-			queryTx.Rollback()
-			return serializer.Err(consts.CodeDBError, "更新出错", err)
-		}
-		// 删除旧的操作权限
-		if _, err := queryTx.AdminRolePermission.Where(pq.RoleID.Eq(int32(req.ID))).Delete(); err != nil {
-			queryTx.Rollback()
-			return serializer.Err(consts.CodeDBError, "更新出错", err)
-		}
-		// 插入新的操作权限
-		if err := queryTx.AdminRolePermission.Create(permissionsModel...); err != nil {
-			queryTx.Rollback()
-			return serializer.Err(consts.CodeDBError, "更新出错", err)
+		// 各系统权限、页面处理
+		for sysId, it := range systemOperations {
+			if _, ok := config.LogDBGroup[sysId]; !ok {
+				continue
+			}
+			logDB := query.Use(config.LogDBGroup[sysId])
+			mq := logDB.AdminRoleMenu
+			pq := logDB.AdminRolePermission
+			queryTx := logDB.Begin()
+			// 删除旧的菜单权限
+			if _, err := queryTx.AdminRoleMenu.Where(mq.RoleID.Eq(int32(req.ID))).Delete(); err != nil {
+				queryTx.Rollback()
+				return serializer.Err(consts.CodeDBError, "更新出错", err)
+			}
+			// 插入新的菜单权限
+			if err := queryTx.AdminRoleMenu.Create(it.Pages...); err != nil {
+				queryTx.Rollback()
+				return serializer.Err(consts.CodeDBError, "更新出错", err)
+			}
+			// 删除旧的操作权限
+			if _, err := queryTx.AdminRolePermission.Where(pq.RoleID.Eq(int32(req.ID))).Delete(); err != nil {
+				queryTx.Rollback()
+				return serializer.Err(consts.CodeDBError, "更新出错", err)
+			}
+			// 插入新的操作权限
+			if err := queryTx.AdminRolePermission.Create(it.Permissions...); err != nil {
+				queryTx.Rollback()
+				return serializer.Err(consts.CodeDBError, "更新出错", err)
+			}
+			queryTx.Commit()
 		}
-		queryTx.Commit()
+
 		// 查询该角色下的用户,清空token
 		users, _ := query.Use(config.AdminDB).AdminUser.Where(uq.RoleID.Eq(int32(req.ID))).Find()
 		for _, user := range users {
@@ -180,32 +210,39 @@ func (s *sAdminRole) Edit(ctx *gin.Context, req forms.AdminRoleEditReq) serializ
 		UpdatedAt: time.Now(),
 		CreatedAt: time.Now(),
 	}
-	queryTx := query.Use(config.AdminDB).Begin()
-	if err := queryTx.AdminRole.WithContext(ctx).Create(create); err != nil {
+
+	if err := q.WithContext(ctx).Create(create); err != nil {
 		logrus.Error(err)
-		queryTx.Rollback()
 		return serializer.Err(consts.CodeDBError, "更新出错", err)
 	}
 	// 插入新的菜单权限
-	for _, item := range menusModel {
-		item.RoleID = int32(create.ID)
-	}
-	if err := queryTx.AdminRoleMenu.Create(menusModel...); err != nil {
-		logrus.Error(err)
-		queryTx.Rollback()
-		return serializer.Err(consts.CodeDBError, "更新出错", err)
+	for sysId, it := range systemOperations {
+		if _, ok := config.LogDBGroup[sysId]; !ok {
+			continue
+		}
+		logDB := query.Use(config.LogDBGroup[sysId])
+		queryTx := logDB.Begin()
+		for i := range it.Pages {
+			it.Pages[i].RoleID = int32(create.ID)
+		}
+		for i := range it.Permissions {
+			it.Permissions[i].RoleID = int32(create.ID)
+		}
+		// 插入页面权限
+		if err := queryTx.AdminRoleMenu.Create(it.Pages...); err != nil {
+			logrus.Error(err)
+			queryTx.Rollback()
+			return serializer.Err(consts.CodeDBError, "更新出错", err)
+		}
+		// 插入操作权限
+		if err := queryTx.AdminRolePermission.Create(it.Permissions...); err != nil {
+			logrus.Error(err)
+			queryTx.Rollback()
+			return serializer.Err(consts.CodeDBError, "更新出错", err)
+		}
+		queryTx.Commit()
 	}
 
-	// 插入新的操作权限
-	for _, item := range permissionsModel {
-		item.RoleID = int32(create.ID)
-	}
-	if err := queryTx.AdminRolePermission.Create(permissionsModel...); err != nil {
-		logrus.Error(err)
-		queryTx.Rollback()
-		return serializer.Err(consts.CodeDBError, "更新出错", err)
-	}
-	queryTx.Commit()
 	return serializer.Suc(nil)
 }
 
@@ -231,3 +268,21 @@ func (s *sAdminRole) GetAllSystem() ([]*model.AdminSystem, error) {
 	}
 	return systems, nil
 }
+
+func (s *sAdminRole) GetOperation(systemId int32) ([]*model.AdminOperation, error) {
+	if _, ok := config.LogDBGroup[systemId]; !ok {
+		logrus.Warnf("系统不存在systemId:%v", systemId)
+		return []*model.AdminOperation{}, nil
+	}
+	q := query.Use(config.LogDBGroup[systemId]).AdminOperation
+
+	//q := query.Use(config.AdminDB).AdminMenu
+	m := q.WithContext(context.Background())
+	operations, err := m.Find()
+	if err != nil {
+		logrus.Error(err)
+		return nil, err
+	}
+	//retMenus := handleMenus(operations)
+	return operations, nil
+}

+ 112 - 4
server/internal/admin/service/admin_user.go

@@ -1,7 +1,10 @@
 package service
 
 import (
+	"context"
 	"encoding/base64"
+	"encoding/json"
+	"entrance-grpc/iam"
 	"gadmin/config"
 	"gadmin/internal/admin/consts"
 	"gadmin/internal/admin/forms"
@@ -82,10 +85,10 @@ func (s *sUser) CheckLoginAllow(ip string) bool {
 }
 
 // GetUser 用ID获取用户
-func (s *sUser) GetUser(ID interface{}) (u *model.AdminUser, err error) {
-	result := config.DB.First(&u, ID)
-	return u, result.Error
-}
+//func (s *sUser) GetUser(ID interface{}) (u *model.AdminUser, err error) {
+//	result := config.DB.First(&u, ID)
+//	return u, result.Error
+//}
 
 // SetPassword 设置密码
 func (s *sUser) SetPassword(password string) (string, error) {
@@ -436,3 +439,108 @@ func (s *sUser) GetUserRolePermission(c *gin.Context) (bool, error) {
 	//	return false, nil
 	//}
 }
+
+func (s *sUser) GetUserInfoByID(ctx context.Context, id int64) (*iam.AdminUserInfo, error) {
+	var (
+		q = query.Use(config.AdminDB).AdminUser
+		m = q.WithContext(ctx)
+	)
+	user, err := m.Where(q.ID.Eq(id)).First()
+	if err != nil {
+		return nil, err
+	}
+	if user == nil {
+		return nil, nil
+	}
+	return &iam.AdminUserInfo{
+		ID:       user.ID,
+		RoleID:   int64(user.RoleID),
+		UserName: user.UserName,
+		NickName: user.Nickname,
+		Status:   int64(user.Status),
+	}, nil
+}
+
+func (s *sUser) BatchGetUsers(ctx context.Context, ids []int64) ([]*iam.AdminUserInfo, error) {
+	var (
+		q = query.Use(config.AdminDB).AdminUser
+		m = q.WithContext(ctx)
+	)
+	users, err := m.Where(q.ID.In(ids...)).Find()
+	if err != nil {
+		return nil, err
+	}
+	var result []*iam.AdminUserInfo
+	for _, v := range users {
+		result = append(result, &iam.AdminUserInfo{
+			ID:       v.ID,
+			RoleID:   int64(v.RoleID),
+			UserName: v.UserName,
+			NickName: v.Nickname,
+			Status:   int64(v.Status),
+		})
+	}
+	return result, nil
+}
+
+func (s *sUser) GetUserByNickName(ctx context.Context, nickName string) (*iam.AdminUserInfo, error) {
+	var (
+		q = query.Use(config.AdminDB).AdminUser
+		m = q.WithContext(ctx)
+	)
+	user, err := m.Where(q.Nickname.Eq(nickName)).First()
+	if err != nil {
+		return nil, err
+	}
+	return &iam.AdminUserInfo{
+		ID:       user.ID,
+		RoleID:   int64(user.RoleID),
+		UserName: user.UserName,
+		NickName: user.Nickname,
+		Status:   int64(user.Status),
+	}, nil
+}
+
+func (s *sUser) GetRoleSystems(ctx context.Context, roleId int64) ([]*iam.SystemInfo, error) {
+	var (
+		q  = query.Use(config.AdminDB).AdminRole
+		sq = query.Use(config.AdminDB).AdminSystem
+	)
+	systemModels := make([]*model.AdminSystem, 0)
+	if config.IsSuperRole(roleId) {
+		models, err := sq.Find()
+		if err != nil {
+			logrus.Error(err)
+			return nil, err
+		}
+		systemModels = models
+	} else {
+		systems := ""
+		if err := q.Where(q.ID.Eq(roleId)).Pluck(q.Systems, &systems); err != nil {
+			return nil, err
+		}
+		if systems == "" {
+			return []*iam.SystemInfo{}, nil
+		}
+		systemIds := make([]int32, 0)
+		if err := json.Unmarshal([]byte(systems), &systemIds); err != nil {
+			return nil, err
+		}
+
+		models, err := sq.Where(sq.ID.In(systemIds...)).Order(sq.ID).Find()
+		if err != nil {
+			logrus.Error(err)
+			return nil, err
+		}
+		systemModels = models
+	}
+	services := make([]*iam.SystemInfo, 0)
+	for _, v := range systemModels {
+		services = append(services, &iam.SystemInfo{
+			ID:   int64(v.ID),
+			Name: v.Name,
+			Url:  v.URL,
+		})
+	}
+	return services, nil
+}

+ 17 - 65
server/internal/admin/service/feishu.go

@@ -29,71 +29,6 @@ func (s *feishuService) FeiShuUserLogin(c *gin.Context) serializer.Response {
 
 	q := query.Use(config.AdminDB).AdminUser
 
-	//encodeToken := token.GetAuthorization(c)
-	//if encodeToken != "" {
-	//	bytesT, err := base64.URLEncoding.DecodeString(encodeToken)
-	//	if err != nil {
-	//		logrus.Warningf("middleware base64.URLEncoding.DecodeString:%+v", err.Error())
-	//		return serializer.CheckLogin()
-	//	}
-	//	t := string(bytesT)
-	//	tokenKey := config.GetTokenKey(t)
-	//	if config.TokenRedis.Exists(tokenKey).Val() == 0 {
-	//		return serializer.CheckLogin()
-	//	}
-	//	userStr := config.TokenRedis.Get(tokenKey).Val()
-	//
-	//	claims := new(token.UserClaims)
-	//	if err := jsoniter.UnmarshalFromString(userStr, claims); err != nil {
-	//		return serializer.CheckLogin()
-	//	}
-	//
-	//	// 查询登录token是否有效
-	//	key := config.GetUserTokenKey(claims.ID)
-	//	tokenCTStr := config.TokenRedis.HGet(key, t).Val()
-	//	tokenCreateTime, err := strconv.Atoi(tokenCTStr)
-	//	if err != nil {
-	//		logrus.Warningf("middleware config.LogRedis.HGet:%+v", err.Error())
-	//		return serializer.CheckLogin()
-	//	}
-	//	tokenCT := time.Unix(int64(tokenCreateTime), 0)
-	//
-	//	if tokenCT.Before(time.Now().Add(-config.TokenExpireTime)) {
-	//		return serializer.CheckLogin()
-	//	}
-	//
-	//	u, err := q.Where(q.ID.Eq(claims.ID)).First()
-	//	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-	//		return serializer.Err(2, "", err)
-	//	}
-	//	if u.Status != 1 {
-	//		return serializer.ParamErr("账号已被禁用", nil)
-	//	}
-	//	user := &token.UserClaims{
-	//		ID:          u.ID,
-	//		UserName:    u.UserName,
-	//		RoleId:      int64(u.RoleID),
-	//		Avatar:      u.Avatar,
-	//		Nickname:    u.Nickname,
-	//		AccessToken: t,
-	//	}
-	//	userStr, _ = jsoniter.MarshalToString(user)
-	//
-	//	config.TokenRedis.HSet(key, t, time.Now().Unix())
-	//	config.TokenRedis.Expire(key, time.Hour*12)
-	//
-	//	config.TokenRedis.Set(tokenKey, userStr, time.Hour*12)
-	//
-	//	return serializer.Suc(forms.UserLoginRes{
-	//		ID:       u.ID,
-	//		UserName: u.UserName,
-	//		Nickname: u.Nickname,
-	//		Status:   u.Status,
-	//		Avatar:   u.Avatar,
-	//		Token:    encodeToken,
-	//	})
-	//}
-
 	code := c.Query("code")
 	if code == "" {
 		return serializer.ParamErr("code is empty", nil)
@@ -134,6 +69,23 @@ func (s *feishuService) FeiShuUserLogin(c *gin.Context) serializer.Response {
 		return serializer.Err(9999, "请联系管理员分配权限!", nil)
 	}
 
+	// 验证用户角色状态
+	rdb := query.Use(config.AdminDB).AdminRole
+	result, err := rdb.Where(rdb.ID.Eq(int64(u.RoleID))).First()
+	if err != nil {
+		logrus.Warnf("AdminRole... err:%+v", err)
+		return serializer.ParamErr("获取角色信息失败", err)
+	}
+
+	if result == nil {
+		return serializer.ParamErr("获取角色信息失败", nil)
+	}
+
+	if result.Status != 1 {
+		return serializer.ParamErr("角色权限已被禁用", nil)
+	}
+
+	// 生成token
 	t := token.GenerateTokenUsingUUID()
 
 	// 记录登录token

+ 7 - 0
server/local.env

@@ -3,6 +3,12 @@
 # 管理后台用户数据库
 ADMIN_MYSQL_DSN="root:123456@(127.0.0.1:3306)/dashboard_admin?charset=utf8mb4&parseTime=True&loc=Local"
 
+# 空之契约管理后台数据库
+LOG1_MYSQL_DSN="root:123456@(127.0.0.1:3306)/covenant_dashboard?charset=utf8mb4&parseTime=True&loc=Local"
+
+# 魔君管理后台数据库
+LOG2_MYSQL_DSN="root:123456@(127.0.0.1:3306)/grave_dashboard?charset=utf8mb4&parseTime=True&loc=Local"
+
 # token-redis
 TOKEN_REDIS_ADDR="127.0.0.1:6379"
 TOKEN_REDIS_PW=""
@@ -10,6 +16,7 @@ TOKEN_REDIS_DB="6"
 
 # 服务端运行端口
 ADMIN_SERVER_PORT=":8258"
+ADMIN_GRPC_SERVER_PORT=":7006"
 
 # 本地开发时设置为1,否则为0
 ADMIN_IS_LOCAL=1

+ 15 - 0
server/package/entrance-grpc/go.mod

@@ -0,0 +1,15 @@
+module entrance-grpc
+
+go 1.23.9
+
+require (
+	google.golang.org/grpc v1.73.0
+	google.golang.org/protobuf v1.36.6
+)
+
+require (
+	golang.org/x/net v0.41.0 // indirect
+	golang.org/x/sys v0.33.0 // indirect
+	golang.org/x/text v0.26.0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+)

+ 731 - 0
server/package/entrance-grpc/iam/iam.pb.go

@@ -0,0 +1,731 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.35.2
+// 	protoc        v3.19.4
+// source: proto/iam.proto
+
+package iam
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type GetAdminUserByIDReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UID int64 `protobuf:"varint,1,opt,name=UID,proto3" json:"UID,omitempty"`
+}
+
+func (x *GetAdminUserByIDReq) Reset() {
+	*x = GetAdminUserByIDReq{}
+	mi := &file_proto_iam_proto_msgTypes[0]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetAdminUserByIDReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAdminUserByIDReq) ProtoMessage() {}
+
+func (x *GetAdminUserByIDReq) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[0]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAdminUserByIDReq.ProtoReflect.Descriptor instead.
+func (*GetAdminUserByIDReq) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *GetAdminUserByIDReq) GetUID() int64 {
+	if x != nil {
+		return x.UID
+	}
+	return 0
+}
+
+type GetAdminUserByIDResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code int64          `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
+	Msg  string         `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
+	Data *AdminUserInfo `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
+}
+
+func (x *GetAdminUserByIDResp) Reset() {
+	*x = GetAdminUserByIDResp{}
+	mi := &file_proto_iam_proto_msgTypes[1]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetAdminUserByIDResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAdminUserByIDResp) ProtoMessage() {}
+
+func (x *GetAdminUserByIDResp) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[1]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAdminUserByIDResp.ProtoReflect.Descriptor instead.
+func (*GetAdminUserByIDResp) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *GetAdminUserByIDResp) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *GetAdminUserByIDResp) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *GetAdminUserByIDResp) GetData() *AdminUserInfo {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type BatchGetAdminUserReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	UIds []int64 `protobuf:"varint,1,rep,packed,name=UIds,proto3" json:"UIds,omitempty"`
+}
+
+func (x *BatchGetAdminUserReq) Reset() {
+	*x = BatchGetAdminUserReq{}
+	mi := &file_proto_iam_proto_msgTypes[2]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *BatchGetAdminUserReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchGetAdminUserReq) ProtoMessage() {}
+
+func (x *BatchGetAdminUserReq) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[2]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchGetAdminUserReq.ProtoReflect.Descriptor instead.
+func (*BatchGetAdminUserReq) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *BatchGetAdminUserReq) GetUIds() []int64 {
+	if x != nil {
+		return x.UIds
+	}
+	return nil
+}
+
+type AdminUserInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ID       int64  `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	RoleID   int64  `protobuf:"varint,2,opt,name=RoleID,proto3" json:"RoleID,omitempty"`
+	UserName string `protobuf:"bytes,3,opt,name=UserName,proto3" json:"UserName,omitempty"`
+	NickName string `protobuf:"bytes,4,opt,name=NickName,proto3" json:"NickName,omitempty"`
+	Status   int64  `protobuf:"varint,5,opt,name=Status,proto3" json:"Status,omitempty"`
+}
+
+func (x *AdminUserInfo) Reset() {
+	*x = AdminUserInfo{}
+	mi := &file_proto_iam_proto_msgTypes[3]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *AdminUserInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*AdminUserInfo) ProtoMessage() {}
+
+func (x *AdminUserInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[3]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use AdminUserInfo.ProtoReflect.Descriptor instead.
+func (*AdminUserInfo) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *AdminUserInfo) GetID() int64 {
+	if x != nil {
+		return x.ID
+	}
+	return 0
+}
+
+func (x *AdminUserInfo) GetRoleID() int64 {
+	if x != nil {
+		return x.RoleID
+	}
+	return 0
+}
+
+func (x *AdminUserInfo) GetUserName() string {
+	if x != nil {
+		return x.UserName
+	}
+	return ""
+}
+
+func (x *AdminUserInfo) GetNickName() string {
+	if x != nil {
+		return x.NickName
+	}
+	return ""
+}
+
+func (x *AdminUserInfo) GetStatus() int64 {
+	if x != nil {
+		return x.Status
+	}
+	return 0
+}
+
+type BatchGetAdminUserResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code int64            `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
+	Msg  string           `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
+	Data []*AdminUserInfo `protobuf:"bytes,3,rep,name=Data,proto3" json:"Data,omitempty"`
+}
+
+func (x *BatchGetAdminUserResp) Reset() {
+	*x = BatchGetAdminUserResp{}
+	mi := &file_proto_iam_proto_msgTypes[4]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *BatchGetAdminUserResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchGetAdminUserResp) ProtoMessage() {}
+
+func (x *BatchGetAdminUserResp) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[4]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchGetAdminUserResp.ProtoReflect.Descriptor instead.
+func (*BatchGetAdminUserResp) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *BatchGetAdminUserResp) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *BatchGetAdminUserResp) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *BatchGetAdminUserResp) GetData() []*AdminUserInfo {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type GetAdminUserByNickNameReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	NickName string `protobuf:"bytes,1,opt,name=NickName,proto3" json:"NickName,omitempty"`
+}
+
+func (x *GetAdminUserByNickNameReq) Reset() {
+	*x = GetAdminUserByNickNameReq{}
+	mi := &file_proto_iam_proto_msgTypes[5]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetAdminUserByNickNameReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAdminUserByNickNameReq) ProtoMessage() {}
+
+func (x *GetAdminUserByNickNameReq) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[5]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAdminUserByNickNameReq.ProtoReflect.Descriptor instead.
+func (*GetAdminUserByNickNameReq) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *GetAdminUserByNickNameReq) GetNickName() string {
+	if x != nil {
+		return x.NickName
+	}
+	return ""
+}
+
+type GetAdminUserByNickNameResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code int64          `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
+	Msg  string         `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
+	Data *AdminUserInfo `protobuf:"bytes,3,opt,name=Data,proto3" json:"Data,omitempty"`
+}
+
+func (x *GetAdminUserByNickNameResp) Reset() {
+	*x = GetAdminUserByNickNameResp{}
+	mi := &file_proto_iam_proto_msgTypes[6]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetAdminUserByNickNameResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetAdminUserByNickNameResp) ProtoMessage() {}
+
+func (x *GetAdminUserByNickNameResp) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[6]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetAdminUserByNickNameResp.ProtoReflect.Descriptor instead.
+func (*GetAdminUserByNickNameResp) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *GetAdminUserByNickNameResp) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *GetAdminUserByNickNameResp) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *GetAdminUserByNickNameResp) GetData() *AdminUserInfo {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+type GetRoleSystemsReq struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	RoleID int64 `protobuf:"varint,1,opt,name=RoleID,proto3" json:"RoleID,omitempty"`
+}
+
+func (x *GetRoleSystemsReq) Reset() {
+	*x = GetRoleSystemsReq{}
+	mi := &file_proto_iam_proto_msgTypes[7]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetRoleSystemsReq) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetRoleSystemsReq) ProtoMessage() {}
+
+func (x *GetRoleSystemsReq) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[7]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetRoleSystemsReq.ProtoReflect.Descriptor instead.
+func (*GetRoleSystemsReq) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *GetRoleSystemsReq) GetRoleID() int64 {
+	if x != nil {
+		return x.RoleID
+	}
+	return 0
+}
+
+type SystemInfo struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ID   int64  `protobuf:"varint,1,opt,name=ID,proto3" json:"ID,omitempty"`
+	Name string `protobuf:"bytes,2,opt,name=Name,proto3" json:"Name,omitempty"`
+	Url  string `protobuf:"bytes,3,opt,name=Url,proto3" json:"Url,omitempty"`
+}
+
+func (x *SystemInfo) Reset() {
+	*x = SystemInfo{}
+	mi := &file_proto_iam_proto_msgTypes[8]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *SystemInfo) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*SystemInfo) ProtoMessage() {}
+
+func (x *SystemInfo) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[8]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use SystemInfo.ProtoReflect.Descriptor instead.
+func (*SystemInfo) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *SystemInfo) GetID() int64 {
+	if x != nil {
+		return x.ID
+	}
+	return 0
+}
+
+func (x *SystemInfo) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *SystemInfo) GetUrl() string {
+	if x != nil {
+		return x.Url
+	}
+	return ""
+}
+
+type GetRoleSystemsResp struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Code int64         `protobuf:"varint,1,opt,name=Code,proto3" json:"Code,omitempty"`
+	Msg  string        `protobuf:"bytes,2,opt,name=Msg,proto3" json:"Msg,omitempty"`
+	Data []*SystemInfo `protobuf:"bytes,3,rep,name=Data,proto3" json:"Data,omitempty"`
+}
+
+func (x *GetRoleSystemsResp) Reset() {
+	*x = GetRoleSystemsResp{}
+	mi := &file_proto_iam_proto_msgTypes[9]
+	ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+	ms.StoreMessageInfo(mi)
+}
+
+func (x *GetRoleSystemsResp) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetRoleSystemsResp) ProtoMessage() {}
+
+func (x *GetRoleSystemsResp) ProtoReflect() protoreflect.Message {
+	mi := &file_proto_iam_proto_msgTypes[9]
+	if x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetRoleSystemsResp.ProtoReflect.Descriptor instead.
+func (*GetRoleSystemsResp) Descriptor() ([]byte, []int) {
+	return file_proto_iam_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *GetRoleSystemsResp) GetCode() int64 {
+	if x != nil {
+		return x.Code
+	}
+	return 0
+}
+
+func (x *GetRoleSystemsResp) GetMsg() string {
+	if x != nil {
+		return x.Msg
+	}
+	return ""
+}
+
+func (x *GetRoleSystemsResp) GetData() []*SystemInfo {
+	if x != nil {
+		return x.Data
+	}
+	return nil
+}
+
+var File_proto_iam_proto protoreflect.FileDescriptor
+
+var file_proto_iam_proto_rawDesc = []byte{
+	0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x69, 0x61, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x12, 0x03, 0x69, 0x61, 0x6d, 0x22, 0x27, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d,
+	0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a,
+	0x03, 0x55, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x03, 0x55, 0x49, 0x44, 0x22,
+	0x64, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42,
+	0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d,
+	0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x26, 0x0a,
+	0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x69, 0x61,
+	0x6d, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52,
+	0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x2a, 0x0a, 0x14, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65,
+	0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x12, 0x0a,
+	0x04, 0x55, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x04, 0x55, 0x49, 0x64,
+	0x73, 0x22, 0x87, 0x01, 0x0a, 0x0d, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49,
+	0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
+	0x02, 0x49, 0x44, 0x12, 0x16, 0x0a, 0x06, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x06, 0x52, 0x6f, 0x6c, 0x65, 0x49, 0x44, 0x12, 0x1a, 0x0a, 0x08, 0x55,
+	0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x55,
+	0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x4e, 0x69, 0x63, 0x6b, 0x4e,
+	0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4e, 0x69, 0x63, 0x6b, 0x4e,
+	0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x03, 0x52, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x65, 0x0a, 0x15, 0x42,
+	0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72,
+	0x52, 0x65, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x03, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x12, 0x26, 0x0a, 0x04, 0x44, 0x61,
+	0x74, 0x61, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x41,
+	0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x44, 0x61,
+	0x74, 0x61, 0x22, 0x37, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73,
+	0x65, 0x72, 0x42, 0x79, 0x4e, 0x69, 0x63, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x12,
+	0x1a, 0x0a, 0x08, 0x4e, 0x69, 0x63, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x09, 0x52, 0x08, 0x4e, 0x69, 0x63, 0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x6a, 0x0a, 0x1a, 0x47,
+	0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x4e, 0x69, 0x63,
+	0x6b, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x65, 0x73, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x43, 0x6f, 0x64,
+	0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a,
+	0x03, 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x4d, 0x73, 0x67, 0x12,
+	0x26, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e,
+	0x69, 0x61, 0x6d, 0x2e, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x49, 0x6e, 0x66,
+	0x6f, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x2b, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x52, 0x6f,
+	0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06,
+	0x52, 0x6f, 0x6c, 0x65, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x52, 0x6f,
+	0x6c, 0x65, 0x49, 0x44, 0x22, 0x42, 0x0a, 0x0a, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e,
+	0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x02,
+	0x49, 0x44, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x55, 0x72, 0x6c, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x03, 0x55, 0x72, 0x6c, 0x22, 0x5f, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x52,
+	0x6f, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x12, 0x12,
+	0x0a, 0x04, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x43, 0x6f,
+	0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x4d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x4d, 0x73, 0x67, 0x12, 0x23, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x03,
+	0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49,
+	0x6e, 0x66, 0x6f, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x32, 0xc0, 0x02, 0x0a, 0x03, 0x49, 0x61,
+	0x6d, 0x12, 0x49, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65,
+	0x72, 0x42, 0x79, 0x49, 0x44, 0x12, 0x18, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41,
+	0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x71, 0x1a,
+	0x19, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73,
+	0x65, 0x72, 0x42, 0x79, 0x49, 0x44, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x4c, 0x0a, 0x11,
+	0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65,
+	0x72, 0x12, 0x19, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74,
+	0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x1a, 0x2e, 0x69,
+	0x61, 0x6d, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x47, 0x65, 0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e,
+	0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x16, 0x47, 0x65,
+	0x74, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x4e, 0x69, 0x63, 0x6b,
+	0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64,
+	0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x4e, 0x69, 0x63, 0x6b, 0x4e, 0x61, 0x6d,
+	0x65, 0x52, 0x65, 0x71, 0x1a, 0x1f, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x64,
+	0x6d, 0x69, 0x6e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x79, 0x4e, 0x69, 0x63, 0x6b, 0x4e, 0x61, 0x6d,
+	0x65, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x52, 0x6f,
+	0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x16, 0x2e, 0x69, 0x61, 0x6d, 0x2e,
+	0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65,
+	0x71, 0x1a, 0x17, 0x2e, 0x69, 0x61, 0x6d, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x53,
+	0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05,
+	0x2e, 0x2f, 0x69, 0x61, 0x6d, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_proto_iam_proto_rawDescOnce sync.Once
+	file_proto_iam_proto_rawDescData = file_proto_iam_proto_rawDesc
+)
+
+func file_proto_iam_proto_rawDescGZIP() []byte {
+	file_proto_iam_proto_rawDescOnce.Do(func() {
+		file_proto_iam_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_iam_proto_rawDescData)
+	})
+	return file_proto_iam_proto_rawDescData
+}
+
+var file_proto_iam_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
+var file_proto_iam_proto_goTypes = []any{
+	(*GetAdminUserByIDReq)(nil),        // 0: iam.GetAdminUserByIDReq
+	(*GetAdminUserByIDResp)(nil),       // 1: iam.GetAdminUserByIDResp
+	(*BatchGetAdminUserReq)(nil),       // 2: iam.BatchGetAdminUserReq
+	(*AdminUserInfo)(nil),              // 3: iam.AdminUserInfo
+	(*BatchGetAdminUserResp)(nil),      // 4: iam.BatchGetAdminUserResp
+	(*GetAdminUserByNickNameReq)(nil),  // 5: iam.GetAdminUserByNickNameReq
+	(*GetAdminUserByNickNameResp)(nil), // 6: iam.GetAdminUserByNickNameResp
+	(*GetRoleSystemsReq)(nil),          // 7: iam.GetRoleSystemsReq
+	(*SystemInfo)(nil),                 // 8: iam.SystemInfo
+	(*GetRoleSystemsResp)(nil),         // 9: iam.GetRoleSystemsResp
+}
+var file_proto_iam_proto_depIdxs = []int32{
+	3, // 0: iam.GetAdminUserByIDResp.Data:type_name -> iam.AdminUserInfo
+	3, // 1: iam.BatchGetAdminUserResp.Data:type_name -> iam.AdminUserInfo
+	3, // 2: iam.GetAdminUserByNickNameResp.Data:type_name -> iam.AdminUserInfo
+	8, // 3: iam.GetRoleSystemsResp.Data:type_name -> iam.SystemInfo
+	0, // 4: iam.Iam.GetAdminUserByID:input_type -> iam.GetAdminUserByIDReq
+	2, // 5: iam.Iam.BatchGetAdminUser:input_type -> iam.BatchGetAdminUserReq
+	5, // 6: iam.Iam.GetAdminUserByNickName:input_type -> iam.GetAdminUserByNickNameReq
+	7, // 7: iam.Iam.GetRoleSystems:input_type -> iam.GetRoleSystemsReq
+	1, // 8: iam.Iam.GetAdminUserByID:output_type -> iam.GetAdminUserByIDResp
+	4, // 9: iam.Iam.BatchGetAdminUser:output_type -> iam.BatchGetAdminUserResp
+	6, // 10: iam.Iam.GetAdminUserByNickName:output_type -> iam.GetAdminUserByNickNameResp
+	9, // 11: iam.Iam.GetRoleSystems:output_type -> iam.GetRoleSystemsResp
+	8, // [8:12] is the sub-list for method output_type
+	4, // [4:8] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
+}
+
+func init() { file_proto_iam_proto_init() }
+func file_proto_iam_proto_init() {
+	if File_proto_iam_proto != nil {
+		return
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_proto_iam_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   10,
+			NumExtensions: 0,
+			NumServices:   1,
+		},
+		GoTypes:           file_proto_iam_proto_goTypes,
+		DependencyIndexes: file_proto_iam_proto_depIdxs,
+		MessageInfos:      file_proto_iam_proto_msgTypes,
+	}.Build()
+	File_proto_iam_proto = out.File
+	file_proto_iam_proto_rawDesc = nil
+	file_proto_iam_proto_goTypes = nil
+	file_proto_iam_proto_depIdxs = nil
+}

+ 243 - 0
server/package/entrance-grpc/iam/iam_grpc.pb.go

@@ -0,0 +1,243 @@
+// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
+// versions:
+// - protoc-gen-go-grpc v1.5.1
+// - protoc             v3.19.4
+// source: proto/iam.proto
+
+package iam
+
+import (
+	context "context"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+)
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+// Requires gRPC-Go v1.64.0 or later.
+const _ = grpc.SupportPackageIsVersion9
+
+const (
+	Iam_GetAdminUserByID_FullMethodName       = "/iam.Iam/GetAdminUserByID"
+	Iam_BatchGetAdminUser_FullMethodName      = "/iam.Iam/BatchGetAdminUser"
+	Iam_GetAdminUserByNickName_FullMethodName = "/iam.Iam/GetAdminUserByNickName"
+	Iam_GetRoleSystems_FullMethodName         = "/iam.Iam/GetRoleSystems"
+)
+
+// IamClient is the client API for Iam service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
+type IamClient interface {
+	// 根据ID获取管理员信息
+	GetAdminUserByID(ctx context.Context, in *GetAdminUserByIDReq, opts ...grpc.CallOption) (*GetAdminUserByIDResp, error)
+	// 批量获取管理员信息
+	BatchGetAdminUser(ctx context.Context, in *BatchGetAdminUserReq, opts ...grpc.CallOption) (*BatchGetAdminUserResp, error)
+	// 根据昵称获取管理员信息
+	GetAdminUserByNickName(ctx context.Context, in *GetAdminUserByNickNameReq, opts ...grpc.CallOption) (*GetAdminUserByNickNameResp, error)
+	// 获取角色拥有的系统权限
+	GetRoleSystems(ctx context.Context, in *GetRoleSystemsReq, opts ...grpc.CallOption) (*GetRoleSystemsResp, error)
+}
+
+type iamClient struct {
+	cc grpc.ClientConnInterface
+}
+
+func NewIamClient(cc grpc.ClientConnInterface) IamClient {
+	return &iamClient{cc}
+}
+
+func (c *iamClient) GetAdminUserByID(ctx context.Context, in *GetAdminUserByIDReq, opts ...grpc.CallOption) (*GetAdminUserByIDResp, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(GetAdminUserByIDResp)
+	err := c.cc.Invoke(ctx, Iam_GetAdminUserByID_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *iamClient) BatchGetAdminUser(ctx context.Context, in *BatchGetAdminUserReq, opts ...grpc.CallOption) (*BatchGetAdminUserResp, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(BatchGetAdminUserResp)
+	err := c.cc.Invoke(ctx, Iam_BatchGetAdminUser_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *iamClient) GetAdminUserByNickName(ctx context.Context, in *GetAdminUserByNickNameReq, opts ...grpc.CallOption) (*GetAdminUserByNickNameResp, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(GetAdminUserByNickNameResp)
+	err := c.cc.Invoke(ctx, Iam_GetAdminUserByNickName_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *iamClient) GetRoleSystems(ctx context.Context, in *GetRoleSystemsReq, opts ...grpc.CallOption) (*GetRoleSystemsResp, error) {
+	cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+	out := new(GetRoleSystemsResp)
+	err := c.cc.Invoke(ctx, Iam_GetRoleSystems_FullMethodName, in, out, cOpts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// IamServer is the server API for Iam service.
+// All implementations must embed UnimplementedIamServer
+// for forward compatibility.
+type IamServer interface {
+	// 根据ID获取管理员信息
+	GetAdminUserByID(context.Context, *GetAdminUserByIDReq) (*GetAdminUserByIDResp, error)
+	// 批量获取管理员信息
+	BatchGetAdminUser(context.Context, *BatchGetAdminUserReq) (*BatchGetAdminUserResp, error)
+	// 根据昵称获取管理员信息
+	GetAdminUserByNickName(context.Context, *GetAdminUserByNickNameReq) (*GetAdminUserByNickNameResp, error)
+	// 获取角色拥有的系统权限
+	GetRoleSystems(context.Context, *GetRoleSystemsReq) (*GetRoleSystemsResp, error)
+	mustEmbedUnimplementedIamServer()
+}
+
+// UnimplementedIamServer must be embedded to have
+// forward compatible implementations.
+//
+// NOTE: this should be embedded by value instead of pointer to avoid a nil
+// pointer dereference when methods are called.
+type UnimplementedIamServer struct{}
+
+func (UnimplementedIamServer) GetAdminUserByID(context.Context, *GetAdminUserByIDReq) (*GetAdminUserByIDResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetAdminUserByID not implemented")
+}
+func (UnimplementedIamServer) BatchGetAdminUser(context.Context, *BatchGetAdminUserReq) (*BatchGetAdminUserResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method BatchGetAdminUser not implemented")
+}
+func (UnimplementedIamServer) GetAdminUserByNickName(context.Context, *GetAdminUserByNickNameReq) (*GetAdminUserByNickNameResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetAdminUserByNickName not implemented")
+}
+func (UnimplementedIamServer) GetRoleSystems(context.Context, *GetRoleSystemsReq) (*GetRoleSystemsResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetRoleSystems not implemented")
+}
+func (UnimplementedIamServer) mustEmbedUnimplementedIamServer() {}
+func (UnimplementedIamServer) testEmbeddedByValue()             {}
+
+// UnsafeIamServer may be embedded to opt out of forward compatibility for this service.
+// Use of this interface is not recommended, as added methods to IamServer will
+// result in compilation errors.
+type UnsafeIamServer interface {
+	mustEmbedUnimplementedIamServer()
+}
+
+func RegisterIamServer(s grpc.ServiceRegistrar, srv IamServer) {
+	// If the following call pancis, it indicates UnimplementedIamServer was
+	// embedded by pointer and is nil.  This will cause panics if an
+	// unimplemented method is ever invoked, so we test this at initialization
+	// time to prevent it from happening at runtime later due to I/O.
+	if t, ok := srv.(interface{ testEmbeddedByValue() }); ok {
+		t.testEmbeddedByValue()
+	}
+	s.RegisterService(&Iam_ServiceDesc, srv)
+}
+
+func _Iam_GetAdminUserByID_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetAdminUserByIDReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IamServer).GetAdminUserByID(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Iam_GetAdminUserByID_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IamServer).GetAdminUserByID(ctx, req.(*GetAdminUserByIDReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Iam_BatchGetAdminUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(BatchGetAdminUserReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IamServer).BatchGetAdminUser(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Iam_BatchGetAdminUser_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IamServer).BatchGetAdminUser(ctx, req.(*BatchGetAdminUserReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Iam_GetAdminUserByNickName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetAdminUserByNickNameReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IamServer).GetAdminUserByNickName(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Iam_GetAdminUserByNickName_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IamServer).GetAdminUserByNickName(ctx, req.(*GetAdminUserByNickNameReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Iam_GetRoleSystems_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetRoleSystemsReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(IamServer).GetRoleSystems(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: Iam_GetRoleSystems_FullMethodName,
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(IamServer).GetRoleSystems(ctx, req.(*GetRoleSystemsReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+// Iam_ServiceDesc is the grpc.ServiceDesc for Iam service.
+// It's only intended for direct use with grpc.RegisterService,
+// and not to be introspected or modified (even as a copy)
+var Iam_ServiceDesc = grpc.ServiceDesc{
+	ServiceName: "iam.Iam",
+	HandlerType: (*IamServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetAdminUserByID",
+			Handler:    _Iam_GetAdminUserByID_Handler,
+		},
+		{
+			MethodName: "BatchGetAdminUser",
+			Handler:    _Iam_BatchGetAdminUser_Handler,
+		},
+		{
+			MethodName: "GetAdminUserByNickName",
+			Handler:    _Iam_GetAdminUserByNickName_Handler,
+		},
+		{
+			MethodName: "GetRoleSystems",
+			Handler:    _Iam_GetRoleSystems_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "proto/iam.proto",
+}

+ 72 - 0
server/package/entrance-grpc/proto/iam.proto

@@ -0,0 +1,72 @@
+syntax = "proto3";
+
+package iam;
+
+option go_package = "./iam";
+
+service Iam {
+  // 根据ID获取管理员信息
+  rpc GetAdminUserByID(GetAdminUserByIDReq) returns (GetAdminUserByIDResp) {}
+  // 批量获取管理员信息
+  rpc BatchGetAdminUser(BatchGetAdminUserReq) returns (BatchGetAdminUserResp) {}
+  // 根据昵称获取管理员信息
+  rpc GetAdminUserByNickName(GetAdminUserByNickNameReq) returns (GetAdminUserByNickNameResp) {}
+  // 获取角色拥有的系统权限
+  rpc GetRoleSystems(GetRoleSystemsReq) returns (GetRoleSystemsResp) {}
+}
+
+message GetAdminUserByIDReq {
+  int64 UID = 1;
+}
+
+message GetAdminUserByIDResp {
+  int64 Code = 1;
+  string Msg = 2;
+  AdminUserInfo Data = 3;
+}
+
+message BatchGetAdminUserReq {
+  repeated int64 UIds = 1;
+}
+
+message AdminUserInfo  {
+  int64 ID = 1;
+  int64 RoleID = 2;
+  string UserName = 3;
+  string NickName = 4;
+  int64 Status = 5;
+}
+
+message BatchGetAdminUserResp {
+  int64 Code = 1;
+  string Msg = 2;
+  repeated AdminUserInfo Data = 3;
+}
+
+message GetAdminUserByNickNameReq  {
+  string NickName = 1;
+}
+
+message GetAdminUserByNickNameResp  {
+  int64 Code = 1;
+  string Msg = 2;
+  AdminUserInfo Data = 3;
+}
+
+message GetRoleSystemsReq {
+  int64 RoleID = 1;
+}
+
+message SystemInfo {
+  int64 ID = 1;
+  string Name = 2;
+  string Url = 3;
+}
+
+message GetRoleSystemsResp {
+  int64 Code = 1;
+  string Msg = 2;
+  repeated SystemInfo Data = 3;
+}
+
+

+ 3 - 0
server/package/entrance-grpc/protoc.bat

@@ -0,0 +1,3 @@
+protoc --go_out=. --go-grpc_out=. .\proto\*.proto
+
+exit

+ 0 - 308
server/utility/player/player.go

@@ -1,308 +0,0 @@
-package player
-
-import (
-	"errors"
-	"gadmin/config"
-	"gadmin/internal/admin/consts"
-	"gadmin/internal/gorm/model"
-	"gadmin/internal/gorm/query"
-	"strconv"
-	"sync"
-
-	"github.com/sirupsen/logrus"
-	"github.com/spf13/cast"
-	"gorm.io/gorm"
-)
-
-const (
-	maxMapStoreLimit = 50000
-)
-
-var (
-	AllRoleData     = make(map[int]*RoleData, 0)
-	lock            sync.RWMutex
-	userStampMap    = make(map[int64]int32)
-	userChannelLock sync.RWMutex
-	userChannelMap  = make(map[int64]string, 0)
-)
-
-type RoleData struct {
-	ID        int `json:"id"`
-	Type      int `json:"type"`
-	Evolution int `json:"evolution"`
-	Level     int `json:"level"`
-	Break     int `json:"break"`
-}
-
-// GetRoleData 根据角色ID获取角色信息
-func GetRoleData(id int) *RoleData {
-	idx := strconv.Itoa(id)
-	if len(idx) == 9 {
-		level, _ := strconv.Atoi(idx[5:8])
-
-		role := &RoleData{
-			ID:        id,
-			Type:      cast.ToInt(idx[:1]),
-			Evolution: cast.ToInt(idx[4:5]),
-			Level:     level,
-			Break:     id % 10,
-		}
-
-		return role
-	}
-	if len(idx) == 10 {
-		level, _ := strconv.Atoi(idx[6:9])
-
-		role := &RoleData{
-			ID:        id,
-			Type:      cast.ToInt(idx[:2]),
-			Evolution: cast.ToInt(idx[5:6]),
-			Level:     level,
-			Break:     id % 10,
-		}
-
-		return role
-	}
-
-	logrus.Warnf("GetRoleData role = nil, id:%+v", id)
-	return nil
-}
-
-func GetUserChannel(userId int64) string {
-	if userId == 0 {
-		return "0"
-	}
-
-	//if val, ok := userChannelMap[userId]; ok {
-	//	return val
-	//}
-
-	userChannelLock.RLock()
-	defer userChannelLock.RUnlock()
-
-	u := query.Use(config.DB).PlayerChannel
-	user, err := u.Where(u.Playerid.Eq(userId)).Select(u.ChannelID).First()
-	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-		logrus.Errorf("GetUserChannel query user failed:%v", err)
-		return "0"
-	}
-
-	if user == nil {
-		logrus.Errorf("GetUserChannel 未查到玩家%v渠道ID..\n", userId)
-		return "0"
-	} else {
-		return user.ChannelID
-	}
-
-	//if user == nil {
-	//	userChannelMap[userId] = "0"
-	//} else {
-	//	userChannelMap[userId] = user.ChannelID
-	//}
-	//
-	//if len(userChannelMap) >= maxMapStoreLimit {
-	//	userChannelMap = make(map[int64]string, 0)
-	//}
-	//return userChannelMap[userId]
-}
-
-func GetUserStamp(userId int64) int32 {
-	if val, ok := userStampMap[userId]; ok {
-		return val
-	}
-	if userId == 0 {
-		return 0
-	}
-
-	var (
-		user *model.PlayerAttr
-		err  error
-	)
-
-	lock.RLock()
-	defer func() {
-		if len(userStampMap) > maxMapStoreLimit {
-			userStampMap = make(map[int64]int32)
-		}
-		lock.RUnlock()
-	}()
-
-	for _, DB := range config.GDBGroup {
-		u := query.Use(DB).PlayerAttr
-		user, err = u.Where(u.Playerid.Eq(userId)).Select(u.CreateTime).First()
-		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-			logrus.Errorf("GetUserStamp query user failed:%v", err)
-			return 0
-		}
-
-		if user == nil {
-			continue
-		} else {
-			userStampMap[userId] = int32(user.CreateTime.Unix())
-			break
-		}
-	}
-
-	if user == nil {
-		//userStampMap[userId] = 0
-		logrus.Errorf("GetUserStamp 未查到玩家注册时间..")
-		return 0
-	}
-
-	return userStampMap[userId]
-}
-
-// GetServerIDByUserId 通过玩家ID获取所在的数据库
-func GetServerIDByUserId(playerId int64) (serverID int32, err error) {
-	var models *model.PlayerAttr
-	for k, DB := range config.GDBGroup {
-		logrus.Warnf("GetDBByUserId DB:%+v", k)
-		var (
-			q = query.Use(DB).PlayerAttr
-			m = q.Where(q.Playerid.Eq(playerId))
-		)
-
-		if err = m.Scan(&models); err != nil {
-			return
-		}
-
-		logrus.Warnf("GetDBByUserId models:%+v", models)
-		if models != nil {
-			break
-		}
-	}
-
-	if models != nil {
-		return models.Line, nil
-	}
-
-	return 0, errors.New("用户不存在")
-}
-
-// GetAccIDByUserId 通过玩家ID获取accId
-func GetAccIDByUserId(playerId int64) (accID int64, err error) {
-	var models *model.PlayerAttr
-	for _, DB := range config.GDBGroup {
-		var (
-			q = query.Use(DB).PlayerAttr
-			m = q.Where(q.Playerid.Eq(playerId))
-		)
-
-		if err = m.Scan(&models); err != nil {
-			return
-		}
-
-		if models != nil {
-			break
-		}
-	}
-
-	if models != nil {
-		return models.AccID, nil
-	}
-
-	return 0, errors.New("用户不存在")
-}
-
-// GetAccIDByOpenId 通过openID获取accId
-func GetAccIDByOpenId(openID string) (accID int64, err error) {
-	var models *model.PlayerAttr
-	for _, DB := range config.GDBGroup {
-		var (
-			q = query.Use(DB).PlayerAttr
-			m = q.Where(q.OpenID.Eq(openID))
-		)
-
-		if err = m.Scan(&models); err != nil {
-			return
-		}
-
-		if models != nil {
-			break
-		}
-	}
-
-	if models != nil {
-		return models.AccID, nil
-	}
-
-	return 0, errors.New("用户不存在")
-}
-
-// GetAttrByUserId 通过User获取user attr
-func GetAttrByUserId(playerId int64) (attr *model.PlayerAttr, err error) {
-	var models *model.PlayerAttr
-	for _, DB := range config.GDBGroup {
-		var (
-			q = query.Use(DB).PlayerAttr
-			m = q.Where(q.Playerid.Eq(playerId))
-		)
-
-		if err = m.Scan(&models); err != nil {
-			return
-		}
-
-		if models != nil {
-			break
-		}
-	}
-
-	if models != nil {
-		return models, nil
-	}
-
-	return nil, errors.New("用户不存在")
-}
-
-func GetAccountByAccId(accId int64) (account *model.UserAccount, err error) {
-	var models *model.UserAccount
-	q := config.LDB.Scopes(model.UserAccountTable(models, accId)).Where("accId = ?", accId)
-	if err := q.Scan(&models).Error; err != nil {
-		return nil, err
-	}
-	if models != nil {
-		return models, nil
-	}
-	return nil, errors.New("账号不存在")
-}
-
-// GetDBByUserId 通过玩家ID获取所在的数据库
-func GetDBByUserId(playerId int64) (Db int, err error) {
-	serverID, err := GetServerIDByUserId(playerId)
-	if err != nil {
-		return 0, err
-	}
-
-	if serverID > 0 {
-		return GetDBByServerID(int(serverID))
-	}
-
-	return 0, errors.New("用户不存在")
-}
-
-// GetDBByServerID 通过serverID获取数据库
-func GetDBByServerID(serverID int) (int, error) {
-	// 目前serverId 和db是对应关系,后面如果不是可以在这里做处理
-	return serverID, nil
-}
-
-// GetDBByPlayerAttr 通过用户信息获取数据库(兼容合服)
-func GetDBByPlayerAttr(playerAttr *model.PlayerAttr) (int, error) {
-	// 目前serverId 和db是对应关系,后面如果不是可以在这里做处理
-	return int(playerAttr.Line), nil
-}
-
-func GetUserFlag(serverID int, userId int64) int32 {
-	u := query.Use(config.GDBGroup[serverID]).PlayerAttr
-	user, err := u.Where(u.Playerid.Eq(userId)).Select(u.Flag).First()
-	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-		logrus.Errorf("GetUserFlag query user failed:%v", err)
-		return 0
-	}
-
-	if user == nil {
-		return consts.UserFlagOld
-	} else {
-		return user.Flag
-	}
-}

+ 0 - 98
server/utility/token/token.go

@@ -1,8 +1,6 @@
 package token
 
 import (
-	"errors"
-	"gadmin/config"
 	"github.com/dgrijalva/jwt-go"
 	"github.com/gin-gonic/gin"
 	"github.com/google/uuid"
@@ -27,61 +25,6 @@ var (
 	effectTime = 30 * 24 * time.Hour // 30天有效期
 )
 
-func GenerateToken(claims *UserClaims) (token string, err error) {
-	claims.ExpiresAt = time.Now().Add(effectTime).Unix()
-	sign, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(secret)
-	if err != nil {
-		return "", err
-	}
-	return sign, nil
-}
-
-func ParseToken(tokenString string) (claims *UserClaims, err error) {
-	token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
-		return secret, nil
-	})
-	if err != nil {
-		return nil, err
-	}
-	claims, ok := token.Claims.(*UserClaims)
-	if !ok {
-		return nil, errors.New("token is valid")
-	}
-	return claims, nil
-}
-
-func Refresh(tokenString string) (t string, err error) {
-	jwt.TimeFunc = func() time.Time {
-		return time.Unix(0, 0)
-	}
-	token, err := jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
-		return secret, nil
-	})
-	if err != nil {
-		return "", err
-	}
-	claims, ok := token.Claims.(*UserClaims)
-	if !ok {
-		return "", errors.New("token is valid")
-	}
-	jwt.TimeFunc = time.Now
-	claims.StandardClaims.ExpiresAt = time.Now().Add(effectTime).Unix()
-	return GenerateToken(claims)
-}
-
-func Layout(tokenString string) (err error) {
-	jwt.TimeFunc = func() time.Time {
-		return time.Unix(0, 0)
-	}
-	_, err = jwt.ParseWithClaims(tokenString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
-		return secret, nil
-	})
-	if err != nil {
-		return err
-	}
-	return
-}
-
 func GetAuthorization(c *gin.Context) (t string) {
 	t = c.GetHeader("authorization")
 	if t == "" {
@@ -109,47 +52,6 @@ func GetUID(c *gin.Context) int64 {
 	return user.ID
 }
 
-func GetUserName(c *gin.Context) string {
-	user := CurrentUser(c)
-	if user == nil {
-		return `游客`
-	}
-	return user.UserName
-}
-
-func GetSystemId(c *gin.Context) int32 {
-	user := CurrentUser(c)
-	if user == nil {
-		return 0
-	}
-	return user.SystemId
-}
-
-func SetSystemId(c *gin.Context, systemId int32) (string, error) {
-	t := GetAuthorization(c)
-	user, err := ParseToken(t)
-	if err != nil {
-		return "", err
-	}
-	err = Layout(t)
-	if err != nil {
-		return "", err
-	}
-	user.SystemId = systemId
-
-	jwt.TimeFunc = time.Now
-	user.StandardClaims.ExpiresAt = time.Now().Add(effectTime).Unix()
-	t, err = GenerateToken(user)
-	if err != nil {
-		return "", err
-	}
-	// 记录登录token
-	key := config.GetUserTokenKey(user.ID)
-	config.TokenRedis.HSet(key, t, time.Now().Unix())
-	config.TokenRedis.Expire(key, config.TokenExpireTime)
-	return t, nil
-}
-
 func GenerateTokenUsingUUID() string {
 	return uuid.New().String()
 }

+ 10 - 4
web/src/views/permission/role/role.vue

@@ -112,7 +112,7 @@
                         class="checkbox-container"
                       >
                         <n-checkbox
-                          v-for="option in optionsPermissions"
+                          v-for="option in optionsPermissions[item.id]"
                           :key="option.value"
                           :value="option.value"
                           :label="option.label"
@@ -231,19 +231,25 @@
 
   // 检查是否全部选中
   const isAllChecked = (id) => {
-    return permissions.value[id]?.length === optionsPermissions.value.length;
+    let totalCount = 0;
+    if (optionsPermissions.value[id]) {
+      totalCount = optionsPermissions.value[id].length;
+    }
+    return permissions.value[id]?.length === totalCount;
   };
 
   // 检查是否是部分选中(不确定状态)
   const isIndeterminate = (id) => {
     const selectedCount = permissions.value[id]?.length || 0;
-    return selectedCount > 0 && selectedCount < optionsPermissions.value.length;
+    return selectedCount > 0 && selectedCount < optionsPermissions.value[id].length;
   };
 
   // 处理全选/全不选
   const handleCheckAll = (checked, sysId) => {
+    console.log(checked, sysId);
     if (checked) {
-      permissions.value[sysId] = optionsPermissions.value.map((opt) => opt.value);
+      permissions.value[sysId] = optionsPermissions.value[sysId].map((opt) => opt.value);
+      console.log(permissions.value[sysId]);
       // formParams.value.permissions[sysId] = optionsPermissions.value.map((opt) => opt.value);
     } else {
       permissions.value[sysId] = [];