244 lines
9.5 KiB
C#
244 lines
9.5 KiB
C#
using AmtScanner.Api.Data;
|
||
using AmtScanner.Api.Models;
|
||
using AmtScanner.Api.Services;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.EntityFrameworkCore;
|
||
|
||
namespace AmtScanner.Api.Controllers;
|
||
|
||
/// <summary>
|
||
/// 菜单控制器
|
||
/// </summary>
|
||
[ApiController]
|
||
public class MenuController : ControllerBase
|
||
{
|
||
private readonly IMenuService _menuService;
|
||
private readonly AppDbContext _context;
|
||
|
||
public MenuController(IMenuService menuService, AppDbContext context)
|
||
{
|
||
_menuService = menuService;
|
||
_context = context;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取用户菜单(adminSystem 前端使用的路由)
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpGet("api/v3/system/menus/simple")]
|
||
public async Task<ActionResult<ApiResponse<List<MenuDto>>>> GetUserMenus()
|
||
{
|
||
var userIdClaim = User.FindFirst("userId")?.Value;
|
||
if (string.IsNullOrEmpty(userIdClaim) || !int.TryParse(userIdClaim, out var userId))
|
||
{
|
||
return Ok(ApiResponse<List<MenuDto>>.Fail(401, "无效的用户"));
|
||
}
|
||
|
||
var menus = await _menuService.GetUserMenusAsync(userId);
|
||
return Ok(ApiResponse<List<MenuDto>>.Success(menus));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有菜单列表
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpGet("api/menu/list")]
|
||
public async Task<ActionResult<ApiResponse<List<MenuDto>>>> GetAllMenus()
|
||
{
|
||
var menus = await _menuService.GetAllMenusAsync();
|
||
return Ok(ApiResponse<List<MenuDto>>.Success(menus));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建菜单
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpPost("api/menu")]
|
||
public async Task<ActionResult<ApiResponse<Menu>>> CreateMenu([FromBody] CreateMenuRequest request)
|
||
{
|
||
var menu = new Menu
|
||
{
|
||
ParentId = request.ParentId,
|
||
Name = request.Name,
|
||
Path = request.Path,
|
||
Component = request.Component,
|
||
Title = request.Title,
|
||
Icon = request.Icon,
|
||
Sort = request.Sort,
|
||
IsHide = request.IsHide,
|
||
KeepAlive = request.KeepAlive,
|
||
Link = request.Link,
|
||
IsIframe = request.IsIframe,
|
||
Roles = request.Roles != null ? string.Join(",", request.Roles) : null
|
||
};
|
||
|
||
_context.Menus.Add(menu);
|
||
await _context.SaveChangesAsync();
|
||
|
||
return Ok(ApiResponse<Menu>.Success(menu, "菜单创建成功"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新菜单
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpPut("api/menu/{id}")]
|
||
public async Task<ActionResult<ApiResponse<Menu>>> UpdateMenu(int id, [FromBody] UpdateMenuRequest request)
|
||
{
|
||
var menu = await _context.Menus.FindAsync(id);
|
||
if (menu == null)
|
||
{
|
||
return Ok(ApiResponse<Menu>.Fail(404, "菜单不存在"));
|
||
}
|
||
|
||
if (request.ParentId.HasValue) menu.ParentId = request.ParentId;
|
||
if (!string.IsNullOrEmpty(request.Name)) menu.Name = request.Name;
|
||
if (!string.IsNullOrEmpty(request.Path)) menu.Path = request.Path;
|
||
if (request.Component != null) menu.Component = request.Component;
|
||
if (!string.IsNullOrEmpty(request.Title)) menu.Title = request.Title;
|
||
if (request.Icon != null) menu.Icon = request.Icon;
|
||
if (request.Sort.HasValue) menu.Sort = request.Sort.Value;
|
||
if (request.IsHide.HasValue) menu.IsHide = request.IsHide.Value;
|
||
if (request.KeepAlive.HasValue) menu.KeepAlive = request.KeepAlive.Value;
|
||
if (request.Link != null) menu.Link = request.Link;
|
||
if (request.IsIframe.HasValue) menu.IsIframe = request.IsIframe.Value;
|
||
if (request.Roles != null) menu.Roles = string.Join(",", request.Roles);
|
||
|
||
await _context.SaveChangesAsync();
|
||
|
||
return Ok(ApiResponse<Menu>.Success(menu, "菜单更新成功"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除菜单
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpDelete("api/menu/{id}")]
|
||
public async Task<ActionResult<ApiResponse<object>>> DeleteMenu(int id)
|
||
{
|
||
var menu = await _context.Menus.FindAsync(id);
|
||
if (menu == null)
|
||
{
|
||
return Ok(ApiResponse<object>.Fail(404, "菜单不存在"));
|
||
}
|
||
|
||
// 检查是否为系统内置菜单
|
||
if (menu.IsSystem)
|
||
{
|
||
return Ok(ApiResponse<object>.Fail(400, "系统内置菜单不能删除"));
|
||
}
|
||
|
||
// 检查是否有子菜单
|
||
var hasChildren = await _context.Menus.AnyAsync(m => m.ParentId == id);
|
||
if (hasChildren)
|
||
{
|
||
return Ok(ApiResponse<object>.Fail(400, "请先删除子菜单"));
|
||
}
|
||
|
||
// 删除角色菜单关联
|
||
var roleMenus = await _context.RoleMenus.Where(rm => rm.MenuId == id).ToListAsync();
|
||
_context.RoleMenus.RemoveRange(roleMenus);
|
||
|
||
_context.Menus.Remove(menu);
|
||
await _context.SaveChangesAsync();
|
||
|
||
return Ok(ApiResponse<object>.Success(null, "菜单删除成功"));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置菜单为默认配置
|
||
/// </summary>
|
||
[Authorize]
|
||
[HttpPost("api/menu/reset")]
|
||
public async Task<ActionResult<ApiResponse<object>>> ResetMenus()
|
||
{
|
||
// 清空现有菜单和角色菜单关联
|
||
_context.RoleMenus.RemoveRange(_context.RoleMenus);
|
||
_context.Menus.RemoveRange(_context.Menus);
|
||
await _context.SaveChangesAsync();
|
||
|
||
// 重新创建默认菜单
|
||
var menus = new List<Menu>
|
||
{
|
||
// 仪表盘菜单(系统内置)
|
||
new() { Id = 1, Name = "Dashboard", Path = "/dashboard", Component = "/index/index", Title = "menus.dashboard.title", Icon = "ri:pie-chart-line", Sort = 1, Roles = "R_SUPER,R_ADMIN,R_USER", IsSystem = true },
|
||
new() { Id = 2, ParentId = 1, Name = "Console", Path = "console", Component = "/dashboard/console", Title = "menus.dashboard.console", KeepAlive = false, Sort = 1, Roles = "R_SUPER,R_ADMIN,R_USER", IsSystem = true },
|
||
|
||
// 系统管理菜单(系统内置)
|
||
new() { Id = 10, Name = "System", Path = "/system", Component = "/index/index", Title = "menus.system.title", Icon = "ri:user-3-line", Sort = 99, Roles = "R_SUPER,R_ADMIN", IsSystem = true },
|
||
new() { Id = 11, ParentId = 10, Name = "User", Path = "user", Component = "/system/user", Title = "menus.system.user", KeepAlive = true, Sort = 1, Roles = "R_SUPER,R_ADMIN", IsSystem = true },
|
||
new() { Id = 12, ParentId = 10, Name = "Role", Path = "role", Component = "/system/role", Title = "menus.system.role", KeepAlive = true, Sort = 2, Roles = "R_SUPER", IsSystem = true },
|
||
new() { Id = 13, ParentId = 10, Name = "UserCenter", Path = "user-center", Component = "/system/user-center", Title = "menus.system.userCenter", IsHide = true, KeepAlive = true, Sort = 3, Roles = "R_SUPER,R_ADMIN,R_USER", IsSystem = true },
|
||
new() { Id = 14, ParentId = 10, Name = "Menus", Path = "menu", Component = "/system/menu", Title = "menus.system.menu", KeepAlive = true, Sort = 4, Roles = "R_SUPER", IsSystem = true }
|
||
};
|
||
|
||
_context.Menus.AddRange(menus);
|
||
await _context.SaveChangesAsync();
|
||
|
||
// 重新分配角色菜单
|
||
var superRole = await _context.Roles.FirstAsync(r => r.RoleCode == "R_SUPER");
|
||
var adminRole = await _context.Roles.FirstAsync(r => r.RoleCode == "R_ADMIN");
|
||
var userRole = await _context.Roles.FirstAsync(r => r.RoleCode == "R_USER");
|
||
|
||
var allMenuIds = await _context.Menus.Select(m => m.Id).ToListAsync();
|
||
var adminMenuIds = await _context.Menus
|
||
.Where(m => m.Roles != null && (m.Roles.Contains("R_ADMIN") || m.Roles.Contains("R_USER")))
|
||
.Select(m => m.Id).ToListAsync();
|
||
var userMenuIds = await _context.Menus
|
||
.Where(m => m.Roles != null && m.Roles.Contains("R_USER"))
|
||
.Select(m => m.Id).ToListAsync();
|
||
|
||
var roleMenus = new List<RoleMenu>();
|
||
foreach (var menuId in allMenuIds)
|
||
roleMenus.Add(new RoleMenu { RoleId = superRole.Id, MenuId = menuId });
|
||
foreach (var menuId in adminMenuIds)
|
||
roleMenus.Add(new RoleMenu { RoleId = adminRole.Id, MenuId = menuId });
|
||
foreach (var menuId in userMenuIds)
|
||
roleMenus.Add(new RoleMenu { RoleId = userRole.Id, MenuId = menuId });
|
||
|
||
_context.RoleMenus.AddRange(roleMenus);
|
||
await _context.SaveChangesAsync();
|
||
|
||
return Ok(ApiResponse<object>.Success(null, "菜单已重置为默认配置"));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 创建菜单请求
|
||
/// </summary>
|
||
public class CreateMenuRequest
|
||
{
|
||
public int? ParentId { get; set; }
|
||
public string Name { get; set; } = string.Empty;
|
||
public string Path { get; set; } = string.Empty;
|
||
public string? Component { get; set; }
|
||
public string Title { get; set; } = string.Empty;
|
||
public string? Icon { get; set; }
|
||
public int Sort { get; set; }
|
||
public bool IsHide { get; set; }
|
||
public bool KeepAlive { get; set; }
|
||
public string? Link { get; set; }
|
||
public bool IsIframe { get; set; }
|
||
public List<string>? Roles { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新菜单请求
|
||
/// </summary>
|
||
public class UpdateMenuRequest
|
||
{
|
||
public int? ParentId { get; set; }
|
||
public string? Name { get; set; }
|
||
public string? Path { get; set; }
|
||
public string? Component { get; set; }
|
||
public string? Title { get; set; }
|
||
public string? Icon { get; set; }
|
||
public int? Sort { get; set; }
|
||
public bool? IsHide { get; set; }
|
||
public bool? KeepAlive { get; set; }
|
||
public string? Link { get; set; }
|
||
public bool? IsIframe { get; set; }
|
||
public List<string>? Roles { get; set; }
|
||
}
|