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;
///
/// 菜单控制器
///
[ApiController]
public class MenuController : ControllerBase
{
private readonly IMenuService _menuService;
private readonly AppDbContext _context;
public MenuController(IMenuService menuService, AppDbContext context)
{
_menuService = menuService;
_context = context;
}
///
/// 获取用户菜单(adminSystem 前端使用的路由)
///
[Authorize]
[HttpGet("api/v3/system/menus/simple")]
public async Task>>> GetUserMenus()
{
var userIdClaim = User.FindFirst("userId")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !int.TryParse(userIdClaim, out var userId))
{
return Ok(ApiResponse>.Fail(401, "无效的用户"));
}
var menus = await _menuService.GetUserMenusAsync(userId);
return Ok(ApiResponse>.Success(menus));
}
///
/// 获取所有菜单列表
///
[Authorize]
[HttpGet("api/menu/list")]
public async Task>>> GetAllMenus()
{
var menus = await _menuService.GetAllMenusAsync();
return Ok(ApiResponse>.Success(menus));
}
///
/// 创建菜单
///
[Authorize]
[HttpPost("api/menu")]
public async Task>> CreateMenu([FromBody] CreateMenuRequest request)
{
Console.WriteLine($"[CreateMenu] 收到请求: ParentId={request.ParentId}, Name={request.Name}, Path={request.Path}, Component={request.Component}");
// 处理路径:子菜单(有 ParentId)的路径不能以 / 开头
var menuPath = request.Path;
if (request.ParentId.HasValue && menuPath.StartsWith("/"))
{
// 子菜单:取最后一段路径作为相对路径
var pathParts = menuPath.Split('/', StringSplitOptions.RemoveEmptyEntries);
menuPath = pathParts.Length > 0 ? pathParts[^1] : menuPath.TrimStart('/');
Console.WriteLine($"[CreateMenu] 子菜单路径已修正: {request.Path} -> {menuPath}");
}
// 目录(无 ParentId)的路径必须以 / 开头
if (!request.ParentId.HasValue && !menuPath.StartsWith("/"))
{
menuPath = "/" + menuPath;
Console.WriteLine($"[CreateMenu] 目录路径已修正: {request.Path} -> {menuPath}");
}
// 检查 Name 是否唯一,如果重复则自动生成唯一名称
var menuName = request.Name;
if (await _context.Menus.AnyAsync(m => m.Name == menuName))
{
// 生成唯一名称:原名称 + 时间戳
menuName = $"{request.Name}_{DateTime.Now:yyyyMMddHHmmss}";
Console.WriteLine($"[CreateMenu] 菜单名称已修正(避免重复): {request.Name} -> {menuName}");
}
var menu = new Menu
{
ParentId = request.ParentId,
Name = menuName,
Path = menuPath,
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();
Console.WriteLine($"[CreateMenu] 菜单已创建: Id={menu.Id}, ParentId={menu.ParentId}");
// 如果有组件路径且不是目录组件,自动创建 Vue 组件文件
if (!string.IsNullOrEmpty(request.Component) &&
request.Component != "/index/index" &&
request.AutoCreateComponent)
{
try
{
await CreateVueComponentAsync(request.Component, request.Title ?? request.Name);
}
catch (Exception ex)
{
Console.WriteLine($"[CreateMenu] 创建组件文件失败: {ex.Message}");
// 不影响菜单创建,只是记录日志
}
}
return Ok(ApiResponse