菜单接口
This commit is contained in:
353
features/sys_menu/api_sys_menu.go
Normal file
353
features/sys_menu/api_sys_menu.go
Normal file
@@ -0,0 +1,353 @@
|
||||
package sysmenu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"ems.agt/features/sys_menu/consts"
|
||||
"ems.agt/features/sys_menu/model"
|
||||
"ems.agt/features/sys_menu/service"
|
||||
"ems.agt/lib/core/conf"
|
||||
"ems.agt/lib/core/utils/ctx"
|
||||
"ems.agt/lib/core/utils/regular"
|
||||
"ems.agt/lib/core/vo/result"
|
||||
"ems.agt/lib/midware"
|
||||
"ems.agt/lib/services"
|
||||
"ems.agt/restagent/config"
|
||||
)
|
||||
|
||||
// 菜单接口添加到路由
|
||||
func Routers() []services.RouterItem {
|
||||
// 实例化控制层 SysMenuApi 结构体
|
||||
var apis = &SysMenuApi{
|
||||
sysMenuService: service.NewServiceSysMenu,
|
||||
}
|
||||
|
||||
rs := [...]services.RouterItem{
|
||||
{
|
||||
Method: "GET",
|
||||
Pattern: "/menuManage/{apiVersion}/list",
|
||||
Handler: apis.List,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:list"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "GET",
|
||||
Pattern: "/menuManage/{apiVersion}/info/{menuId}",
|
||||
Handler: apis.Info,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:query"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "POST",
|
||||
Pattern: "/menuManage/{apiVersion}/add",
|
||||
Handler: apis.Add,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:add"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "PUT",
|
||||
Pattern: "/menuManage/{apiVersion}/edit",
|
||||
Handler: apis.Edit,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:edit"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "DELETE",
|
||||
Pattern: "/menuManage/{apiVersion}/del/{menuId}",
|
||||
Handler: apis.Remove,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:edit"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "GET",
|
||||
Pattern: "/menuManage/{apiVersion}/treeSelect",
|
||||
Handler: apis.TreeSelect,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:list"},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Method: "GET",
|
||||
Pattern: "/menuManage/{apiVersion}/roleMenuTreeSelect/{roleId}",
|
||||
Handler: apis.RoleMenuTreeSelect,
|
||||
Middleware: midware.Authorize(map[string][]string{
|
||||
"hasPerms": {"system:menu:list"},
|
||||
}),
|
||||
},
|
||||
// 添加更多的 Router 对象...
|
||||
}
|
||||
|
||||
// 生成两组前缀路由
|
||||
rsPrefix := []services.RouterItem{}
|
||||
for _, v := range rs {
|
||||
path := v.Pattern
|
||||
// 固定前缀
|
||||
v.Pattern = config.DefaultUriPrefix + path
|
||||
rsPrefix = append(rsPrefix, v)
|
||||
// 可配置
|
||||
v.Pattern = config.UriPrefix + path
|
||||
rsPrefix = append(rsPrefix, v)
|
||||
}
|
||||
return rsPrefix
|
||||
}
|
||||
|
||||
// // 实例化控制层 SysMenuApi 结构体
|
||||
// var NewSysMenu = &SysMenuApi{
|
||||
// sysMenuService: NewServiceSysMenu,
|
||||
// }
|
||||
|
||||
// 菜单信息
|
||||
//
|
||||
// PATH /menuManage
|
||||
type SysMenuApi struct {
|
||||
// 菜单服务
|
||||
sysMenuService *service.ServiceSysMenu
|
||||
}
|
||||
|
||||
// 菜单列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysMenuApi) List(w http.ResponseWriter, r *http.Request) {
|
||||
query := model.SysMenu{}
|
||||
if v := ctx.GetQuery(r, "menuName"); v != "" {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v := ctx.GetQuery(r, "status"); v != "" {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(r)
|
||||
if conf.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuList(query, userId)
|
||||
ctx.JSON(w, 200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 菜单信息
|
||||
//
|
||||
// GET /:menuId
|
||||
func (s *SysMenuApi) Info(w http.ResponseWriter, r *http.Request) {
|
||||
menuId := ctx.Param(r, "menuId")
|
||||
if menuId == "" {
|
||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuById(menuId)
|
||||
if data.MenuID == menuId {
|
||||
ctx.JSON(w, 200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
ctx.JSON(w, 200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysMenuApi) Add(w http.ResponseWriter, r *http.Request) {
|
||||
var body model.SysMenu
|
||||
err := ctx.ShouldBindJSON(r, &body)
|
||||
if err != nil || body.MenuID != "" {
|
||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 目录和菜单检查地址唯一
|
||||
if consts.TYPE_DIR == body.MenuType || consts.TYPE_MENU == body.MenuType {
|
||||
uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, "")
|
||||
if !uniqueNenuPath {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,菜单路由地址已存在", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, "")
|
||||
if !uniqueNenuName {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,菜单名称已存在", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 外链菜单需要符合网站http(s)开头
|
||||
if body.IsFrame == "0" && !regular.ValidHttp(body.Path) {
|
||||
msg := fmt.Sprintf("菜单新增【%s】失败,非内部地址必须以http(s)://开头", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(r)
|
||||
insertId := s.sysMenuService.InsertMenu(body)
|
||||
if insertId != "" {
|
||||
ctx.JSON(w, 200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
ctx.JSON(w, 200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysMenuApi) Edit(w http.ResponseWriter, r *http.Request) {
|
||||
var body model.SysMenu
|
||||
err := ctx.ShouldBindJSON(r, &body)
|
||||
if err != nil || body.MenuID == "" {
|
||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级菜单不能选自己
|
||||
if body.MenuID == body.ParentID {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,上级菜单不能选择自己", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
menuInfo := s.sysMenuService.SelectMenuById(body.MenuID)
|
||||
if menuInfo.MenuID != body.MenuID {
|
||||
ctx.JSON(w, 200, result.ErrMsg("没有权限访问菜单数据"))
|
||||
return
|
||||
}
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
menuParent := s.sysMenuService.SelectMenuById(body.ParentID)
|
||||
if menuParent.MenuID != body.ParentID {
|
||||
ctx.JSON(w, 200, result.ErrMsg("没有权限访问菜单数据"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 目录和菜单检查地址唯一
|
||||
if consts.TYPE_DIR == body.MenuType || consts.TYPE_MENU == body.MenuType {
|
||||
uniqueNenuPath := s.sysMenuService.CheckUniqueMenuPath(body.Path, body.MenuID)
|
||||
if !uniqueNenuPath {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,菜单路由地址已存在", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查名称唯一
|
||||
uniqueNenuName := s.sysMenuService.CheckUniqueMenuName(body.MenuName, body.ParentID, body.MenuID)
|
||||
if !uniqueNenuName {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,菜单名称已存在", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 外链菜单需要符合网站http(s)开头
|
||||
if body.IsFrame == "0" && !regular.ValidHttp(body.Path) {
|
||||
msg := fmt.Sprintf("菜单修改【%s】失败,非内部地址必须以http(s)://开头", body.MenuName)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(r)
|
||||
rows := s.sysMenuService.UpdateMenu(body)
|
||||
if rows > 0 {
|
||||
ctx.JSON(w, 200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
ctx.JSON(w, 200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单删除
|
||||
//
|
||||
// DELETE /:menuId
|
||||
func (s *SysMenuApi) Remove(w http.ResponseWriter, r *http.Request) {
|
||||
menuId := ctx.Param(r, "menuId")
|
||||
if menuId == "" {
|
||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
menu := s.sysMenuService.SelectMenuById(menuId)
|
||||
if menu.MenuID != menuId {
|
||||
ctx.JSON(w, 200, result.ErrMsg("没有权限访问菜单数据!"))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在子菜单
|
||||
hasChild := s.sysMenuService.HasChildByMenuId(menuId)
|
||||
if hasChild > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,存在子菜单数:%d", hasChild)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否分配给角色
|
||||
existRole := s.sysMenuService.CheckMenuExistRole(menuId)
|
||||
if existRole > 0 {
|
||||
msg := fmt.Sprintf("不允许删除,菜单已分配给角色数:%d", existRole)
|
||||
ctx.JSON(w, 200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
rows := s.sysMenuService.DeleteMenuById(menuId)
|
||||
if rows > 0 {
|
||||
msg := fmt.Sprintf("删除成功:%d", rows)
|
||||
ctx.JSON(w, 200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
ctx.JSON(w, 200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 菜单树结构列表
|
||||
//
|
||||
// GET /treeSelect
|
||||
func (s *SysMenuApi) TreeSelect(w http.ResponseWriter, r *http.Request) {
|
||||
query := model.SysMenu{}
|
||||
if v := ctx.GetQuery(r, "menuName"); v != "" {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v := ctx.GetQuery(r, "status"); v != "" {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(r)
|
||||
if conf.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
data := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId)
|
||||
ctx.JSON(w, 200, result.OkData(data))
|
||||
|
||||
}
|
||||
|
||||
// 菜单树结构列表(指定角色)
|
||||
//
|
||||
// GET /roleMenuTreeSelect/:roleId
|
||||
func (s *SysMenuApi) RoleMenuTreeSelect(w http.ResponseWriter, r *http.Request) {
|
||||
roleId := ctx.Param(r, "roleId")
|
||||
if roleId == "" {
|
||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||
return
|
||||
}
|
||||
|
||||
query := model.SysMenu{}
|
||||
if v := ctx.GetQuery(r, "menuName"); v != "" {
|
||||
query.MenuName = v
|
||||
}
|
||||
if v := ctx.GetQuery(r, "status"); v != "" {
|
||||
query.Status = v
|
||||
}
|
||||
|
||||
userId := ctx.LoginUserToUserID(r)
|
||||
if conf.IsAdmin(userId) {
|
||||
userId = "*"
|
||||
}
|
||||
menuTreeSelect := s.sysMenuService.SelectMenuTreeSelectByUserId(query, userId)
|
||||
checkedKeys := s.sysMenuService.SelectMenuListByRoleId(roleId)
|
||||
ctx.JSON(w, 200, result.OkData(map[string]any{
|
||||
"menus": menuTreeSelect,
|
||||
"checkedKeys": checkedKeys,
|
||||
}))
|
||||
}
|
||||
24
features/sys_menu/consts/consts_menu.go
Normal file
24
features/sys_menu/consts/consts_menu.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package consts
|
||||
|
||||
// 系统菜单常量信息
|
||||
|
||||
const (
|
||||
// 组件布局类型-基础布局组件标识
|
||||
COMPONENT_LAYOUT_BASIC = "BasicLayout"
|
||||
// 组件布局类型-空白布局组件标识
|
||||
COMPONENT_LAYOUT_BLANK = "BlankLayout"
|
||||
// 组件布局类型-内链接布局组件标识
|
||||
COMPONENT_LAYOUT_LINK = "LinkLayout"
|
||||
)
|
||||
|
||||
const (
|
||||
// 菜单类型-目录
|
||||
TYPE_DIR = "D"
|
||||
// 菜单类型-菜单
|
||||
TYPE_MENU = "M"
|
||||
// 菜单类型-按钮
|
||||
TYPE_BUTTON = "B"
|
||||
)
|
||||
|
||||
// 菜单内嵌地址标识-带/前缀
|
||||
const PATH_INLINE = "/inline"
|
||||
46
features/sys_menu/model/sys_menu.go
Normal file
46
features/sys_menu/model/sys_menu.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package model
|
||||
|
||||
// SysMenu 菜单权限对象 sys_menu
|
||||
type SysMenu struct {
|
||||
// 菜单ID
|
||||
MenuID string `json:"menuId"`
|
||||
// 菜单名称
|
||||
MenuName string `json:"menuName" binding:"required"`
|
||||
// 父菜单ID 默认0
|
||||
ParentID string `json:"parentId" binding:"required"`
|
||||
// 显示顺序
|
||||
MenuSort int `json:"menuSort"`
|
||||
// 路由地址
|
||||
Path string `json:"path"`
|
||||
// 组件路径
|
||||
Component string `json:"component"`
|
||||
// 是否内部跳转(0否 1是)
|
||||
IsFrame string `json:"isFrame"`
|
||||
// 是否缓存(0不缓存 1缓存)
|
||||
IsCache string `json:"isCache"`
|
||||
// 菜单类型(D目录 M菜单 B按钮)
|
||||
MenuType string `json:"menuType" binding:"required"`
|
||||
// 是否显示(0隐藏 1显示)
|
||||
Visible string `json:"visible"`
|
||||
// 菜单状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 权限标识
|
||||
Perms string `json:"perms"`
|
||||
// 菜单图标(#无图标)
|
||||
Icon string `json:"icon"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
// 备注
|
||||
Remark string `json:"remark"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 子菜单
|
||||
Children []SysMenu `json:"children,omitempty"`
|
||||
}
|
||||
452
features/sys_menu/service/repo_sys_menu.go
Normal file
452
features/sys_menu/service/repo_sys_menu.go
Normal file
@@ -0,0 +1,452 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/features/sys_menu/consts"
|
||||
"ems.agt/features/sys_menu/model"
|
||||
"ems.agt/lib/core/datasource"
|
||||
"ems.agt/lib/core/utils/parse"
|
||||
"github.com/go-admin-team/go-admin-core/logger"
|
||||
)
|
||||
|
||||
// 实例化数据层 RepoSysMenu 结构体
|
||||
var NewRepoSysMenu = &RepoSysMenu{
|
||||
selectSql: `select
|
||||
m.menu_id, m.menu_name, m.parent_id, m.menu_sort, m.path, m.component, m.is_frame, m.is_cache, m.menu_type, m.visible, m.status, ifnull(m.perms,'') as perms, m.icon, m.create_time, m.remark
|
||||
from sys_menu m`,
|
||||
|
||||
selectSqlByUser: `select distinct
|
||||
m.menu_id, m.menu_name, m.parent_id, m.menu_sort, m.path, m.component, m.is_frame, m.is_cache, m.menu_type, m.visible, m.status, ifnull(m.perms,'') as perms, m.icon, m.create_time, m.remark
|
||||
from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||
left join sys_role ro on ur.role_id = ro.role_id`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"menu_id": "MenuID",
|
||||
"menu_name": "MenuName",
|
||||
"parent_name": "ParentName",
|
||||
"parent_id": "ParentID",
|
||||
"path": "Path",
|
||||
"menu_sort": "MenuSort",
|
||||
"component": "Component",
|
||||
"is_frame": "IsFrame",
|
||||
"is_cache": "IsCache",
|
||||
"menu_type": "MenuType",
|
||||
"visible": "Visible",
|
||||
"status": "Status",
|
||||
"perms": "Perms",
|
||||
"icon": "Icon",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"remark": "Remark",
|
||||
},
|
||||
}
|
||||
|
||||
// RepoSysMenu 菜单表 数据层处理
|
||||
type RepoSysMenu struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 查询视图用户对象SQL
|
||||
selectSqlByUser string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *RepoSysMenu) convertResultRows(rows []map[string]any) []model.SysMenu {
|
||||
arr := make([]model.SysMenu, 0)
|
||||
for _, row := range rows {
|
||||
sysMenu := model.SysMenu{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
datasource.SetFieldValue(&sysMenu, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysMenu)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectMenuList 查询系统菜单列表
|
||||
func (r *RepoSysMenu) SelectMenuList(sysMenu model.SysMenu, userId string) []model.SysMenu {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysMenu.MenuName != "" {
|
||||
conditions = append(conditions, "m.menu_name like concat(?, '%')")
|
||||
params = append(params, sysMenu.MenuName)
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
conditions = append(conditions, "m.visible = ?")
|
||||
params = append(params, sysMenu.Visible)
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
conditions = append(conditions, "m.status = ?")
|
||||
params = append(params, sysMenu.Status)
|
||||
}
|
||||
|
||||
fromSql := r.selectSql
|
||||
|
||||
// 个人菜单
|
||||
if userId != "*" {
|
||||
fromSql = r.selectSqlByUser
|
||||
conditions = append(conditions, "ur.user_id = ?")
|
||||
params = append(params, userId)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by m.parent_id, m.menu_sort"
|
||||
querySql := fromSql + whereSql + orderSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectMenuPermsByUserId 根据用户ID查询权限
|
||||
func (r *RepoSysMenu) SelectMenuPermsByUserId(userId string) []string {
|
||||
querySql := `select distinct m.perms as 'str' from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
left join sys_user_role ur on rm.role_id = ur.role_id
|
||||
left join sys_role r on r.role_id = ur.role_id
|
||||
where m.status = '1' and m.perms != '' and r.status = '1' and ur.user_id = ? `
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, []any{userId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// 读取结果
|
||||
rows := make([]string, 0)
|
||||
for _, m := range results {
|
||||
rows = append(rows, fmt.Sprintf("%v", m["str"]))
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// SelectMenuTreeByUserId 根据用户ID查询菜单
|
||||
func (r *RepoSysMenu) SelectMenuTreeByUserId(userId string) []model.SysMenu {
|
||||
var params []any
|
||||
var querySql string
|
||||
|
||||
if userId == "*" {
|
||||
// 管理员全部菜单
|
||||
querySql = r.selectSql + ` where
|
||||
m.menu_type in (?,?) and m.status = '1'
|
||||
order by m.parent_id, m.menu_sort`
|
||||
params = append(params, consts.TYPE_DIR)
|
||||
params = append(params, consts.TYPE_MENU)
|
||||
} else {
|
||||
// 用户ID权限
|
||||
querySql = r.selectSqlByUser + ` where
|
||||
m.menu_type in (?, ?) and m.status = '1'
|
||||
and ur.user_id = ? and ro.status = '1'
|
||||
order by m.parent_id, m.menu_sort`
|
||||
params = append(params, consts.TYPE_DIR)
|
||||
params = append(params, consts.TYPE_MENU)
|
||||
params = append(params, userId)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectMenuListByRoleId 根据角色ID查询菜单树信息
|
||||
func (r *RepoSysMenu) SelectMenuListByRoleId(roleId string, menuCheckStrictly bool) []string {
|
||||
querySql := `select m.menu_id as 'str' from sys_menu m
|
||||
left join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
where rm.role_id = ? `
|
||||
var params []any
|
||||
params = append(params, roleId)
|
||||
// 展开
|
||||
if menuCheckStrictly {
|
||||
querySql += ` and m.menu_id not in
|
||||
(select m.parent_id from sys_menu m
|
||||
inner join sys_role_menu rm on m.menu_id = rm.menu_id
|
||||
and rm.role_id = ?) `
|
||||
params = append(params, roleId)
|
||||
}
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, 0)
|
||||
for _, v := range results {
|
||||
ids = append(ids, fmt.Sprintf("%v", v["str"]))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectMenuByIds 根据菜单ID查询信息
|
||||
func (r *RepoSysMenu) SelectMenuByIds(menuIds []string) []model.SysMenu {
|
||||
placeholder := datasource.KeyPlaceholderByQuery(len(menuIds))
|
||||
querySql := r.selectSql + " where m.menu_id in (" + placeholder + ")"
|
||||
parameters := datasource.ConvertIdsSlice(menuIds)
|
||||
results, err := datasource.RawDB("", querySql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysMenu{}
|
||||
}
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// HasChildByMenuId 存在菜单子节点数量
|
||||
func (r *RepoSysMenu) HasChildByMenuId(menuId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_menu where parent_id = ?"
|
||||
results, err := datasource.RawDB("", querySql, []any{menuId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// InsertMenu 新增菜单信息
|
||||
func (r *RepoSysMenu) InsertMenu(sysMenu model.SysMenu) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysMenu.MenuID != "" {
|
||||
params["menu_id"] = sysMenu.MenuID
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
params["parent_id"] = sysMenu.ParentID
|
||||
}
|
||||
if sysMenu.MenuName != "" {
|
||||
params["menu_name"] = sysMenu.MenuName
|
||||
}
|
||||
if sysMenu.MenuSort > 0 {
|
||||
params["menu_sort"] = sysMenu.MenuSort
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
params["path"] = sysMenu.Path
|
||||
}
|
||||
if sysMenu.Component != "" {
|
||||
params["component"] = sysMenu.Component
|
||||
}
|
||||
if sysMenu.IsFrame != "" {
|
||||
params["is_frame"] = sysMenu.IsFrame
|
||||
}
|
||||
if sysMenu.IsCache != "" {
|
||||
params["is_cache"] = sysMenu.IsCache
|
||||
}
|
||||
if sysMenu.MenuType != "" {
|
||||
params["menu_type"] = sysMenu.MenuType
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
params["visible"] = sysMenu.Visible
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
params["status"] = sysMenu.Status
|
||||
}
|
||||
if sysMenu.Perms != "" {
|
||||
params["perms"] = sysMenu.Perms
|
||||
}
|
||||
if sysMenu.Icon != "" {
|
||||
params["icon"] = sysMenu.Icon
|
||||
} else {
|
||||
params["icon"] = "#"
|
||||
}
|
||||
if sysMenu.Remark != "" {
|
||||
params["remark"] = sysMenu.Remark
|
||||
}
|
||||
if sysMenu.CreateBy != "" {
|
||||
params["create_by"] = sysMenu.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据菜单类型重置参数
|
||||
if sysMenu.MenuType == consts.TYPE_BUTTON {
|
||||
params["component"] = ""
|
||||
params["path"] = ""
|
||||
params["icon"] = "#"
|
||||
params["is_cache"] = "1"
|
||||
params["is_frame"] = "1"
|
||||
params["visible"] = "1"
|
||||
params["status"] = "1"
|
||||
}
|
||||
if sysMenu.MenuType == consts.TYPE_DIR {
|
||||
params["component"] = ""
|
||||
params["perms"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := datasource.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_menu (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
// 执行插入
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
return ""
|
||||
}
|
||||
|
||||
return fmt.Sprint(rows)
|
||||
}
|
||||
|
||||
// UpdateMenu 修改菜单信息
|
||||
func (r *RepoSysMenu) UpdateMenu(sysMenu model.SysMenu) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysMenu.MenuID != "" {
|
||||
params["menu_id"] = sysMenu.MenuID
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
params["parent_id"] = sysMenu.ParentID
|
||||
}
|
||||
if sysMenu.MenuName != "" {
|
||||
params["menu_name"] = sysMenu.MenuName
|
||||
}
|
||||
if sysMenu.MenuSort > 0 {
|
||||
params["menu_sort"] = sysMenu.MenuSort
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
params["path"] = sysMenu.Path
|
||||
}
|
||||
if sysMenu.Component != "" {
|
||||
params["component"] = sysMenu.Component
|
||||
}
|
||||
if sysMenu.IsFrame != "" {
|
||||
params["is_frame"] = sysMenu.IsFrame
|
||||
}
|
||||
if sysMenu.IsCache != "" {
|
||||
params["is_cache"] = sysMenu.IsCache
|
||||
}
|
||||
if sysMenu.MenuType != "" {
|
||||
params["menu_type"] = sysMenu.MenuType
|
||||
}
|
||||
if sysMenu.Visible != "" {
|
||||
params["visible"] = sysMenu.Visible
|
||||
}
|
||||
if sysMenu.Status != "" {
|
||||
params["status"] = sysMenu.Status
|
||||
}
|
||||
if sysMenu.Perms != "" {
|
||||
params["perms"] = sysMenu.Perms
|
||||
}
|
||||
if sysMenu.Icon != "" {
|
||||
params["icon"] = sysMenu.Icon
|
||||
} else {
|
||||
params["icon"] = "#"
|
||||
}
|
||||
if sysMenu.Remark != "" {
|
||||
params["remark"] = sysMenu.Remark
|
||||
}
|
||||
if sysMenu.UpdateBy != "" {
|
||||
params["update_by"] = sysMenu.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 根据菜单类型重置参数
|
||||
if sysMenu.MenuType == consts.TYPE_BUTTON {
|
||||
params["component"] = ""
|
||||
params["path"] = ""
|
||||
params["icon"] = "#"
|
||||
params["is_cache"] = "1"
|
||||
params["is_frame"] = "1"
|
||||
params["visible"] = "1"
|
||||
params["status"] = "1"
|
||||
}
|
||||
if sysMenu.MenuType == consts.TYPE_DIR {
|
||||
params["component"] = ""
|
||||
params["perms"] = ""
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := datasource.KeyValueByUpdate(params)
|
||||
sql := "update sys_menu set " + strings.Join(keys, ",") + " where menu_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysMenu.MenuID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// DeleteMenuById 删除菜单管理信息
|
||||
func (r *RepoSysMenu) DeleteMenuById(menuId string) int64 {
|
||||
sql := "delete from sys_menu where menu_id = ?"
|
||||
results, err := datasource.ExecDB("", sql, []any{menuId})
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// CheckUniqueMenu 校验菜单是否唯一
|
||||
func (r *RepoSysMenu) CheckUniqueMenu(sysMenu model.SysMenu) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysMenu.MenuName != "" {
|
||||
conditions = append(conditions, "menu_name = ?")
|
||||
params = append(params, sysMenu.MenuName)
|
||||
}
|
||||
if sysMenu.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysMenu.ParentID)
|
||||
}
|
||||
if sysMenu.Path != "" {
|
||||
conditions = append(conditions, "path = ?")
|
||||
params = append(params, sysMenu.Path)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
if whereSql == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select menu_id as 'str' from sys_menu " + whereSql + " limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprintf("%v", results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
397
features/sys_menu/service/service_sys_menu.go
Normal file
397
features/sys_menu/service/service_sys_menu.go
Normal file
@@ -0,0 +1,397 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"strings"
|
||||
|
||||
"ems.agt/features/sys_menu/consts"
|
||||
"ems.agt/features/sys_menu/model"
|
||||
sysRoleService "ems.agt/features/sys_role/service"
|
||||
sysrolemenu "ems.agt/features/sys_role_menu"
|
||||
"ems.agt/lib/core/utils/parse"
|
||||
"ems.agt/lib/core/utils/regular"
|
||||
"ems.agt/lib/core/vo"
|
||||
)
|
||||
|
||||
// 实例化服务层 ServiceSysMenu 结构体
|
||||
var NewServiceSysMenu = &ServiceSysMenu{
|
||||
sysMenuRepository: NewRepoSysMenu,
|
||||
sysRoleMenuRepository: sysrolemenu.NewRepoSysRoleMenu,
|
||||
sysRoleRepository: sysRoleService.NewRepoSysRole,
|
||||
}
|
||||
|
||||
// ServiceSysMenu 菜单 服务层处理
|
||||
type ServiceSysMenu struct {
|
||||
// 菜单服务
|
||||
sysMenuRepository *RepoSysMenu
|
||||
// 角色与菜单关联服务
|
||||
sysRoleMenuRepository *sysrolemenu.RepoSysRoleMenu
|
||||
// 角色服务
|
||||
sysRoleRepository *sysRoleService.RepoSysRole
|
||||
}
|
||||
|
||||
// SelectMenuList 查询系统菜单列表
|
||||
func (r *ServiceSysMenu) SelectMenuList(sysMenu model.SysMenu, userId string) []model.SysMenu {
|
||||
return r.sysMenuRepository.SelectMenuList(sysMenu, userId)
|
||||
}
|
||||
|
||||
// SelectMenuPermsByUserId 根据用户ID查询权限
|
||||
func (r *ServiceSysMenu) SelectMenuPermsByUserId(userId string) []string {
|
||||
return r.sysMenuRepository.SelectMenuPermsByUserId(userId)
|
||||
}
|
||||
|
||||
// SelectMenuTreeByUserId 根据用户ID查询菜单
|
||||
func (r *ServiceSysMenu) SelectMenuTreeByUserId(userId string) []model.SysMenu {
|
||||
sysMenus := r.sysMenuRepository.SelectMenuTreeByUserId(userId)
|
||||
return r.parseDataToTree(sysMenus)
|
||||
}
|
||||
|
||||
// SelectMenuTreeSelectByUserId 根据用户ID查询菜单树结构信息
|
||||
func (r *ServiceSysMenu) SelectMenuTreeSelectByUserId(sysMenu model.SysMenu, userId string) []vo.TreeSelect {
|
||||
sysMenus := r.sysMenuRepository.SelectMenuList(sysMenu, userId)
|
||||
menus := r.parseDataToTree(sysMenus)
|
||||
tree := make([]vo.TreeSelect, 0)
|
||||
for _, menu := range menus {
|
||||
tree = append(tree, sysMenuTreeSelect(menu))
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// sysMenuTreeSelect 使用给定的 SysMenu 对象解析为 TreeSelect 对象
|
||||
func sysMenuTreeSelect(sysMenu model.SysMenu) vo.TreeSelect {
|
||||
t := vo.TreeSelect{}
|
||||
t.ID = sysMenu.MenuID
|
||||
t.Label = sysMenu.MenuName
|
||||
|
||||
if len(sysMenu.Children) > 0 {
|
||||
for _, menu := range sysMenu.Children {
|
||||
child := sysMenuTreeSelect(menu)
|
||||
t.Children = append(t.Children, child)
|
||||
}
|
||||
} else {
|
||||
t.Children = []vo.TreeSelect{}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// SelectMenuListByRoleId 根据角色ID查询菜单树信息 TODO
|
||||
func (r *ServiceSysMenu) SelectMenuListByRoleId(roleId string) []string {
|
||||
roles := r.sysRoleRepository.SelectRoleByIds([]string{roleId})
|
||||
if len(roles) > 0 {
|
||||
role := roles[0]
|
||||
if role.RoleID == roleId {
|
||||
return r.sysMenuRepository.SelectMenuListByRoleId(
|
||||
role.RoleID,
|
||||
role.MenuCheckStrictly == "1",
|
||||
)
|
||||
}
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectMenuById 根据菜单ID查询信息
|
||||
func (r *ServiceSysMenu) SelectMenuById(menuId string) model.SysMenu {
|
||||
if menuId == "" {
|
||||
return model.SysMenu{}
|
||||
}
|
||||
menus := r.sysMenuRepository.SelectMenuByIds([]string{menuId})
|
||||
if len(menus) > 0 {
|
||||
return menus[0]
|
||||
}
|
||||
return model.SysMenu{}
|
||||
}
|
||||
|
||||
// HasChildByMenuId 存在菜单子节点数量
|
||||
func (r *ServiceSysMenu) HasChildByMenuId(menuId string) int64 {
|
||||
return r.sysMenuRepository.HasChildByMenuId(menuId)
|
||||
}
|
||||
|
||||
// CheckMenuExistRole 查询菜单是否存在角色
|
||||
func (r *ServiceSysMenu) CheckMenuExistRole(menuId string) int64 {
|
||||
return r.sysRoleMenuRepository.CheckMenuExistRole(menuId)
|
||||
}
|
||||
|
||||
// InsertMenu 新增菜单信息
|
||||
func (r *ServiceSysMenu) InsertMenu(sysMenu model.SysMenu) string {
|
||||
return r.sysMenuRepository.InsertMenu(sysMenu)
|
||||
}
|
||||
|
||||
// UpdateMenu 修改菜单信息
|
||||
func (r *ServiceSysMenu) UpdateMenu(sysMenu model.SysMenu) int64 {
|
||||
return r.sysMenuRepository.UpdateMenu(sysMenu)
|
||||
}
|
||||
|
||||
// DeleteMenuById 删除菜单管理信息
|
||||
func (r *ServiceSysMenu) DeleteMenuById(menuId string) int64 {
|
||||
// 删除菜单与角色关联
|
||||
r.sysRoleMenuRepository.DeleteMenuRole([]string{menuId})
|
||||
return r.sysMenuRepository.DeleteMenuById(menuId)
|
||||
}
|
||||
|
||||
// CheckUniqueMenuName 校验菜单名称是否唯一
|
||||
func (r *ServiceSysMenu) CheckUniqueMenuName(menuName, parentId, menuId string) bool {
|
||||
uniqueId := r.sysMenuRepository.CheckUniqueMenu(model.SysMenu{
|
||||
MenuName: menuName,
|
||||
ParentID: parentId,
|
||||
})
|
||||
if uniqueId == menuId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// CheckUniqueMenuPath 校验路由地址是否唯一(针对目录和菜单)
|
||||
func (r *ServiceSysMenu) CheckUniqueMenuPath(path, menuId string) bool {
|
||||
uniqueId := r.sysMenuRepository.CheckUniqueMenu(model.SysMenu{
|
||||
Path: path,
|
||||
})
|
||||
if uniqueId == menuId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// BuildRouteMenus 构建前端路由所需要的菜单
|
||||
func (r *ServiceSysMenu) BuildRouteMenus(sysMenus []model.SysMenu, prefix string) []vo.Router {
|
||||
routers := []vo.Router{}
|
||||
for _, item := range sysMenus {
|
||||
router := vo.Router{}
|
||||
router.Name = r.getRouteName(item)
|
||||
router.Path = r.getRouterPath(item)
|
||||
router.Component = r.getComponent(item)
|
||||
router.Meta = r.getRouteMeta(item)
|
||||
|
||||
// 子项菜单 目录类型 非路径链接
|
||||
cMenus := item.Children
|
||||
if len(cMenus) > 0 && item.MenuType == consts.TYPE_DIR && !regular.ValidHttp(item.Path) {
|
||||
// 获取重定向地址
|
||||
redirectPrefix, redirectPath := r.getRouteRedirect(
|
||||
cMenus,
|
||||
router.Path,
|
||||
prefix,
|
||||
)
|
||||
router.Redirect = redirectPath
|
||||
// 子菜单进入递归
|
||||
router.Children = r.BuildRouteMenus(cMenus, redirectPrefix)
|
||||
} else if item.ParentID == "0" && item.IsFrame == "1" && item.MenuType == consts.TYPE_MENU {
|
||||
// 父菜单 内部跳转 菜单类型
|
||||
menuPath := "/" + item.MenuID
|
||||
childPath := menuPath + r.getRouterPath(item)
|
||||
children := vo.Router{
|
||||
Name: r.getRouteName(item),
|
||||
Path: childPath,
|
||||
Component: item.Component,
|
||||
Meta: r.getRouteMeta(item),
|
||||
}
|
||||
router.Meta.HideChildInMenu = true
|
||||
router.Children = append(router.Children, children)
|
||||
router.Name = item.MenuID
|
||||
router.Path = menuPath
|
||||
router.Redirect = childPath
|
||||
router.Component = consts.COMPONENT_LAYOUT_BASIC
|
||||
} else if item.ParentID == "0" && item.IsFrame == "1" && regular.ValidHttp(item.Path) {
|
||||
// 父菜单 内部跳转 路径链接
|
||||
menuPath := "/" + item.MenuID
|
||||
childPath := menuPath + r.getRouterPath(item)
|
||||
children := vo.Router{
|
||||
Name: r.getRouteName(item),
|
||||
Path: childPath,
|
||||
Component: consts.COMPONENT_LAYOUT_LINK,
|
||||
Meta: r.getRouteMeta(item),
|
||||
}
|
||||
router.Meta.HideChildInMenu = true
|
||||
router.Children = append(router.Children, children)
|
||||
router.Name = item.MenuID
|
||||
router.Path = menuPath
|
||||
router.Redirect = childPath
|
||||
router.Component = consts.COMPONENT_LAYOUT_BASIC
|
||||
}
|
||||
|
||||
routers = append(routers, router)
|
||||
}
|
||||
return routers
|
||||
}
|
||||
|
||||
// getRouteName 获取路由名称 路径英文首字母大写
|
||||
func (r *ServiceSysMenu) getRouteName(sysMenu model.SysMenu) string {
|
||||
routerName := parse.FirstUpper(sysMenu.Path)
|
||||
// 路径链接
|
||||
if regular.ValidHttp(sysMenu.Path) {
|
||||
return routerName[:5] + "Link" + sysMenu.MenuID
|
||||
}
|
||||
return routerName
|
||||
}
|
||||
|
||||
// getRouterPath 获取路由地址
|
||||
func (r *ServiceSysMenu) getRouterPath(sysMenu model.SysMenu) string {
|
||||
routerPath := sysMenu.Path
|
||||
|
||||
// 显式路径
|
||||
if routerPath == "" || strings.HasPrefix(routerPath, "/") {
|
||||
return routerPath
|
||||
}
|
||||
|
||||
// 路径链接 内部跳转
|
||||
if regular.ValidHttp(routerPath) && sysMenu.IsFrame == "1" {
|
||||
routerPath = regular.Replace(routerPath, `/^http(s)?:\/\/+/`, "")
|
||||
routerPath = base64.StdEncoding.EncodeToString([]byte(routerPath))
|
||||
}
|
||||
|
||||
// 父菜单 内部跳转
|
||||
if sysMenu.ParentID == "0" && sysMenu.IsFrame == "1" {
|
||||
routerPath = "/" + routerPath
|
||||
}
|
||||
|
||||
return routerPath
|
||||
}
|
||||
|
||||
// getComponent 获取组件信息
|
||||
func (r *ServiceSysMenu) getComponent(sysMenu model.SysMenu) string {
|
||||
// 内部跳转 路径链接
|
||||
if sysMenu.IsFrame == "1" && regular.ValidHttp(sysMenu.Path) {
|
||||
return consts.COMPONENT_LAYOUT_LINK
|
||||
}
|
||||
|
||||
// 非父菜单 目录类型
|
||||
if sysMenu.ParentID != "0" && sysMenu.MenuType == consts.TYPE_DIR {
|
||||
return consts.COMPONENT_LAYOUT_BLANK
|
||||
}
|
||||
|
||||
// 组件路径 内部跳转 菜单类型
|
||||
if sysMenu.Component != "" && sysMenu.IsFrame == "1" && sysMenu.MenuType == consts.TYPE_MENU {
|
||||
// 父菜单套外层布局
|
||||
if sysMenu.ParentID == "0" {
|
||||
return consts.COMPONENT_LAYOUT_BASIC
|
||||
}
|
||||
return sysMenu.Component
|
||||
}
|
||||
|
||||
return consts.COMPONENT_LAYOUT_BASIC
|
||||
}
|
||||
|
||||
// getRouteMeta 获取路由元信息
|
||||
func (r *ServiceSysMenu) getRouteMeta(sysMenu model.SysMenu) vo.RouterMeta {
|
||||
meta := vo.RouterMeta{}
|
||||
if sysMenu.Icon == "#" {
|
||||
meta.Icon = ""
|
||||
} else {
|
||||
meta.Icon = sysMenu.Icon
|
||||
}
|
||||
meta.Title = sysMenu.MenuName
|
||||
meta.HideChildInMenu = false
|
||||
meta.HideInMenu = sysMenu.Visible == "0"
|
||||
meta.Cache = sysMenu.IsCache == "1"
|
||||
meta.Target = ""
|
||||
|
||||
// 路径链接 非内部跳转
|
||||
if regular.ValidHttp(sysMenu.Path) && sysMenu.IsFrame == "0" {
|
||||
meta.Target = "_blank"
|
||||
}
|
||||
|
||||
return meta
|
||||
}
|
||||
|
||||
// getRouteRedirect 获取路由重定向地址(针对目录)
|
||||
//
|
||||
// cMenus 子菜单数组
|
||||
// routerPath 当前菜单路径
|
||||
// prefix 菜单重定向路径前缀
|
||||
func (r *ServiceSysMenu) getRouteRedirect(cMenus []model.SysMenu, routerPath string, prefix string) (string, string) {
|
||||
redirectPath := ""
|
||||
|
||||
// 重定向为首个显示并启用的子菜单
|
||||
var firstChild *model.SysMenu
|
||||
for _, item := range cMenus {
|
||||
if item.IsFrame == "1" && item.Visible == "1" {
|
||||
firstChild = &item
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 检查内嵌隐藏菜单是否可做重定向
|
||||
if firstChild == nil {
|
||||
for _, item := range cMenus {
|
||||
if item.IsFrame == "1" && item.Visible == "1" && strings.Contains(item.Path, consts.PATH_INLINE) {
|
||||
firstChild = &item
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if firstChild != nil {
|
||||
firstChildPath := r.getRouterPath(*firstChild)
|
||||
if strings.HasPrefix(firstChildPath, "/") {
|
||||
redirectPath = firstChildPath
|
||||
} else {
|
||||
// 拼接追加路径
|
||||
if !strings.HasPrefix(routerPath, "/") {
|
||||
prefix += "/"
|
||||
}
|
||||
prefix = prefix + routerPath
|
||||
redirectPath = prefix + "/" + firstChildPath
|
||||
}
|
||||
}
|
||||
|
||||
return prefix, redirectPath
|
||||
}
|
||||
|
||||
// parseDataToTree 将数据解析为树结构,构建前端所需要下拉树结构
|
||||
func (r *ServiceSysMenu) parseDataToTree(sysMenus []model.SysMenu) []model.SysMenu {
|
||||
// 节点分组
|
||||
nodesMap := make(map[string][]model.SysMenu)
|
||||
// 节点id
|
||||
treeIds := []string{}
|
||||
// 树节点
|
||||
tree := []model.SysMenu{}
|
||||
|
||||
for _, item := range sysMenus {
|
||||
parentID := item.ParentID
|
||||
// 分组
|
||||
mapItem, ok := nodesMap[parentID]
|
||||
if !ok {
|
||||
mapItem = []model.SysMenu{}
|
||||
}
|
||||
mapItem = append(mapItem, item)
|
||||
nodesMap[parentID] = mapItem
|
||||
// 记录节点ID
|
||||
treeIds = append(treeIds, item.MenuID)
|
||||
}
|
||||
|
||||
for key, value := range nodesMap {
|
||||
// 选择不是节点ID的作为树节点
|
||||
found := false
|
||||
for _, id := range treeIds {
|
||||
if id == key {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
tree = append(tree, value...)
|
||||
}
|
||||
}
|
||||
|
||||
for i, node := range tree {
|
||||
iN := r.parseDataToTreeComponet(node, &nodesMap)
|
||||
tree[i] = iN
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
// parseDataToTreeComponet 递归函数处理子节点
|
||||
func (r *ServiceSysMenu) parseDataToTreeComponet(node model.SysMenu, nodesMap *map[string][]model.SysMenu) model.SysMenu {
|
||||
id := node.MenuID
|
||||
children, ok := (*nodesMap)[id]
|
||||
if ok {
|
||||
node.Children = children
|
||||
}
|
||||
if len(node.Children) > 0 {
|
||||
for i, child := range node.Children {
|
||||
icN := r.parseDataToTreeComponet(child, nodesMap)
|
||||
node.Children[i] = icN
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
Reference in New Issue
Block a user