Compare commits
6 Commits
c21b8be5e1
...
994bd60872
Author | SHA1 | Date | |
---|---|---|---|
994bd60872 | |||
1ee4c59f6c | |||
41fa797284 | |||
1e839e5217 | |||
085442d54e | |||
7326a190d9 |
1
.idea/.idea.AGSS/.idea/.name
generated
Normal file
1
.idea/.idea.AGSS/.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
||||
AGSS
|
@ -144,7 +144,7 @@ public class AdminRoleControllers:ControllerBase
|
||||
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> SetMenu([FromBody]MenuRequest request)
|
||||
public async Task<IActionResult> SetMenu([FromBody]UserMenuRequest request)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(request.Id) || string.IsNullOrWhiteSpace(request.MenuName))
|
||||
{
|
||||
|
72
AGSS/Controllers/Menu/MenuController.cs
Normal file
72
AGSS/Controllers/Menu/MenuController.cs
Normal file
@ -0,0 +1,72 @@
|
||||
using AGSS.Models.DTOs;
|
||||
using AGSS.Models.Template;
|
||||
using AGSS.Services;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace AGSS.Controllers.Menu;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class MenuController : ControllerBase
|
||||
{
|
||||
private readonly MenuService _menuService;
|
||||
|
||||
public MenuController(MenuService menuService)
|
||||
{
|
||||
_menuService = menuService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增父级菜单
|
||||
/// </summary>
|
||||
[HttpPost("create-parent")]
|
||||
public async Task<ReturnTemplate> CreateParentMenu([FromBody] MenuRequest request)
|
||||
{
|
||||
return await _menuService.CreateParentMenu(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑父级菜单
|
||||
/// </summary>
|
||||
[HttpPut("update-parent")]
|
||||
public async Task<ReturnTemplate> UpdateParentMenu([FromBody] MenuRequest request)
|
||||
{
|
||||
return await _menuService.UpdateParentMenu(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增子级菜单
|
||||
/// </summary>
|
||||
[HttpPost("create-child")]
|
||||
public async Task<ReturnTemplate> CreateChildMenu([FromBody] MenuRequest request)
|
||||
{
|
||||
return await _menuService.CreateChildMenu(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑子级菜单
|
||||
/// </summary>
|
||||
[HttpPut("update-child")]
|
||||
public async Task<ReturnTemplate> UpdateChildMenu([FromBody] MenuRequest request)
|
||||
{
|
||||
return await _menuService.UpdateChildMenu(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询菜单全量返回(树形结构)
|
||||
/// </summary>
|
||||
[HttpGet("all")]
|
||||
public async Task<ReturnTemplate> GetAllMenus()
|
||||
{
|
||||
return await _menuService.GetAllMenus();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除菜单(递归删除)
|
||||
/// </summary>
|
||||
[HttpDelete("delete/{uuid}")]
|
||||
public async Task<ReturnTemplate> DeleteMenu(string uuid)
|
||||
{
|
||||
return await _menuService.DeleteMenu(uuid);
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ namespace AGSS.DbSet
|
||||
public override DbSet<UserModel> Users { get; set; }
|
||||
public override DbSet<RoleModel> Roles { get; set; }
|
||||
public DbSet<DictionaryModel> Dictionaries { get; set; }
|
||||
public DbSet<MenuModel> Menus { get; set; }
|
||||
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
@ -25,6 +26,14 @@ namespace AGSS.DbSet
|
||||
modelBuilder.Entity<DictionaryModel>()
|
||||
.HasKey(d => d.Uuid); // 假设 Id 是 DictionaryModel 的主键字段
|
||||
|
||||
modelBuilder.Entity<MenuModel>()
|
||||
.HasKey(m => m.Uuid);
|
||||
|
||||
modelBuilder.Entity<MenuModel>()
|
||||
.HasOne<MenuModel>()
|
||||
.WithMany()
|
||||
.HasForeignKey(m => m.ParentId)
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
|
||||
// 在这里添加额外的配置,如果需要的话
|
||||
// 例如:
|
||||
|
425
AGSS/Migrations/20250714031454_AddMenuTable.Designer.cs
generated
Normal file
425
AGSS/Migrations/20250714031454_AddMenuTable.Designer.cs
generated
Normal file
@ -0,0 +1,425 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using AGSS.DbSet;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AGSS.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250714031454_AddMenuTable")]
|
||||
partial class AddMenuTable
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.DictionaryModel", b =>
|
||||
{
|
||||
b.Property<string>("Uuid")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("CreateUserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Label")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LabelEn")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParentValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Remark")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Tag")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Uuid");
|
||||
|
||||
b.ToTable("Dictionaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.Property<string>("Uuid")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Adaptability")
|
||||
.IsRequired()
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("Component")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<DateTime>("CreateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Icon")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Label")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("MenuCode")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("ParentId")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Query")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("Sort")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1)
|
||||
.HasColumnType("character varying(1)");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Uuid");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("Menus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Birthday")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Config")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("JobCode")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<string>("JobName")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("MenuCode")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("MenuName")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Sex")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.MenuModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.RoleModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.RoleModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
56
AGSS/Migrations/20250714031454_AddMenuTable.cs
Normal file
56
AGSS/Migrations/20250714031454_AddMenuTable.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AGSS.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddMenuTable : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Menus",
|
||||
columns: table => new
|
||||
{
|
||||
Uuid = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: false),
|
||||
ParentId = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true),
|
||||
Path = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Label = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
Icon = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: false),
|
||||
MenuCode = table.Column<string>(type: "character varying(500)", maxLength: 500, nullable: true),
|
||||
Adaptability = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false),
|
||||
Component = table.Column<string>(type: "character varying(200)", maxLength: 200, nullable: false),
|
||||
Sort = table.Column<int>(type: "integer", nullable: false),
|
||||
Status = table.Column<string>(type: "character varying(1)", maxLength: 1, nullable: false),
|
||||
Query = table.Column<string>(type: "character varying(1000)", maxLength: 1000, nullable: true),
|
||||
CreateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
UpdateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Menus", x => x.Uuid);
|
||||
table.ForeignKey(
|
||||
name: "FK_Menus_Menus_ParentId",
|
||||
column: x => x.ParentId,
|
||||
principalTable: "Menus",
|
||||
principalColumn: "Uuid",
|
||||
onDelete: ReferentialAction.Restrict);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Menus_ParentId",
|
||||
table: "Menus",
|
||||
column: "ParentId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Menus");
|
||||
}
|
||||
}
|
||||
}
|
425
AGSS/Migrations/20250714035418_AddMenuTableV2.Designer.cs
generated
Normal file
425
AGSS/Migrations/20250714035418_AddMenuTableV2.Designer.cs
generated
Normal file
@ -0,0 +1,425 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using AGSS.DbSet;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AGSS.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250714035418_AddMenuTableV2")]
|
||||
partial class AddMenuTableV2
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "9.0.6")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.DictionaryModel", b =>
|
||||
{
|
||||
b.Property<string>("Uuid")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<DateTime>("CreateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("CreateUserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Label")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LabelEn")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParentId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ParentValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Remark")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Tag")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Uuid");
|
||||
|
||||
b.ToTable("Dictionaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.Property<string>("Uuid")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Adaptability")
|
||||
.IsRequired()
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("Component")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<DateTime>("CreateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Icon")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Label")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("MenuCode")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("ParentId")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Query")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("Sort")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1)
|
||||
.HasColumnType("character varying(1)");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Uuid");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("Menus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("AspNetRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.UserModel", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Birthday")
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Config")
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("JobCode")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<string>("JobName")
|
||||
.HasMaxLength(10)
|
||||
.HasColumnType("character varying(10)");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("MenuCode")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("MenuName")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Sex")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("AspNetUsers", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetRoleClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserClaims", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("AspNetUserLogins", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("AspNetUserRoles", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.MenuModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.RoleModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.RoleModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.UserModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
22
AGSS/Migrations/20250714035418_AddMenuTableV2.cs
Normal file
22
AGSS/Migrations/20250714035418_AddMenuTableV2.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace AGSS.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddMenuTableV2 : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -67,6 +67,70 @@ namespace AGSS.Migrations
|
||||
b.ToTable("Dictionaries");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.Property<string>("Uuid")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Adaptability")
|
||||
.IsRequired()
|
||||
.HasMaxLength(20)
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("Component")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<DateTime>("CreateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Icon")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Label")
|
||||
.IsRequired()
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("MenuCode")
|
||||
.HasMaxLength(500)
|
||||
.HasColumnType("character varying(500)");
|
||||
|
||||
b.Property<string>("ParentId")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Path")
|
||||
.IsRequired()
|
||||
.HasMaxLength(200)
|
||||
.HasColumnType("character varying(200)");
|
||||
|
||||
b.Property<string>("Query")
|
||||
.HasMaxLength(1000)
|
||||
.HasColumnType("character varying(1000)");
|
||||
|
||||
b.Property<int>("Sort")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(1)
|
||||
.HasColumnType("character varying(1)");
|
||||
|
||||
b.Property<DateTime?>("UpdateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.HasKey("Uuid");
|
||||
|
||||
b.HasIndex("ParentId");
|
||||
|
||||
b.ToTable("Menus");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.RoleModel", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
@ -294,6 +358,14 @@ namespace AGSS.Migrations
|
||||
b.ToTable("AspNetUserTokens", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("AGSS.Models.Entities.MenuModel", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.MenuModel", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("ParentId")
|
||||
.OnDelete(DeleteBehavior.Restrict);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("AGSS.Models.Entities.RoleModel", null)
|
||||
|
39
AGSS/Models/DTOs/MenuDto.cs
Normal file
39
AGSS/Models/DTOs/MenuDto.cs
Normal file
@ -0,0 +1,39 @@
|
||||
namespace AGSS.Models.DTOs;
|
||||
|
||||
public class MenuRequest
|
||||
{
|
||||
public string? Uuid { get; set; }
|
||||
public string? ParentId { get; set; }
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
public string? MenuCode { get; set; }
|
||||
public string Adaptability { get; set; } = "pc";
|
||||
public string Component { get; set; } = string.Empty;
|
||||
public int Sort { get; set; }
|
||||
public string Status { get; set; } = "1";
|
||||
public string? Query { get; set; }
|
||||
}
|
||||
|
||||
public class MenuResponse
|
||||
{
|
||||
public string Uuid { get; set; } = string.Empty;
|
||||
public string? ParentId { get; set; }
|
||||
public string Path { get; set; } = string.Empty;
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
public string? MenuCode { get; set; }
|
||||
public string Adaptability { get; set; } = string.Empty;
|
||||
public string Component { get; set; } = string.Empty;
|
||||
public int Sort { get; set; }
|
||||
public string Status { get; set; } = string.Empty;
|
||||
public string? Query { get; set; }
|
||||
public DateTime CreateTime { get; set; }
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
public List<MenuResponse> Children { get; set; } = new();
|
||||
}
|
||||
|
||||
public class DeleteMenuRequest
|
||||
{
|
||||
public string Uuid { get; set; } = string.Empty;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
namespace AGSS.Models.DTOs;
|
||||
|
||||
public struct MenuRequest
|
||||
public struct UserMenuRequest
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string MenuName { get; set; }
|
||||
|
43
AGSS/Models/Entities/MenuModel.cs
Normal file
43
AGSS/Models/Entities/MenuModel.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AGSS.Models.Entities;
|
||||
|
||||
public class MenuModel
|
||||
{
|
||||
[Key]
|
||||
[MaxLength(50)]
|
||||
public string Uuid { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(50)]
|
||||
public string? ParentId { get; set; }
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Path { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(100)]
|
||||
public string Label { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(100)]
|
||||
public string Icon { get; set; } = string.Empty;
|
||||
|
||||
[MaxLength(500)]
|
||||
public string? MenuCode { get; set; }
|
||||
|
||||
[MaxLength(20)]
|
||||
public string Adaptability { get; set; } = "pc";
|
||||
|
||||
[MaxLength(200)]
|
||||
public string Component { get; set; } = string.Empty;
|
||||
|
||||
public int Sort { get; set; }
|
||||
|
||||
[MaxLength(1)]
|
||||
public string Status { get; set; } = "1";
|
||||
|
||||
[MaxLength(1000)]
|
||||
public string? Query { get; set; }
|
||||
|
||||
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||
|
||||
public DateTime? UpdateTime { get; set; }
|
||||
}
|
@ -55,6 +55,7 @@ builder.Services.AddIdentityCore<UserModel>(options =>
|
||||
|
||||
builder.Services.AddScoped<Jwt>();
|
||||
builder.Services.AddScoped<UserService>();
|
||||
builder.Services.AddScoped<MenuService>();
|
||||
|
||||
|
||||
|
||||
|
327
AGSS/Services/MenuService.cs
Normal file
327
AGSS/Services/MenuService.cs
Normal file
@ -0,0 +1,327 @@
|
||||
using AGSS.DbSet;
|
||||
using AGSS.Models.DTOs;
|
||||
using AGSS.Models.Entities;
|
||||
using AGSS.Models.Template;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AGSS.Services;
|
||||
|
||||
public class MenuService
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public MenuService(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增父级菜单
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> CreateParentMenu(MenuRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var menu = new MenuModel
|
||||
{
|
||||
Uuid = Guid.NewGuid().ToString(),
|
||||
ParentId = null,
|
||||
Path = request.Path,
|
||||
Label = request.Label,
|
||||
Icon = request.Icon,
|
||||
MenuCode = request.MenuCode,
|
||||
Adaptability = request.Adaptability,
|
||||
Component = request.Component,
|
||||
Sort = request.Sort,
|
||||
Status = request.Status,
|
||||
Query = request.Query,
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
|
||||
_context.Menus.Add(menu);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return new ReturnTemplate(200, "父级菜单创建成功", menu);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"创建父级菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑父级菜单
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> UpdateParentMenu(MenuRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.Uuid))
|
||||
{
|
||||
return new ReturnTemplate(400, "UUID不能为空", null);
|
||||
}
|
||||
|
||||
var menu = await _context.Menus.FirstOrDefaultAsync(m => m.Uuid == request.Uuid);
|
||||
if (menu == null)
|
||||
{
|
||||
return new ReturnTemplate(404, "菜单不存在", null);
|
||||
}
|
||||
|
||||
// 确保是父级菜单
|
||||
if (!string.IsNullOrEmpty(menu.ParentId))
|
||||
{
|
||||
return new ReturnTemplate(400, "只能编辑父级菜单", null);
|
||||
}
|
||||
|
||||
menu.Path = request.Path;
|
||||
menu.Label = request.Label;
|
||||
menu.Icon = request.Icon;
|
||||
menu.MenuCode = request.MenuCode;
|
||||
menu.Adaptability = request.Adaptability;
|
||||
menu.Component = request.Component;
|
||||
menu.Sort = request.Sort;
|
||||
menu.Status = request.Status;
|
||||
menu.Query = request.Query;
|
||||
menu.UpdateTime = DateTime.Now;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return new ReturnTemplate(200, "父级菜单更新成功", menu);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"更新父级菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 新增子级菜单
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> CreateChildMenu(MenuRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.ParentId))
|
||||
{
|
||||
return new ReturnTemplate(400, "父级ID不能为空", null);
|
||||
}
|
||||
|
||||
// 验证父级菜单是否存在
|
||||
var parentMenu = await _context.Menus.FirstOrDefaultAsync(m => m.Uuid == request.ParentId);
|
||||
if (parentMenu == null)
|
||||
{
|
||||
return new ReturnTemplate(404, "父级菜单不存在", null);
|
||||
}
|
||||
|
||||
var menu = new MenuModel
|
||||
{
|
||||
Uuid = Guid.NewGuid().ToString(),
|
||||
ParentId = request.ParentId,
|
||||
Path = request.Path,
|
||||
Label = request.Label,
|
||||
Icon = request.Icon,
|
||||
MenuCode = request.MenuCode,
|
||||
Adaptability = request.Adaptability,
|
||||
Component = request.Component,
|
||||
Sort = request.Sort,
|
||||
Status = request.Status,
|
||||
Query = request.Query,
|
||||
CreateTime = DateTime.Now
|
||||
};
|
||||
|
||||
_context.Menus.Add(menu);
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return new ReturnTemplate(200, "子级菜单创建成功", menu);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"创建子级菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑子级菜单
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> UpdateChildMenu(MenuRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(request.Uuid))
|
||||
{
|
||||
return new ReturnTemplate(400, "UUID不能为空", null);
|
||||
}
|
||||
|
||||
var menu = await _context.Menus.FirstOrDefaultAsync(m => m.Uuid == request.Uuid);
|
||||
if (menu == null)
|
||||
{
|
||||
return new ReturnTemplate(404, "菜单不存在", null);
|
||||
}
|
||||
|
||||
// 确保是子级菜单
|
||||
if (string.IsNullOrEmpty(menu.ParentId))
|
||||
{
|
||||
return new ReturnTemplate(400, "只能编辑子级菜单", null);
|
||||
}
|
||||
|
||||
menu.Path = request.Path;
|
||||
menu.Label = request.Label;
|
||||
menu.Icon = request.Icon;
|
||||
menu.MenuCode = request.MenuCode;
|
||||
menu.Adaptability = request.Adaptability;
|
||||
menu.Component = request.Component;
|
||||
menu.Sort = request.Sort;
|
||||
menu.Status = request.Status;
|
||||
menu.Query = request.Query;
|
||||
menu.UpdateTime = DateTime.Now;
|
||||
|
||||
await _context.SaveChangesAsync();
|
||||
|
||||
return new ReturnTemplate(200, "子级菜单更新成功", menu);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"更新子级菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询菜单全量返回(树形结构)
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> GetAllMenus()
|
||||
{
|
||||
try
|
||||
{
|
||||
var allMenus = await _context.Menus
|
||||
.OrderBy(m => m.Sort)
|
||||
.ToListAsync();
|
||||
|
||||
var menuTree = BuildMenuTree(allMenus);
|
||||
|
||||
return new ReturnTemplate(200, "成功", menuTree);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"查询菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除菜单(递归删除)
|
||||
/// </summary>
|
||||
public async Task<ReturnTemplate> DeleteMenu(string uuid)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(uuid))
|
||||
{
|
||||
return new ReturnTemplate(400, "UUID不能为空", null);
|
||||
}
|
||||
|
||||
var menuToDelete = await _context.Menus.FirstOrDefaultAsync(m => m.Uuid == uuid);
|
||||
if (menuToDelete == null)
|
||||
{
|
||||
return new ReturnTemplate(404, "菜单不存在", null);
|
||||
}
|
||||
|
||||
// 递归删除所有子菜单
|
||||
await DeleteMenuRecursive(uuid);
|
||||
|
||||
return new ReturnTemplate(200, "菜单删除成功", null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return new ReturnTemplate(500, $"删除菜单失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 递归删除菜单及其子菜单
|
||||
/// </summary>
|
||||
private async Task DeleteMenuRecursive(string parentUuid)
|
||||
{
|
||||
var children = await _context.Menus.Where(m => m.ParentId == parentUuid).ToListAsync();
|
||||
|
||||
foreach (var child in children)
|
||||
{
|
||||
await DeleteMenuRecursive(child.Uuid);
|
||||
}
|
||||
|
||||
var menu = await _context.Menus.FirstOrDefaultAsync(m => m.Uuid == parentUuid);
|
||||
if (menu != null)
|
||||
{
|
||||
_context.Menus.Remove(menu);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建菜单树形结构
|
||||
/// </summary>
|
||||
private List<MenuResponse> BuildMenuTree(List<MenuModel> allMenus)
|
||||
{
|
||||
var menuDict = allMenus.ToDictionary(m => m.Uuid);
|
||||
var rootMenus = new List<MenuResponse>();
|
||||
|
||||
foreach (var menu in allMenus)
|
||||
{
|
||||
var menuResponse = new MenuResponse
|
||||
{
|
||||
Uuid = menu.Uuid,
|
||||
ParentId = menu.ParentId,
|
||||
Path = menu.Path,
|
||||
Label = menu.Label,
|
||||
Icon = menu.Icon,
|
||||
MenuCode = menu.MenuCode,
|
||||
Adaptability = menu.Adaptability,
|
||||
Component = menu.Component,
|
||||
Sort = menu.Sort,
|
||||
Status = menu.Status,
|
||||
Query = menu.Query,
|
||||
CreateTime = menu.CreateTime,
|
||||
UpdateTime = menu.UpdateTime
|
||||
};
|
||||
|
||||
if (string.IsNullOrEmpty(menu.ParentId))
|
||||
{
|
||||
// 根菜单
|
||||
rootMenus.Add(menuResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 子菜单
|
||||
if (menuDict.TryGetValue(menu.ParentId, out var parentMenu))
|
||||
{
|
||||
var parentResponse = FindMenuResponse(rootMenus, menu.ParentId);
|
||||
if (parentResponse != null)
|
||||
{
|
||||
parentResponse.Children.Add(menuResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rootMenus;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在菜单树中查找指定UUID的菜单响应对象
|
||||
/// </summary>
|
||||
private MenuResponse? FindMenuResponse(List<MenuResponse> menus, string uuid)
|
||||
{
|
||||
foreach (var menu in menus)
|
||||
{
|
||||
if (menu.Uuid == uuid)
|
||||
{
|
||||
return menu;
|
||||
}
|
||||
|
||||
var found = FindMenuResponse(menu.Children, uuid);
|
||||
if (found != null)
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user