diff --git a/app/enum/enum_admin.go b/app/enum/enum_admin.go
new file mode 100644
index 0000000..e69c56d
--- /dev/null
+++ b/app/enum/enum_admin.go
@@ -0,0 +1,37 @@
+package enum
+
+type AdminState int32
+
+const (
+	AdminStateForNormal = 1
+	AdminStateForFreeze = 2
+)
+
+func (gt AdminState) String() string {
+	switch gt {
+	case AdminStateForNormal:
+		return "正常"
+	case AdminStateForFreeze:
+		return "冻结"
+	default:
+		return "未知"
+	}
+}
+
+type IsSuperAdministrator int32
+
+const (
+	IsSuperAdministratorTure  = 1
+	IsSuperAdministratorFalse = 2
+)
+
+func (gt IsSuperAdministrator) String() string {
+	switch gt {
+	case IsSuperAdministratorTure:
+		return "超管"
+	case IsSuperAdministratorFalse:
+		return "非超管"
+	default:
+		return "未知"
+	}
+}
diff --git a/app/enum/enum_permission_group.go b/app/enum/enum_permission_group.go
new file mode 100644
index 0000000..eda844a
--- /dev/null
+++ b/app/enum/enum_permission_group.go
@@ -0,0 +1,19 @@
+package enum
+
+type PermissionGroupState int32
+
+const (
+	PermissionGroupStateForNormal  = 1
+	PermissionGroupStateForDiscard = 2
+)
+
+func (gt PermissionGroupState) String() string {
+	switch gt {
+	case PermissionGroupStateForNormal:
+		return "正常"
+	case PermissionGroupStateForDiscard:
+		return "废弃"
+	default:
+		return "未知"
+	}
+}
diff --git a/app/hdl/comm/hdl_comm.go b/app/hdl/comm/hdl_comm.go
new file mode 100644
index 0000000..3461031
--- /dev/null
+++ b/app/hdl/comm/hdl_comm.go
@@ -0,0 +1,108 @@
+package comm
+
+import (
+	"applet/app/db"
+	"applet/app/e"
+	"applet/app/enum"
+	"applet/app/md"
+	"applet/app/svc"
+	"applet/app/utils"
+	"code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
+	"github.com/gin-gonic/gin"
+)
+
+func MenuList(c *gin.Context) {
+	engine := db.Db
+	admin := svc.GetUser(c)
+	qrcodeWithBatchRecordsDb := implement.NewPermissionGroupDb(engine)
+	groupList, err := qrcodeWithBatchRecordsDb.FindPermissionGroupV2()
+	if err != nil {
+		e.OutErr(c, e.ERR_DB_ORM, err.Error())
+		return
+	}
+
+	// 1、查询出当前用户所有角色
+	adminRoleDb := implement.NewAdminRoleDb(engine)
+	roles, err := adminRoleDb.FindAdminRole(admin.AdmId)
+	if err != nil {
+		e.OutErr(c, e.ERR_DB_ORM, err.Error())
+		return
+	}
+
+	roleDb := implement.NewRoleDb(engine, 0)
+	var adminHasPermissionGroupIds []string
+	for _, v := range *roles {
+		list, _, err1 := roleDb.FindPermissionGroupByRole(v.RoleId)
+		if err1 != nil {
+			e.OutErr(c, e.ERR_DB_ORM, err1.Error())
+			return
+		}
+		for _, v1 := range list {
+			adminHasPermissionGroupIds = append(adminHasPermissionGroupIds, utils.IntToStr(v1.PermissionGroup.Id))
+		}
+	}
+
+	var tempRespMap = map[string]*md.PermissionGroupListResp{}
+	var tempRespMapKeys []string
+	for _, v := range *groupList {
+
+		var isCheck bool
+		if admin.IsSuperAdministrator == enum.IsSuperAdministratorTure {
+			isCheck = true
+		} else {
+			isCheck = false
+		}
+
+		if utils.InArr(utils.IntToStr(v.Id), adminHasPermissionGroupIds) {
+			isCheck = true
+		}
+
+		if v.State == enum.PermissionGroupStateForDiscard {
+			isCheck = false
+		}
+
+		tempRespMap[utils.IntToStr(v.Id)] = &md.PermissionGroupListResp{
+			Id:       v.Id,
+			Name:     v.Name,
+			Key:      v.Key,
+			State:    v.State,
+			ParentId: v.ParentId,
+			CreateAt: v.CreateAt,
+			UpdateAt: v.UpdateAt,
+			IsCheck:  isCheck,
+		}
+		tempRespMapKeys = append(tempRespMapKeys, utils.IntToStr(v.Id))
+	}
+	for _, v := range tempRespMap {
+		if v.ParentId != 0 && tempRespMap[utils.IntToStr(v.ParentId)].ParentId != 0 {
+			tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList = append(tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList, *v)
+		}
+	}
+	for _, v := range tempRespMap {
+		if v.ParentId != 0 && tempRespMap[utils.IntToStr(v.ParentId)].ParentId == 0 {
+			tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList = append(tempRespMap[utils.IntToStr(v.ParentId)].SubPermissionGroupList, *v)
+		}
+	}
+
+	var resp []*md.PermissionGroupListResp
+	for _, v := range tempRespMapKeys {
+		if tempRespMap[v].ParentId == 0 {
+			resp = append(resp, tempRespMap[v])
+		}
+	}
+
+	e.OutSuc(c, map[string]interface{}{
+		"list": resp,
+		"state": []map[string]interface{}{
+			{
+				"name":  enum.PermissionGroupState(enum.PermissionGroupStateForNormal).String(),
+				"value": enum.PermissionGroupStateForNormal,
+			},
+			{
+				"name":  enum.PermissionGroupState(enum.PermissionGroupStateForDiscard).String(),
+				"value": enum.PermissionGroupStateForDiscard,
+			},
+		},
+	}, nil)
+	return
+}
diff --git a/app/md/app_redis_key.go b/app/md/app_redis_key.go
index 7bf090c..fb85fa6 100644
--- a/app/md/app_redis_key.go
+++ b/app/md/app_redis_key.go
@@ -9,4 +9,8 @@ const (
 	AppCfgCacheKey = "cfg_cache:%s" // 占位符: key的第一个字母
 
 	CfgCacheTime = 86400
+
+	AdminRolePermissionKey = "egg_admin_role_permission:%s" // 占位符:admin:id
+
+	AdminRolePermissionCacheTime = 3600 * 24 * 0.5
 )
diff --git a/app/md/md_role.go b/app/md/md_role.go
new file mode 100644
index 0000000..5e8c173
--- /dev/null
+++ b/app/md/md_role.go
@@ -0,0 +1,99 @@
+package md
+
+import (
+	"code.fnuoos.com/EggPlanet/egg_models.git/src/model"
+)
+
+type RoleListResp struct {
+	Data      model.Role `json:"data"`
+	AdminList []struct {
+		Name string `json:"name"`
+	} `json:"admin_list"`
+}
+
+type UpdateRoleStateReq struct {
+	RoleId int `json:"role_id" binding:"required" label:"id"`
+	State  int `json:"state" binding:"required" label:"状态"`
+}
+
+type AddRoleReq struct {
+	Name     string `json:"name" binding:"required" label:"名称"`
+	Memo     string `json:"memo" binding:"required" label:"备注"`
+	Logo     string `json:"logo"  label:"左边图标"`
+	Label    string `json:"label"  label:"身份标签"`
+	SeoLogo  string `json:"seo_logo"  label:"seo"`
+	SeoTitle string `json:"seo_title"  label:"seo"`
+}
+
+type UpdateRoleReq struct {
+	RoleId   int    `json:"role_id" binding:"required" label:"id"`
+	Name     string `json:"name" binding:"required" label:"名称"`
+	Memo     string `json:"memo" binding:"required" label:"备注"`
+	Logo     string `json:"logo"  label:"左边图标"`
+	Label    string `json:"label"  label:"身份标签"`
+	SeoLogo  string `json:"seo_logo"  label:"seo"`
+	SeoTitle string `json:"seo_title"  label:"seo"`
+}
+
+type RoleBindPermissionGroupReq struct {
+	RoleId        int   `json:"role_id" binding:"required" label:"id"`
+	PermissionIds []int `json:"permission_ids" label:"权限组id"`
+}
+
+type PermissionGroupListResp struct {
+	Id                     int                       `json:"id"`
+	Name                   string                    `json:"name"` //菜单名称
+	Key                    string                    `json:"key"`  //唯一标识符
+	State                  int                       `json:"state"`
+	ParentId               int                       `json:"parent_id"` //父级id,为0则代表没有父级
+	CreateAt               string                    `json:"create_at"`
+	UpdateAt               string                    `json:"update_at"`
+	IsCheck                bool                      `json:"is_check"`                  //是否用用
+	SubPermissionGroupList []PermissionGroupListResp `json:"sub_permission_group_list"` //子集菜单
+}
+
+type AdminListReq struct {
+	Limit    int    `json:"limit"`
+	Page     int    `json:"page" `
+	UserName string `json:"username"`
+	State    int    `json:"state"`
+}
+
+type AdminListResp struct {
+	AdmId                int      `json:"adm_id"`
+	Username             string   `json:"username"`
+	State                int      `json:"state"`
+	IsSuperAdministrator int      `json:"is_super_administrator"`
+	Memo                 string   `json:"memo"`
+	CreateAt             string   `json:"create_at"`
+	UpdateAt             string   `json:"update_at"`
+	RoleList             []string `json:"role_list"`
+}
+
+type UpdateAdminStateReq struct {
+	AdmId int `json:"adm_id" binding:"required" label:"管理员id"`
+	State int `json:"state" binding:"required" label:"状态"`
+}
+
+type AddAdminReq struct {
+	Username string `json:"username" binding:"required" label:"名称"`
+	Password string `json:"password" binding:"required" label:"密码"`
+	Memo     string `json:"memo"  label:"备注"`
+}
+
+type UpdateAdminReq struct {
+	AdmId    int    `json:"adm_id" binding:"required" label:"管理员id"`
+	Username string `json:"username" binding:"required" label:"名称"`
+	Password string `json:"password" binding:"required" label:"密码"`
+	Memo     string `json:"memo"  label:"备注"`
+}
+
+type BindAdminRoleReq struct {
+	AdmId   int   `json:"adm_id" binding:"required" label:"管理员id"`
+	RoleIds []int `json:"role_ids" label:"角色id"`
+}
+
+type BindAdminWithEnterpriseReq struct {
+	AdmId int   `json:"adm_id" binding:"required" label:"管理员id"`
+	Ids   []int `json:"ids" label:"记录id"`
+}
diff --git a/app/md/md_white_uri.go b/app/md/md_white_uri.go
new file mode 100644
index 0000000..b5c54d7
--- /dev/null
+++ b/app/md/md_white_uri.go
@@ -0,0 +1,5 @@
+package md
+
+var WhiteUri = []string{
+	"/api/admin/comm/getMenuList",
+}
diff --git a/app/mw/mw_admin_permission.go b/app/mw/mw_admin_permission.go
new file mode 100644
index 0000000..4165ee6
--- /dev/null
+++ b/app/mw/mw_admin_permission.go
@@ -0,0 +1,33 @@
+package mw
+
+import (
+	"applet/app/e"
+	"applet/app/enum"
+	"applet/app/md"
+	"applet/app/svc"
+	"applet/app/utils"
+	"fmt"
+	"github.com/gin-gonic/gin"
+)
+
+// CheckPermission 检查权限
+func CheckPermission(c *gin.Context) {
+	admin := svc.GetUser(c)
+
+	// TODO::判断是否为超管
+	if admin.IsSuperAdministrator == enum.IsSuperAdministratorTure {
+		c.Next()
+	} else {
+		rolePermissionKey := fmt.Sprintf(md.AdminRolePermissionKey, utils.AnyToString(admin.AdmId))
+		isHasPermission, err := svc.CheckUserRole(c, rolePermissionKey, c.Request.RequestURI, admin.AdmId)
+		if err != nil {
+			e.OutErr(c, e.ERR, err.Error())
+			return
+		}
+		if !isHasPermission {
+			e.OutErr(c, e.ERR_FORBIDEN, "当前用户暂未拥有该路由权限,请联系管理员")
+			return
+		}
+		c.Next()
+	}
+}
diff --git a/app/mw/mw_cors.go b/app/mw/mw_cors.go
index 3433553..1151639 100644
--- a/app/mw/mw_cors.go
+++ b/app/mw/mw_cors.go
@@ -4,7 +4,7 @@ import (
 	"github.com/gin-gonic/gin"
 )
 
-// cors跨域
+// Cors 跨域
 func Cors(c *gin.Context) {
 	// 放行所有OPTIONS方法
 	if c.Request.Method == "OPTIONS" {
diff --git a/app/mw/mw_limiter.go b/app/mw/mw_limiter.go
index 4eb5299..7171002 100644
--- a/app/mw/mw_limiter.go
+++ b/app/mw/mw_limiter.go
@@ -10,7 +10,7 @@ import (
 	"applet/app/utils/cache"
 )
 
-// 限流器
+// Limiter 限流器
 func Limiter(c *gin.Context) {
 	limit := 100 // 限流次数
 	ttl := 1     // 限流过期时间
diff --git a/app/router/router.go b/app/router/router.go
index a34b248..1a4e675 100644
--- a/app/router/router.go
+++ b/app/router/router.go
@@ -3,6 +3,7 @@ package router
 import (
 	"applet/app/cfg"
 	"applet/app/hdl"
+	"applet/app/hdl/comm"
 	"applet/app/hdl/institutional_management/public_platoon"
 	"applet/app/mw"
 	_ "applet/docs"
@@ -49,9 +50,10 @@ func Init() *gin.Engine {
 func route(r *gin.RouterGroup) {
 	r.GET("/test", hdl.Demo)
 	r.POST("/login", hdl.Login)
-	rInstitutionalManagement(r.Group("/institutionalManagement"))
 	r.Use(mw.Auth) // 以下接口需要JWT验证
-
+	rComm(r.Group("/comm"))
+	r.Use(mw.CheckPermission) // 检测权限
+	rInstitutionalManagement(r.Group("/institutionalManagement"))
 }
 
 func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理
@@ -60,3 +62,7 @@ func rInstitutionalManagement(r *gin.RouterGroup) { //制度管理
 		rPublicPlatoon.GET("/getBasic", public_platoon.GetPublicPlatoonBasic)
 	}
 }
+
+func rComm(r *gin.RouterGroup) {
+	r.POST("/getMenuList", comm.MenuList) // 获取菜单栏列表
+}
diff --git a/app/svc/svc_role.go b/app/svc/svc_role.go
new file mode 100644
index 0000000..3e3f8e6
--- /dev/null
+++ b/app/svc/svc_role.go
@@ -0,0 +1,195 @@
+package svc
+
+import (
+	"applet/app/db"
+	"applet/app/md"
+	"applet/app/utils"
+	"applet/app/utils/cache"
+	"code.fnuoos.com/EggPlanet/egg_models.git/src/implement"
+	"code.fnuoos.com/EggPlanet/egg_models.git/src/model"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"regexp"
+	"strings"
+	"time"
+)
+
+func CheckUserRole(c *gin.Context, cacheKey, uri string, admId int) (isHasPermission bool, err error) {
+	uri = utils.UriFilterExcludeQueryString(uri) // 去除uri中?后的query参数
+	isHasPermission = false
+	var rolePermission []string
+	var rolePermissionString string
+	rolePermissionString, _ = cache.GetString(cacheKey)
+
+	// TODO::判断是否在白名单中
+	if utils.InArr(uri, md.WhiteUri) {
+		isHasPermission = true
+		return
+	}
+
+	if rolePermissionString != "" {
+		// if false {
+		if err = json.Unmarshal([]byte(rolePermissionString), &rolePermission); err != nil {
+			return
+		}
+	} else {
+		adminDb := implement.NewAdminDb(db.Db)
+		list, _, err1 := adminDb.GetAdminRolePermission(admId)
+		if err1 != nil {
+			return isHasPermission, err1
+		}
+		for _, v := range list {
+			rolePermission = append(rolePermission, v.Permission.Action)
+		}
+		marshal, err1 := json.Marshal(rolePermission)
+		if err1 != nil {
+			return isHasPermission, err1
+		}
+		rolePermissionString = string(marshal)
+		_, err = cache.SetEx(cacheKey, rolePermissionString, md.AdminRolePermissionCacheTime)
+	}
+
+	if utils.InArr(uri, rolePermission) {
+		isHasPermission = true
+	} else {
+		// 正则匹配占位符情况
+		compileRegex := regexp.MustCompile("[0-9]+")
+		matchArr := compileRegex.FindAllString(uri, -1)
+		if len(matchArr) > 0 {
+			uri = strings.Replace(uri, matchArr[len(matchArr)-1], ":id", 1)
+			if utils.InArr(uri, rolePermission) {
+				isHasPermission = true
+			}
+		}
+	}
+	return
+}
+
+func DeleteRole(c *gin.Context, roleId int) (err error) {
+	engine := db.Db
+	session := engine.NewSession()
+	defer session.Close()
+	session.Begin()
+
+	// 1、删除 `role`
+	roleDb := implement.NewRoleDb(engine, roleId)
+	_, err = roleDb.RoleDeleteBySession(session, roleId)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	// 2、删除 `role_permission_group`
+	rolePermissionGroupDb := implement.NewRolePermissionGroupDb(db.Db)
+	_, err = rolePermissionGroupDb.RolePermissionGroupDeleteForRoleBySession(session, roleId)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	// 3、删除 `admin_role`
+	adminRoleDb := implement.NewAdminRoleDb(db.Db)
+	_, err = adminRoleDb.AdminRoleDeleteForRoleBySession(session, roleId)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	return session.Commit()
+}
+
+func RoleBindPermissionGroup(c *gin.Context, req md.RoleBindPermissionGroupReq) (err error) {
+	engine := db.Db
+	session := engine.NewSession()
+	defer session.Close()
+	session.Begin()
+	// 1、查询 `role`
+	roleDb := implement.NewRoleDb(db.Db, req.RoleId)
+	role, err := roleDb.GetRole()
+	if err != nil {
+		return
+	}
+	if role == nil {
+		return errors.New("未查询到相应记录")
+	}
+
+	// 1、删除 `role_permission_group`
+	rolePermissionGroupDb := implement.NewRolePermissionGroupDb(db.Db)
+	_, err = rolePermissionGroupDb.RolePermissionGroupDeleteForRoleBySession(session, req.RoleId)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	// 2、新增 `role_permission_group``
+	var mm []*model.RolePermissionGroup
+	now := time.Now()
+	for _, v := range req.PermissionIds {
+		mm = append(mm, &model.RolePermissionGroup{
+			RoleId:   role.Id,
+			GroupId:  v,
+			CreateAt: now.Format("2006-01-02 15:04:05"),
+			UpdateAt: now.Format("2006-01-02 15:04:05"),
+		})
+	}
+	_, err = rolePermissionGroupDb.BatchAddRolePermissionGroupBySession(session, mm)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	session.Commit()
+	var data []model.AdminRole
+	engine.Where("role_id=?", role.Id).Find(&data)
+	for _, v := range data {
+		rolePermissionKey := fmt.Sprintf(md.AdminRolePermissionKey, utils.AnyToString(v.AdmId))
+		cache.Del(rolePermissionKey)
+	}
+	return nil
+}
+
+func BindAdminRole(c *gin.Context, req md.BindAdminRoleReq) (err error) {
+	engine := db.Db
+	session := engine.NewSession()
+	defer session.Close()
+	session.Begin()
+	// 1、查询 `role`
+	adminDb := implement.NewAdminDb(db.Db)
+	role, err := adminDb.GetAdmin(req.AdmId)
+	if err != nil {
+		return
+	}
+	if role == nil {
+		return errors.New("未查询到相应记录")
+	}
+
+	// 1、删除 `admin_role`
+	adminRoleDb := implement.NewAdminRoleDb(db.Db)
+	_, err = adminRoleDb.AdminRoleDeleteBySession(session, req.AdmId)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	// 2、新增 `删除 `admin_role``
+	var mm []*model.AdminRole
+	now := time.Now()
+	for _, v := range req.RoleIds {
+		mm = append(mm, &model.AdminRole{
+			AdmId:    req.AdmId,
+			RoleId:   v,
+			State:    1,
+			CreateAt: now.Format("2006-01-02 15:04:05"),
+			UpdateAt: now.Format("2006-01-02 15:04:05"),
+		})
+	}
+	_, err = adminRoleDb.BatchAddAdminRoleBySession(session, mm)
+	if err != nil {
+		_ = session.Rollback()
+		return
+	}
+
+	return session.Commit()
+}
diff --git a/app/utils/url.go b/app/utils/url.go
new file mode 100644
index 0000000..f0c7d6b
--- /dev/null
+++ b/app/utils/url.go
@@ -0,0 +1,16 @@
+package utils
+
+import (
+	"net/url"
+	"strings"
+)
+
+func UriFilterExcludeQueryString(uri string) string {
+	URL, _ := url.Parse(uri)
+
+	clearUri := strings.ReplaceAll(uri, URL.RawQuery, "")
+
+	clearUri = strings.TrimRight(clearUri, "?")
+
+	return strings.TrimRight(clearUri, "/")
+}