Platform upgrade: login auth fix, OCR/OSS upload, system menus and dicts, weather dashboard, weighing and invoice modules
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
using System.Security.Claims;
|
||||
using AgriculturalPlatform.Api.Data;
|
||||
using AgriculturalPlatform.Api.Dtos;
|
||||
using AgriculturalPlatform.Api.Models;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace AgriculturalPlatform.Api.Controllers;
|
||||
|
||||
/// <summary>菜单/权限管理</summary>
|
||||
[ApiController]
|
||||
[Route("api/menus")]
|
||||
[Authorize]
|
||||
public class MenusController(AppDbContext db) : ControllerBase
|
||||
{
|
||||
/// <summary>菜单树(全部)</summary>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> Tree()
|
||||
{
|
||||
var menus = await db.SysMenus.AsNoTracking().OrderBy(m => m.Sort).ThenBy(m => m.Id).ToListAsync();
|
||||
return Ok(BuildTree(menus, null));
|
||||
}
|
||||
|
||||
/// <summary>当前登录用户的菜单与权限</summary>
|
||||
[HttpGet("my")]
|
||||
public async Task<ActionResult> My()
|
||||
{
|
||||
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||
if (userId is null) return Unauthorized();
|
||||
|
||||
// 用户角色 -> 菜单
|
||||
var user = await db.Users.Include(u => u.SysRole).FirstOrDefaultAsync(u => u.Id == int.Parse(userId));
|
||||
if (user is null) return Unauthorized();
|
||||
|
||||
int[] menuIds;
|
||||
if (user.SysRole?.Code == "super_admin" || user.Role == UserRole.SuperAdmin)
|
||||
{
|
||||
menuIds = await db.SysMenus.Select(m => m.Id).ToArrayAsync();
|
||||
}
|
||||
else if (user.RoleId is int rid)
|
||||
{
|
||||
menuIds = await db.SysRoleMenus.Where(rm => rm.RoleId == rid).Select(rm => rm.MenuId).ToArrayAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
menuIds = Array.Empty<int>();
|
||||
}
|
||||
|
||||
var menus = await db.SysMenus.AsNoTracking()
|
||||
.Where(m => menuIds.Contains(m.Id))
|
||||
.OrderBy(m => m.Sort).ThenBy(m => m.Id)
|
||||
.ToListAsync();
|
||||
var tree = BuildTree(menus, null);
|
||||
var permissions = menus.Where(m => !string.IsNullOrWhiteSpace(m.Permission)).Select(m => m.Permission).Distinct().ToArray();
|
||||
return Ok(new { menus = tree, permissions });
|
||||
}
|
||||
|
||||
private static List<MenuDto> BuildTree(List<SysMenu> all, int? parentId)
|
||||
{
|
||||
return all.Where(m => m.ParentId == parentId)
|
||||
.Select(m => new MenuDto(
|
||||
m.Id, m.ParentId, m.Name, m.Path, m.Component, m.Icon, m.Type,
|
||||
m.Permission, m.Visible, m.Sort, BuildTree(all, m.Id)))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>新增菜单</summary>
|
||||
[HttpPost]
|
||||
public async Task<ActionResult> Create(MenuSaveRequest req)
|
||||
{
|
||||
var menu = new SysMenu
|
||||
{
|
||||
ParentId = req.ParentId, Name = req.Name, Path = req.Path, Component = req.Component,
|
||||
Icon = req.Icon, Type = req.Type, Permission = req.Permission, Visible = req.Visible,
|
||||
Sort = req.Sort, CreatedAt = DateTime.Now
|
||||
};
|
||||
db.SysMenus.Add(menu);
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { message = "保存成功", id = menu.Id });
|
||||
}
|
||||
|
||||
/// <summary>修改菜单</summary>
|
||||
[HttpPut("{id:int}")]
|
||||
public async Task<ActionResult> Update(int id, MenuSaveRequest req)
|
||||
{
|
||||
var menu = await db.SysMenus.FindAsync(id);
|
||||
if (menu is null) return NotFound();
|
||||
if (req.ParentId == id) return BadRequest(new { message = "父级不能选择自身" });
|
||||
|
||||
menu.ParentId = req.ParentId; menu.Name = req.Name; menu.Path = req.Path;
|
||||
menu.Component = req.Component; menu.Icon = req.Icon; menu.Type = req.Type;
|
||||
menu.Permission = req.Permission; menu.Visible = req.Visible; menu.Sort = req.Sort;
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { message = "保存成功" });
|
||||
}
|
||||
|
||||
/// <summary>删除菜单(有子菜单或已被角色引用时禁止删除)</summary>
|
||||
[HttpDelete("{id:int}")]
|
||||
public async Task<IActionResult> Delete(int id)
|
||||
{
|
||||
if (await db.SysMenus.AnyAsync(m => m.ParentId == id))
|
||||
return BadRequest(new { message = "请先删除子菜单" });
|
||||
if (await db.SysRoleMenus.AnyAsync(rm => rm.MenuId == id))
|
||||
return BadRequest(new { message = "该菜单已被角色引用,请先解除关联" });
|
||||
var menu = await db.SysMenus.FindAsync(id);
|
||||
if (menu is null) return NotFound();
|
||||
db.SysMenus.Remove(menu);
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { message = "删除成功" });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user