kra/internal/service/system/menu.go

442 lines
13 KiB
Go

package system
import (
"context"
"kra/internal/biz/system"
"kra/internal/server/middleware"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/transport/http"
)
// MenuService 菜单服务
type MenuService struct {
uc *system.MenuUsecase
}
// NewMenuService 创建菜单服务
func NewMenuService(uc *system.MenuUsecase) *MenuService {
return &MenuService{uc: uc}
}
// MenuInfo 菜单信息
type MenuInfo struct {
ID uint `json:"ID"`
ParentId uint `json:"parentId"`
Path string `json:"path"`
Name string `json:"name"`
Hidden bool `json:"hidden"`
Component string `json:"component"`
Sort int `json:"sort"`
Meta MenuMeta `json:"meta"`
AuthorityId uint `json:"authorityId,omitempty"`
MenuId uint `json:"menuId,omitempty"`
Parameters []*MenuParamInfo `json:"parameters,omitempty"`
MenuBtn []*MenuBtnInfo `json:"menuBtn,omitempty"`
Btns map[string]uint `json:"btns,omitempty"`
Children []*MenuInfo `json:"children,omitempty"`
}
// MenuMeta 菜单元信息
type MenuMeta struct {
ActiveName string `json:"activeName"`
KeepAlive bool `json:"keepAlive"`
DefaultMenu bool `json:"defaultMenu"`
Title string `json:"title"`
Icon string `json:"icon"`
CloseTab bool `json:"closeTab"`
TransitionType string `json:"transitionType"`
}
// MenuParamInfo 菜单参数信息
type MenuParamInfo struct {
ID uint `json:"ID"`
SysBaseMenuID uint `json:"sysBaseMenuId"`
Type string `json:"type"`
Key string `json:"key"`
Value string `json:"value"`
}
// MenuBtnInfo 菜单按钮信息
type MenuBtnInfo struct {
ID uint `json:"ID"`
SysBaseMenuID uint `json:"sysBaseMenuId"`
Name string `json:"name"`
Desc string `json:"desc"`
}
// BaseMenuRequest 基础菜单请求
type BaseMenuRequest struct {
ID uint `json:"ID"`
ParentId uint `json:"parentId"`
Path string `json:"path"`
Name string `json:"name"`
Hidden bool `json:"hidden"`
Component string `json:"component"`
Sort int `json:"sort"`
Meta MenuMeta `json:"meta"`
Parameters []*MenuParamInfo `json:"parameters"`
MenuBtn []*MenuBtnInfo `json:"menuBtn"`
}
// GetMenu 获取用户动态路由
func (s *MenuService) GetMenu(ctx context.Context, authorityId uint) ([]*MenuInfo, error) {
menus, err := s.uc.GetMenuTree(ctx, authorityId)
if err != nil {
return nil, err
}
return toMenuInfoList(menus), nil
}
// GetBaseMenuTree 获取基础菜单树
func (s *MenuService) GetBaseMenuTree(ctx context.Context, authorityId uint) ([]*MenuInfo, error) {
menus, err := s.uc.GetBaseMenuTree(ctx, authorityId)
if err != nil {
return nil, err
}
return toBaseMenuInfoList(menus), nil
}
// GetMenuList 获取菜单列表
func (s *MenuService) GetMenuList(ctx context.Context, authorityId uint) ([]*MenuInfo, error) {
menus, err := s.uc.GetInfoList(ctx, authorityId)
if err != nil {
return nil, err
}
return toBaseMenuInfoList(menus), nil
}
// AddBaseMenu 添加基础菜单
func (s *MenuService) AddBaseMenu(ctx context.Context, req *BaseMenuRequest) error {
menu := toBaseMenu(req)
return s.uc.AddBaseMenu(ctx, menu)
}
// UpdateBaseMenu 更新基础菜单
func (s *MenuService) UpdateBaseMenu(ctx context.Context, req *BaseMenuRequest) error {
menu := toBaseMenu(req)
return s.uc.UpdateBaseMenu(ctx, menu)
}
// DeleteBaseMenu 删除基础菜单
func (s *MenuService) DeleteBaseMenu(ctx context.Context, id uint) error {
return s.uc.DeleteBaseMenu(ctx, id)
}
// GetBaseMenuById 根据ID获取基础菜单
func (s *MenuService) GetBaseMenuById(ctx context.Context, id uint) (*MenuInfo, error) {
menu, err := s.uc.GetBaseMenuById(ctx, id)
if err != nil {
return nil, err
}
return toBaseMenuInfo(menu), nil
}
// AddMenuAuthorityRequest 添加菜单权限请求
type AddMenuAuthorityRequest struct {
AuthorityId uint `json:"authorityId"`
Menus []*BaseMenuRequest `json:"menus"`
}
// AddMenuAuthority 添加菜单权限
func (s *MenuService) AddMenuAuthority(ctx context.Context, adminAuthorityID uint, req *AddMenuAuthorityRequest) error {
menus := make([]*system.BaseMenu, len(req.Menus))
for i, m := range req.Menus {
menus[i] = toBaseMenu(m)
}
return s.uc.AddMenuAuthority(ctx, menus, adminAuthorityID, req.AuthorityId)
}
// GetMenuAuthority 获取角色菜单权限
func (s *MenuService) GetMenuAuthority(ctx context.Context, authorityId uint) ([]*MenuInfo, error) {
menus, err := s.uc.GetMenuAuthority(ctx, authorityId)
if err != nil {
return nil, err
}
return toMenuInfoList(menus), nil
}
// 转换函数
func toBaseMenu(req *BaseMenuRequest) *system.BaseMenu {
menu := &system.BaseMenu{
ID: req.ID,
ParentId: req.ParentId,
Path: req.Path,
Name: req.Name,
Hidden: req.Hidden,
Component: req.Component,
Sort: req.Sort,
ActiveName: req.Meta.ActiveName,
KeepAlive: req.Meta.KeepAlive,
DefaultMenu: req.Meta.DefaultMenu,
Title: req.Meta.Title,
Icon: req.Meta.Icon,
CloseTab: req.Meta.CloseTab,
TransitionType: req.Meta.TransitionType,
}
if len(req.Parameters) > 0 {
menu.Parameters = make([]*system.MenuParameter, len(req.Parameters))
for i, p := range req.Parameters {
menu.Parameters[i] = &system.MenuParameter{
ID: p.ID,
SysBaseMenuID: p.SysBaseMenuID,
Type: p.Type,
Key: p.Key,
Value: p.Value,
}
}
}
if len(req.MenuBtn) > 0 {
menu.MenuBtn = make([]*system.MenuBtn, len(req.MenuBtn))
for i, b := range req.MenuBtn {
menu.MenuBtn[i] = &system.MenuBtn{
ID: b.ID,
SysBaseMenuID: b.SysBaseMenuID,
Name: b.Name,
Desc: b.Desc,
}
}
}
return menu
}
func toMenuInfoList(menus []*system.Menu) []*MenuInfo {
if menus == nil {
return []*MenuInfo{}
}
result := make([]*MenuInfo, len(menus))
for i, m := range menus {
result[i] = toMenuInfo(m)
}
return result
}
func toMenuInfo(m *system.Menu) *MenuInfo {
info := &MenuInfo{
ID: m.ID,
ParentId: m.ParentId,
Path: m.Path,
Name: m.Name,
Hidden: m.Hidden,
Component: m.Component,
Sort: m.Sort,
AuthorityId: m.AuthorityId,
MenuId: m.MenuId,
Btns: m.Btns,
Meta: MenuMeta{
ActiveName: m.ActiveName,
KeepAlive: m.KeepAlive,
DefaultMenu: m.DefaultMenu,
Title: m.Title,
Icon: m.Icon,
CloseTab: m.CloseTab,
TransitionType: m.TransitionType,
},
}
if len(m.Parameters) > 0 {
info.Parameters = make([]*MenuParamInfo, len(m.Parameters))
for i, p := range m.Parameters {
info.Parameters[i] = &MenuParamInfo{
ID: p.ID,
SysBaseMenuID: p.SysBaseMenuID,
Type: p.Type,
Key: p.Key,
Value: p.Value,
}
}
}
if len(m.Children) > 0 {
info.Children = toMenuInfoList(m.Children)
}
return info
}
func toBaseMenuInfoList(menus []*system.BaseMenu) []*MenuInfo {
if menus == nil {
return []*MenuInfo{}
}
result := make([]*MenuInfo, len(menus))
for i, m := range menus {
result[i] = toBaseMenuInfo(m)
}
return result
}
func toBaseMenuInfo(m *system.BaseMenu) *MenuInfo {
info := &MenuInfo{
ID: m.ID,
ParentId: m.ParentId,
Path: m.Path,
Name: m.Name,
Hidden: m.Hidden,
Component: m.Component,
Sort: m.Sort,
Meta: MenuMeta{
ActiveName: m.ActiveName,
KeepAlive: m.KeepAlive,
DefaultMenu: m.DefaultMenu,
Title: m.Title,
Icon: m.Icon,
CloseTab: m.CloseTab,
TransitionType: m.TransitionType,
},
}
if len(m.Parameters) > 0 {
info.Parameters = make([]*MenuParamInfo, len(m.Parameters))
for i, p := range m.Parameters {
info.Parameters[i] = &MenuParamInfo{
ID: p.ID,
SysBaseMenuID: p.SysBaseMenuID,
Type: p.Type,
Key: p.Key,
Value: p.Value,
}
}
}
if len(m.MenuBtn) > 0 {
info.MenuBtn = make([]*MenuBtnInfo, len(m.MenuBtn))
for i, b := range m.MenuBtn {
info.MenuBtn[i] = &MenuBtnInfo{
ID: b.ID,
SysBaseMenuID: b.SysBaseMenuID,
Name: b.Name,
Desc: b.Desc,
}
}
}
if len(m.Children) > 0 {
info.Children = toBaseMenuInfoList(m.Children)
}
return info
}
// RegisterRoutes 注册路由
func (s *MenuService) RegisterRoutes(rg *RouterGroup) {
// 私有路由 + 操作记录(写操作)
rg.PrivateWithRecord.POST("/menu/addBaseMenu", s.handleAddBaseMenu)
rg.PrivateWithRecord.POST("/menu/addMenuAuthority", s.handleAddMenuAuthority)
rg.PrivateWithRecord.POST("/menu/deleteBaseMenu", s.handleDeleteBaseMenu)
rg.PrivateWithRecord.POST("/menu/updateBaseMenu", s.handleUpdateBaseMenu)
// 私有路由(读操作,不记录)
rg.Private.POST("/menu/getMenu", s.handleGetMenu)
rg.Private.POST("/menu/getMenuList", s.handleGetMenuList)
rg.Private.POST("/menu/getBaseMenuTree", s.handleGetBaseMenuTree)
rg.Private.POST("/menu/getMenuAuthority", s.handleGetMenuAuthority)
rg.Private.POST("/menu/getBaseMenuById", s.handleGetBaseMenuById)
}
// HTTP Handlers
func (s *MenuService) handleGetMenu(ctx http.Context) error {
authorityId := middleware.GetAuthorityID(ctx)
menus, err := s.GetMenu(ctx, authorityId)
if err != nil {
return errors.InternalServer("GET_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"menus": menus}})
}
func (s *MenuService) handleGetBaseMenuTree(ctx http.Context) error {
authorityId := middleware.GetAuthorityID(ctx)
menus, err := s.GetBaseMenuTree(ctx, authorityId)
if err != nil {
return errors.InternalServer("GET_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"menus": menus}})
}
func (s *MenuService) handleGetMenuList(ctx http.Context) error {
authorityId := middleware.GetAuthorityID(ctx)
menus, err := s.GetMenuList(ctx, authorityId)
if err != nil {
return errors.InternalServer("GET_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": menus})
}
func (s *MenuService) handleAddBaseMenu(ctx http.Context) error {
var req BaseMenuRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.AddBaseMenu(ctx, &req); err != nil {
return errors.BadRequest("ADD_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "添加成功"})
}
func (s *MenuService) handleUpdateBaseMenu(ctx http.Context) error {
var req BaseMenuRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.UpdateBaseMenu(ctx, &req); err != nil {
return errors.BadRequest("UPDATE_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "更新成功"})
}
func (s *MenuService) handleDeleteBaseMenu(ctx http.Context) error {
var req struct {
ID uint `json:"ID"`
}
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.DeleteBaseMenu(ctx, req.ID); err != nil {
return errors.BadRequest("DELETE_MENU_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "删除成功"})
}
func (s *MenuService) handleGetBaseMenuById(ctx http.Context) error {
var req struct {
ID uint `json:"ID"`
}
if err := ctx.Bind(&req); err != nil {
return err
}
menu, err := s.GetBaseMenuById(ctx, req.ID)
if err != nil {
return errors.NotFound("MENU_NOT_FOUND", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"menu": menu}})
}
func (s *MenuService) handleAddMenuAuthority(ctx http.Context) error {
var req AddMenuAuthorityRequest
if err := ctx.Bind(&req); err != nil {
return err
}
adminAuthorityID := middleware.GetAuthorityID(ctx)
if err := s.AddMenuAuthority(ctx, adminAuthorityID, &req); err != nil {
return errors.BadRequest("ADD_AUTHORITY_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "添加成功"})
}
func (s *MenuService) handleGetMenuAuthority(ctx http.Context) error {
var req struct {
AuthorityId uint `json:"authorityId"`
}
if err := ctx.Bind(&req); err != nil {
return err
}
menus, err := s.GetMenuAuthority(ctx, req.AuthorityId)
if err != nil {
return errors.InternalServer("GET_AUTHORITY_FAILED", err.Error())
}
return ctx.Result(200, map[string]any{"code": 0, "msg": "获取成功", "data": map[string]any{"menus": menus}})
}