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; /// 角色管理(RBAC) [ApiController] [Route("api/roles")] [Authorize] public class RolesController(AppDbContext db) : ControllerBase { /// 角色列表 [HttpGet] public async Task>> List(string? keyword, [FromQuery] int page = 1, [FromQuery] int pageSize = 20) { var query = db.SysRoles.AsQueryable(); if (!string.IsNullOrWhiteSpace(keyword)) query = query.Where(r => r.Name.Contains(keyword) || r.Code.Contains(keyword)); var total = await query.CountAsync(); var items = await query.OrderBy(r => r.Id) .Skip((page - 1) * pageSize).Take(pageSize) .Select(r => new RoleDto( r.Id, r.Name, r.Code, r.Description, r.IsSystem, db.SysRoleMenus.Where(rm => rm.RoleId == r.Id).Select(rm => rm.MenuId).ToArray())) .ToListAsync(); return Ok(new PagedResult(items, total)); } /// 全部角色(下拉选择用) [HttpGet("all")] public async Task All() { var items = await db.SysRoles.AsNoTracking().OrderBy(r => r.Id) .Select(r => new { r.Id, r.Name, r.Code }).ToListAsync(); return Ok(items); } /// 新增角色 [HttpPost] public async Task Create(RoleSaveRequest req) { if (string.IsNullOrWhiteSpace(req.Code)) return BadRequest(new { message = "角色编码不能为空" }); if (await db.SysRoles.AnyAsync(r => r.Code == req.Code.Trim())) return BadRequest(new { message = "角色编码已存在" }); var role = new SysRole { Name = req.Name, Code = req.Code.Trim(), Description = req.Description, CreatedAt = DateTime.Now }; db.SysRoles.Add(role); await db.SaveChangesAsync(); if (req.MenuIds.Length > 0) { db.SysRoleMenus.AddRange(req.MenuIds.Distinct().Select(mid => new SysRoleMenu { RoleId = role.Id, MenuId = mid })); await db.SaveChangesAsync(); } return Ok(new { message = "保存成功", id = role.Id }); } /// 修改角色 [HttpPut("{id:int}")] public async Task Update(int id, RoleSaveRequest req) { var role = await db.SysRoles.FindAsync(id); if (role is null) return NotFound(); role.Name = req.Name; role.Description = req.Description; // 系统内置角色编码不可改 if (!role.IsSystem) role.Code = req.Code.Trim(); var old = await db.SysRoleMenus.Where(rm => rm.RoleId == id).Select(rm => rm.MenuId).ToListAsync(); var newMenuIds = req.MenuIds.Distinct().ToArray(); var toRemove = old.Where(m => !newMenuIds.Contains(m)).ToList(); var toAdd = newMenuIds.Where(m => !old.Contains(m)).ToList(); if (toRemove.Count > 0) db.SysRoleMenus.RemoveRange(toRemove.Select(m => new SysRoleMenu { RoleId = id, MenuId = m })); if (toAdd.Count > 0) db.SysRoleMenus.AddRange(toAdd.Select(m => new SysRoleMenu { RoleId = id, MenuId = m })); await db.SaveChangesAsync(); return Ok(new { message = "保存成功" }); } /// 删除角色(系统内置或有用户引用时禁止删除) [HttpDelete("{id:int}")] public async Task Delete(int id) { var role = await db.SysRoles.FindAsync(id); if (role is null) return NotFound(); if (role.IsSystem) return BadRequest(new { message = "系统内置角色不可删除" }); if (await db.Users.AnyAsync(u => u.RoleId == id)) return BadRequest(new { message = "该角色已被用户使用,请先解除关联" }); db.SysRoleMenus.RemoveRange(db.SysRoleMenus.Where(rm => rm.RoleId == id)); db.SysRoles.Remove(role); await db.SaveChangesAsync(); return Ok(new { message = "删除成功" }); } }