菜单路由动态加载
This commit is contained in:
parent
2993f28e59
commit
09a80bc7bc
|
@ -0,0 +1,17 @@
|
||||||
|
server:
|
||||||
|
port: 8001
|
||||||
|
datasource:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 3306
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
database: d2admin
|
||||||
|
redis:
|
||||||
|
host: 127.0.0.1
|
||||||
|
port: 6379
|
||||||
|
password: 123456
|
||||||
|
database: 1
|
||||||
|
pool:
|
||||||
|
size: 1024
|
||||||
|
jwt:
|
||||||
|
secret: 123456
|
|
@ -1,2 +1,2 @@
|
||||||
active: dev
|
active: macDev
|
||||||
debug: true
|
debug: true
|
|
@ -55,7 +55,7 @@ func RunServer() {
|
||||||
apiGroup := r.Group("/api/v1")
|
apiGroup := r.Group("/api/v1")
|
||||||
apiGroup.Use(jwt.AuthMiddleware())
|
apiGroup.Use(jwt.AuthMiddleware())
|
||||||
{
|
{
|
||||||
routes := dao.ApiDao{}.GetAllRouter()
|
routes := dao.ApiDao{}.GetAllApi()
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if route.ApiMethod == "GET" {
|
if route.ApiMethod == "GET" {
|
||||||
apiGroup.GET(route.ApiPath, InnerRouters[route.ApiName])
|
apiGroup.GET(route.ApiPath, InnerRouters[route.ApiName])
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
type ApiDao struct {
|
type ApiDao struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ApiDao) GetAllRouter() []domain.Api {
|
func (ApiDao) GetAllApi() []domain.Api {
|
||||||
var routers []domain.Api
|
var apis []domain.Api
|
||||||
// select * from system_router where router_status = 1
|
// select * from system_api where api_status = 1
|
||||||
database.DB.Model(domain.Api{ApiStatus: 1}).Find(&routers)
|
database.DB.Model(domain.Api{ApiStatus: 1}).Find(&apis)
|
||||||
return routers
|
return apis
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package dao
|
||||||
|
|
||||||
|
import (
|
||||||
|
"d2-admin-service/src/infra/database"
|
||||||
|
"d2-admin-service/src/modules/system/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
type MenuDao struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (MenuDao) GetAllMenu() []domain.Menu {
|
||||||
|
var menus []domain.Menu
|
||||||
|
// select * from system_menu
|
||||||
|
database.DB.Find(&menus)
|
||||||
|
return menus
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ type Api struct {
|
||||||
ApiPath string `gorm:"not null;unique_index:index_npm"` // 接口路径, 例如: /api/v1/getUser
|
ApiPath string `gorm:"not null;unique_index:index_npm"` // 接口路径, 例如: /api/v1/getUser
|
||||||
ApiMethod string `gorm:"not null;unique_index:index_npm"` // GET、POST
|
ApiMethod string `gorm:"not null;unique_index:index_npm"` // GET、POST
|
||||||
ApiDesc string `gorm:"not null"` // 接口说明
|
ApiDesc string `gorm:"not null"` // 接口说明
|
||||||
ApiStatus int `gorm:"not null"` // 接口是否可用
|
ApiStatus uint `gorm:"not null"` // 接口是否可用
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Api) TableName() string {
|
func (Api) TableName() string {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package dto
|
||||||
|
|
||||||
|
type MenuItem struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
MenuParentId uint `json:"menuParentId"`
|
||||||
|
MenuTitle string `json:"menuTitle"`
|
||||||
|
MenuIcon string `json:"menuIcon"`
|
||||||
|
MenuPath string `json:"menuPath"`
|
||||||
|
RouterPath string `json:"routerPath"`
|
||||||
|
RouterName string `json:"routerName"`
|
||||||
|
RouterAuth uint `json:"routerAuth"`
|
||||||
|
RouterHidden uint `json:"routerHidden"`
|
||||||
|
RouterComponentPath string `json:"routerComponentPath"`
|
||||||
|
Children []*MenuItem `json:"children"` // 子菜单项
|
||||||
|
}
|
|
@ -4,15 +4,15 @@ import "github.com/jinzhu/gorm"
|
||||||
|
|
||||||
type Menu struct {
|
type Menu struct {
|
||||||
gorm.Model
|
gorm.Model
|
||||||
MenuParentId int `gorm:"null"`
|
MenuParentId uint `gorm:"null" json:"menuParentId"`
|
||||||
MenuTitle string `gorm:"not null"`
|
MenuTitle string `gorm:"not null" json:"menuTitle"`
|
||||||
MenuIcon string `gorm:"not null;default:''"`
|
MenuIcon string `gorm:"not null;default:''" json:"menuIcon"`
|
||||||
MenuPath string `gorm:"not null"`
|
MenuPath string `gorm:"not null" json:"menuPath"`
|
||||||
RouterPath string `gorm:"not null"`
|
RouterPath string `gorm:"not null" json:"routerPath"`
|
||||||
RouterName string `gorm:"not null"`
|
RouterName string `gorm:"not null" json:"routerName"`
|
||||||
RouterAuth int `gorm:"not null"`
|
RouterAuth uint `gorm:"not null" json:"routerAuth"`
|
||||||
RouterHidden int `gorm:"not null"`
|
RouterHidden uint `gorm:"not null" json:"routerHidden"`
|
||||||
RouterComponentPath string `gorm:"not null"`
|
RouterComponentPath string `gorm:"not null" json:"routerComponentPath"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Menu) TableName() string {
|
func (Menu) TableName() string {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"d2-admin-service/src/infra/redistool"
|
"d2-admin-service/src/infra/redistool"
|
||||||
"d2-admin-service/src/infra/resp"
|
"d2-admin-service/src/infra/resp"
|
||||||
"d2-admin-service/src/modules/system/dao"
|
"d2-admin-service/src/modules/system/dao"
|
||||||
"d2-admin-service/src/modules/system/rest/dto"
|
dto2 "d2-admin-service/src/modules/system/domain/dto"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
@ -21,7 +21,7 @@ func (AuthController) Login(c *gin.Context) {
|
||||||
userDao := dao.UserDao{}
|
userDao := dao.UserDao{}
|
||||||
|
|
||||||
// 声明接收的变量
|
// 声明接收的变量
|
||||||
var json dto.LoginDTO
|
var json dto2.LoginDTO
|
||||||
// 将request的body中的数据,自动按照json格式解析到结构体
|
// 将request的body中的数据,自动按照json格式解析到结构体
|
||||||
if err := c.ShouldBindJSON(&json); err != nil {
|
if err := c.ShouldBindJSON(&json); err != nil {
|
||||||
c.JSON(http.StatusBadRequest, resp.ResolveParamsError)
|
c.JSON(http.StatusBadRequest, resp.ResolveParamsError)
|
||||||
|
@ -62,7 +62,7 @@ func (AuthController) KickOut(c *gin.Context) {
|
||||||
c.JSON(http.StatusBadRequest, resp.NoOperationPermissionError)
|
c.JSON(http.StatusBadRequest, resp.NoOperationPermissionError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var json dto.KickOutDTO
|
var json dto2.KickOutDTO
|
||||||
if err := c.ShouldBindJSON(&json); err != nil {
|
if err := c.ShouldBindJSON(&json); err != nil {
|
||||||
c.JSON(http.StatusBadRequest, resp.ResolveParamsError)
|
c.JSON(http.StatusBadRequest, resp.ResolveParamsError)
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,11 +1,98 @@
|
||||||
package rest
|
package rest
|
||||||
|
|
||||||
import "github.com/gin-gonic/gin"
|
import (
|
||||||
|
"d2-admin-service/src/infra/resp"
|
||||||
|
"d2-admin-service/src/modules/system/dao"
|
||||||
|
"d2-admin-service/src/modules/system/domain/dto"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
type MenuController struct {
|
type MenuController struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (MenuController) TreeMenu(c *gin.Context) {}
|
func (MenuController) TreeMenu(c *gin.Context) {
|
||||||
|
menuDao := dao.MenuDao{}
|
||||||
|
menus := menuDao.GetAllMenu()
|
||||||
|
|
||||||
|
var newMenus []dto.MenuItem
|
||||||
|
for _, menu := range menus {
|
||||||
|
menuItem := dto.MenuItem{}
|
||||||
|
menuItem.ID = menu.ID
|
||||||
|
menuItem.MenuParentId = menu.MenuParentId
|
||||||
|
menuItem.MenuTitle = menu.MenuTitle
|
||||||
|
menuItem.MenuIcon = menu.MenuIcon
|
||||||
|
menuItem.MenuPath = menu.MenuPath
|
||||||
|
menuItem.RouterAuth = menu.RouterAuth
|
||||||
|
menuItem.RouterHidden = menu.RouterHidden
|
||||||
|
menuItem.RouterName = menu.RouterName
|
||||||
|
menuItem.RouterPath = menu.RouterPath
|
||||||
|
menuItem.RouterComponentPath = menu.RouterComponentPath
|
||||||
|
newMenus = append(newMenus, menuItem)
|
||||||
|
}
|
||||||
|
c.JSON(http.StatusOK, resp.Success(buildTree(newMenus)))
|
||||||
|
}
|
||||||
func (MenuController) CreateMenu(c *gin.Context) {}
|
func (MenuController) CreateMenu(c *gin.Context) {}
|
||||||
func (MenuController) DeleteMenu(c *gin.Context) {}
|
func (MenuController) DeleteMenu(c *gin.Context) {}
|
||||||
func (MenuController) ModifyMenu(c *gin.Context) {}
|
func (MenuController) ModifyMenu(c *gin.Context) {}
|
||||||
|
|
||||||
|
// 递归构建无限级树结构
|
||||||
|
func buildTree(menuItems []dto.MenuItem) []*dto.MenuItem {
|
||||||
|
var rootNodes []*dto.MenuItem
|
||||||
|
|
||||||
|
for _, item := range menuItems {
|
||||||
|
if item.MenuParentId == 0 { // 根节点
|
||||||
|
rootNodes = append(rootNodes, &item)
|
||||||
|
} else {
|
||||||
|
// 查找并插入到相应父节点的子菜单中
|
||||||
|
insertIntoParent(&item, menuItems)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对每个根节点进行递归处理其子节点
|
||||||
|
for i := range rootNodes {
|
||||||
|
rootNodes[i].Children = buildChildren(rootNodes[i], menuItems)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootNodes
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将一个菜单项插入到其父节点的子菜单列表中(如果父节点已存在于菜单列表中)
|
||||||
|
func insertIntoParent(item *dto.MenuItem, menuItems []dto.MenuItem) {
|
||||||
|
for i := range menuItems {
|
||||||
|
if menuItems[i].ID == item.MenuParentId {
|
||||||
|
menuItems[i].Children = append(menuItems[i].Children, item)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 递归构建某个节点的所有子节点
|
||||||
|
func buildChildren(parent *dto.MenuItem, menuItems []dto.MenuItem) []*dto.MenuItem {
|
||||||
|
var children []*dto.MenuItem
|
||||||
|
processedIds := make(map[uint]bool)
|
||||||
|
|
||||||
|
for _, item := range menuItems {
|
||||||
|
if item.MenuParentId == parent.ID && !processedIds[item.ID] { // 防止重复和无限递归
|
||||||
|
child := item
|
||||||
|
processedIds[child.ID] = true // 标记为已处理
|
||||||
|
|
||||||
|
// 使用剩余未处理的菜单项构建子节点
|
||||||
|
child.Children = buildChildren(&child, filterUnprocessed(menuItems, processedIds)) // 递归处理子节点
|
||||||
|
children = append(children, &child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建一个新的切片,其中不包含已处理过的菜单项
|
||||||
|
func filterUnprocessed(menuItems []dto.MenuItem, processedIds map[uint]bool) []dto.MenuItem {
|
||||||
|
var unprocessedItems []dto.MenuItem
|
||||||
|
for _, item := range menuItems {
|
||||||
|
if !processedIds[item.ID] {
|
||||||
|
unprocessedItems = append(unprocessedItems, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unprocessedItems
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
export default ({ service, request, tools }) => ({
|
export default ({ service, request, tools }) => ({
|
||||||
/**
|
/**
|
||||||
* @description 登录
|
* @description 获取所有菜单
|
||||||
* @param {Object} data 登录携带的信息
|
|
||||||
*/
|
*/
|
||||||
login (data = {}) {
|
queryAllMenus (data = {}) {
|
||||||
// 接口请求
|
// 接口请求
|
||||||
return request({
|
return request({
|
||||||
url: '/login',
|
url: '/queryAllMenus',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data
|
data
|
||||||
})
|
})
|
|
@ -74,7 +74,7 @@ const frameIn = [
|
||||||
auth: true
|
auth: true
|
||||||
},
|
},
|
||||||
component: _import('demo/page3')
|
component: _import('demo/page3')
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -27,7 +27,7 @@ export default {
|
||||||
util.cookies.set('username', res.username)
|
util.cookies.set('username', res.username)
|
||||||
util.cookies.set('name', res.name)
|
util.cookies.set('name', res.name)
|
||||||
util.cookies.set('token', res.token)
|
util.cookies.set('token', res.token)
|
||||||
console.log("=============== 设置用户token")
|
console.log('=============== 设置用户token')
|
||||||
// 设置 vuex 用户信息
|
// 设置 vuex 用户信息
|
||||||
await dispatch('d2admin/user/set', { name: res.name }, { root: true })
|
await dispatch('d2admin/user/set', { name: res.name }, { root: true })
|
||||||
// 用户登录后从持久化数据加载一系列的设置
|
// 用户登录后从持久化数据加载一系列的设置
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default {
|
||||||
value: info,
|
value: info,
|
||||||
user: true
|
user: true
|
||||||
}, { root: true })
|
}, { root: true })
|
||||||
console.log("================ 配置用户信息")
|
console.log('================ 配置用户信息')
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* @description 从数据库取用户数据
|
* @description 从数据库取用户数据
|
||||||
|
|
Loading…
Reference in New Issue