Platform upgrade: login auth fix, OCR/OSS upload, system menus and dicts, weather dashboard, weighing and invoice modules

This commit is contained in:
2026-08-14 01:12:33 +08:00
parent c377421a3e
commit 8099ebae0a
75 changed files with 5611 additions and 473 deletions
@@ -0,0 +1,106 @@
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>角色管理(RBAC</summary>
[ApiController]
[Route("api/roles")]
[Authorize]
public class RolesController(AppDbContext db) : ControllerBase
{
/// <summary>角色列表</summary>
[HttpGet]
public async Task<ActionResult<PagedResult<RoleDto>>> 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<RoleDto>(items, total));
}
/// <summary>全部角色(下拉选择用)</summary>
[HttpGet("all")]
public async Task<ActionResult> All()
{
var items = await db.SysRoles.AsNoTracking().OrderBy(r => r.Id)
.Select(r => new { r.Id, r.Name, r.Code }).ToListAsync();
return Ok(items);
}
/// <summary>新增角色</summary>
[HttpPost]
public async Task<ActionResult> 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 });
}
/// <summary>修改角色</summary>
[HttpPut("{id:int}")]
public async Task<ActionResult> 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 = "保存成功" });
}
/// <summary>删除角色(系统内置或有用户引用时禁止删除)</summary>
[HttpDelete("{id:int}")]
public async Task<IActionResult> 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 = "删除成功" });
}
}