feat: 添加系统菜单保护功能,防止删除内置菜单
This commit is contained in:
parent
eda41878a6
commit
dcda5fa528
@ -1,7 +1,9 @@
|
|||||||
|
using AmtScanner.Api.Data;
|
||||||
using AmtScanner.Api.Models;
|
using AmtScanner.Api.Models;
|
||||||
using AmtScanner.Api.Services;
|
using AmtScanner.Api.Services;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace AmtScanner.Api.Controllers;
|
namespace AmtScanner.Api.Controllers;
|
||||||
|
|
||||||
@ -12,10 +14,12 @@ namespace AmtScanner.Api.Controllers;
|
|||||||
public class MenuController : ControllerBase
|
public class MenuController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly IMenuService _menuService;
|
private readonly IMenuService _menuService;
|
||||||
|
private readonly AppDbContext _context;
|
||||||
|
|
||||||
public MenuController(IMenuService menuService)
|
public MenuController(IMenuService menuService, AppDbContext context)
|
||||||
{
|
{
|
||||||
_menuService = menuService;
|
_menuService = menuService;
|
||||||
|
_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -45,4 +49,195 @@ public class MenuController : ControllerBase
|
|||||||
var menus = await _menuService.GetAllMenusAsync();
|
var menus = await _menuService.GetAllMenusAsync();
|
||||||
return Ok(ApiResponse<List<MenuDto>>.Success(menus));
|
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; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -101,16 +101,16 @@ public static class DbSeeder
|
|||||||
|
|
||||||
var menus = new List<Menu>
|
var menus = new List<Menu>
|
||||||
{
|
{
|
||||||
// 仪表盘菜单 - 与前端 dashboard.ts 匹配
|
// 仪表盘菜单 - 与前端 dashboard.ts 匹配(系统内置)
|
||||||
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" },
|
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" },
|
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 },
|
||||||
|
|
||||||
// 系统管理菜单 - 与前端 system.ts 匹配
|
// 系统管理菜单 - 与前端 system.ts 匹配(系统内置)
|
||||||
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" },
|
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" },
|
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" },
|
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" },
|
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" }
|
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 }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 使用 IDENTITY_INSERT 插入带 ID 的数据
|
// 使用 IDENTITY_INSERT 插入带 ID 的数据
|
||||||
|
|||||||
662
backend-csharp/AmtScanner.Api/Migrations/20260120082406_AddMenuIsSystemColumn.Designer.cs
generated
Normal file
662
backend-csharp/AmtScanner.Api/Migrations/20260120082406_AddMenuIsSystemColumn.Designer.cs
generated
Normal file
@ -0,0 +1,662 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using AmtScanner.Api.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AmtScanner.Api.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(AppDbContext))]
|
||||||
|
[Migration("20260120082406_AddMenuIsSystemColumn")]
|
||||||
|
partial class AddMenuIsSystemColumn
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "8.0.0")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.AmtCredential", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDefault")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.ToTable("AmtCredentials");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.AmtDevice", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<bool>("AmtOnline")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<DateTime>("DiscoveredAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Hostname")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("IpAddress")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("varchar(50)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastSeenAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<int>("MajorVersion")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("MinorVersion")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<bool>("OsOnline")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<int>("ProvisioningState")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("IpAddress")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("AmtDevices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.HardwareInfo", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<long>("DeviceId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("LastUpdated")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<int?>("ProcessorCores")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("ProcessorCurrentClockSpeed")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int?>("ProcessorMaxClockSpeed")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("ProcessorModel")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("ProcessorThreads")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("SystemManufacturer")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("SystemModel")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("SystemSerialNumber")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<long?>("TotalMemoryBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DeviceId");
|
||||||
|
|
||||||
|
b.HasIndex("LastUpdated");
|
||||||
|
|
||||||
|
b.ToTable("HardwareInfos");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.MemoryModule", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<long?>("CapacityBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<long>("HardwareInfoId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<string>("Manufacturer")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("MemoryType")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("PartNumber")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("SerialNumber")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("SlotLocation")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<int?>("SpeedMHz")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("HardwareInfoId");
|
||||||
|
|
||||||
|
b.ToTable("MemoryModules");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.Menu", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("AuthList")
|
||||||
|
.HasMaxLength(1000)
|
||||||
|
.HasColumnType("varchar(1000)");
|
||||||
|
|
||||||
|
b.Property<string>("Component")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Icon")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsHide")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsHideTab")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsIframe")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSystem")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("KeepAlive")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Link")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.Property<int?>("ParentId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Path")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Roles")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<int>("Sort")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.HasIndex("ParentId");
|
||||||
|
|
||||||
|
b.ToTable("Menus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.RemoteAccessToken", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<long>("DeviceId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("ExpiresAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsUsed")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<int>("MaxUseCount")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Note")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<string>("Token")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(64)
|
||||||
|
.HasColumnType("varchar(64)");
|
||||||
|
|
||||||
|
b.Property<int>("UseCount")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("UsedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<long?>("WindowsCredentialId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("DeviceId");
|
||||||
|
|
||||||
|
b.HasIndex("Token")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.HasIndex("WindowsCredentialId");
|
||||||
|
|
||||||
|
b.ToTable("RemoteAccessTokens");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.Role", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<bool>("Enabled")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("RoleCode")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(50)
|
||||||
|
.HasColumnType("varchar(50)");
|
||||||
|
|
||||||
|
b.Property<string>("RoleName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("RoleCode")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Roles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.RoleMenu", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("MenuId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("RoleId", "MenuId");
|
||||||
|
|
||||||
|
b.HasIndex("MenuId");
|
||||||
|
|
||||||
|
b.ToTable("RoleMenus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.StorageDevice", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<long?>("CapacityBytes")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<string>("DeviceId")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<long>("HardwareInfoId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<string>("InterfaceType")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.Property<string>("Model")
|
||||||
|
.HasColumnType("longtext");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("HardwareInfoId");
|
||||||
|
|
||||||
|
b.ToTable("StorageDevices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<string>("Avatar")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("CreatedBy")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("Email")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Gender")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(1)
|
||||||
|
.HasColumnType("varchar(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDeleted")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("NickName")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("PasswordHash")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Phone")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("varchar(20)");
|
||||||
|
|
||||||
|
b.Property<string>("RefreshToken")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("RefreshTokenExpiryTime")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Status")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(1)
|
||||||
|
.HasColumnType("varchar(1)");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("UpdatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("UpdatedBy")
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.Property<string>("UserName")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(100)
|
||||||
|
.HasColumnType("varchar(100)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("UserName")
|
||||||
|
.IsUnique();
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.UserRole", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.Property<int>("RoleId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("UserId", "RoleId");
|
||||||
|
|
||||||
|
b.HasIndex("RoleId");
|
||||||
|
|
||||||
|
b.ToTable("UserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.WindowsCredential", b =>
|
||||||
|
{
|
||||||
|
b.Property<long>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Domain")
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsDefault")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.Property<string>("Note")
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<string>("Password")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(500)
|
||||||
|
.HasColumnType("varchar(500)");
|
||||||
|
|
||||||
|
b.Property<DateTime>("UpdatedAt")
|
||||||
|
.HasColumnType("datetime(6)");
|
||||||
|
|
||||||
|
b.Property<string>("Username")
|
||||||
|
.IsRequired()
|
||||||
|
.HasMaxLength(200)
|
||||||
|
.HasColumnType("varchar(200)");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("Name");
|
||||||
|
|
||||||
|
b.ToTable("WindowsCredentials");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.HardwareInfo", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.AmtDevice", "Device")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("DeviceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Device");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.MemoryModule", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.HardwareInfo", "HardwareInfo")
|
||||||
|
.WithMany("MemoryModules")
|
||||||
|
.HasForeignKey("HardwareInfoId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("HardwareInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.Menu", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.Menu", "Parent")
|
||||||
|
.WithMany("Children")
|
||||||
|
.HasForeignKey("ParentId")
|
||||||
|
.OnDelete(DeleteBehavior.Restrict);
|
||||||
|
|
||||||
|
b.Navigation("Parent");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.RemoteAccessToken", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.AmtDevice", "Device")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("DeviceId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AmtScanner.Api.Models.WindowsCredential", "WindowsCredential")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("WindowsCredentialId")
|
||||||
|
.OnDelete(DeleteBehavior.SetNull);
|
||||||
|
|
||||||
|
b.Navigation("Device");
|
||||||
|
|
||||||
|
b.Navigation("WindowsCredential");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.RoleMenu", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.Menu", "Menu")
|
||||||
|
.WithMany("RoleMenus")
|
||||||
|
.HasForeignKey("MenuId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AmtScanner.Api.Models.Role", "Role")
|
||||||
|
.WithMany("RoleMenus")
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Menu");
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.StorageDevice", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.HardwareInfo", "HardwareInfo")
|
||||||
|
.WithMany("StorageDevices")
|
||||||
|
.HasForeignKey("HardwareInfoId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("HardwareInfo");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.UserRole", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("AmtScanner.Api.Models.Role", "Role")
|
||||||
|
.WithMany("UserRoles")
|
||||||
|
.HasForeignKey("RoleId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("AmtScanner.Api.Models.User", "User")
|
||||||
|
.WithMany("UserRoles")
|
||||||
|
.HasForeignKey("UserId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Role");
|
||||||
|
|
||||||
|
b.Navigation("User");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.HardwareInfo", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("MemoryModules");
|
||||||
|
|
||||||
|
b.Navigation("StorageDevices");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.Menu", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Children");
|
||||||
|
|
||||||
|
b.Navigation("RoleMenus");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.Role", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("RoleMenus");
|
||||||
|
|
||||||
|
b.Navigation("UserRoles");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("AmtScanner.Api.Models.User", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("UserRoles");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace AmtScanner.Api.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddMenuIsSystemColumn : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "IsSystem",
|
||||||
|
table: "Menus",
|
||||||
|
type: "tinyint(1)",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "IsSystem",
|
||||||
|
table: "Menus");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -224,6 +224,9 @@ namespace AmtScanner.Api.Migrations
|
|||||||
b.Property<bool>("IsIframe")
|
b.Property<bool>("IsIframe")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSystem")
|
||||||
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
b.Property<bool>("KeepAlive")
|
b.Property<bool>("KeepAlive")
|
||||||
.HasColumnType("tinyint(1)");
|
.HasColumnType("tinyint(1)");
|
||||||
|
|
||||||
|
|||||||
@ -73,6 +73,11 @@ public class Menu
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool IsIframe { get; set; } = false;
|
public bool IsIframe { get; set; } = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否系统内置菜单(不可删除)
|
||||||
|
/// </summary>
|
||||||
|
public bool IsSystem { get; set; } = false;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否隐藏标签页
|
/// 是否隐藏标签页
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user