新增MES模块,包含供应商、客户、车辆和地磅数据记录管理功能,支持免密接口和数据同步。更新相关控制器、实体、服务和数据库配置,优化权限管理和数据字典支持,确保系统的灵活性和可扩展性。

This commit is contained in:
geht
2026-04-30 15:28:20 +08:00
parent 142a0bdaba
commit b03cbeff9b
121 changed files with 10540 additions and 424 deletions

View File

@@ -1,13 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YY.Admin.Core;
using YY.Admin.Services;
namespace YY.Admin.Services.Service.Menu
namespace YY.Admin.Services.Service.Menu;
public interface ISysMenuService
{
public interface ISysMenuService
{
Task<List<MenuOutput>> GetLoginMenuTree();
}
Task<List<MenuOutput>> GetLoginMenuTree();
/// <summary>
/// 菜单管理:加载全部菜单(含按钮类型),按排序与 Id 排序
/// </summary>
Task<List<SysMenu>> GetAllMenusForManageAsync();
/// <summary>
/// 新增菜单并可选关联当前用户租户
/// </summary>
Task<(bool ok, string message, long id)> CreateMenuAsync(SysMenu input);
/// <summary>
/// 更新菜单
/// </summary>
Task<(bool ok, string message)> UpdateMenuAsync(SysMenu input);
/// <summary>
/// 删除菜单(无子节点时)
/// </summary>
Task<(bool ok, string message)> DeleteMenuAsync(long id);
}

View File

@@ -1,10 +1,6 @@
using Mapster;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YY.Admin.Core;
using YY.Admin.Core.Session;
using YY.Admin.Services.Service.Role;
using YY.Admin.Services.Service.User;
@@ -132,5 +128,137 @@ namespace YY.Admin.Services.Service.Menu
.ToTreeAsync(u => u.Children, u => u.Pid, 0);
}
/// <inheritdoc />
public async Task<List<SysMenu>> GetAllMenusForManageAsync()
{
return await _dbContext.Queryable<SysMenu>()
.OrderBy(m => m.OrderNo)
.OrderBy(m => m.Id)
.ToListAsync();
}
/// <inheritdoc />
public async Task<(bool ok, string message, long id)> CreateMenuAsync(SysMenu input)
{
if (string.IsNullOrWhiteSpace(input.Title))
return (false, "菜单名称不能为空", 0);
var all = await GetAllMenusForManageAsync();
if (input.Pid != 0 && all.All(m => m.Id != input.Pid))
return (false, "父级菜单不存在", 0);
var id = SnowflakeId.Next();
input.Id = id;
input.CreateTime = DateTime.Now;
input.UpdateTime = null;
input.Children = new List<SysMenu>();
var n = await _dbContext.Insertable(input).ExecuteCommandAsync();
if (n <= 0)
return (false, "保存失败", 0);
await TryLinkCurrentTenantMenuAsync(id);
return (true, "保存成功", id);
}
/// <inheritdoc />
public async Task<(bool ok, string message)> UpdateMenuAsync(SysMenu input)
{
if (input.Id <= 0)
return (false, "无效的菜单 Id");
if (string.IsNullOrWhiteSpace(input.Title))
return (false, "菜单名称不能为空");
var all = await GetAllMenusForManageAsync();
var existing = all.FirstOrDefault(m => m.Id == input.Id);
if (existing == null)
return (false, "菜单不存在");
if (input.Pid != 0 && all.All(m => m.Id != input.Pid))
return (false, "父级菜单不存在");
if (NewParentIsInsideMenuSubtree(input.Id, input.Pid, all))
return (false, "不能将父级设为当前菜单或其子菜单");
existing.Pid = input.Pid;
existing.Type = input.Type;
existing.Name = input.Name;
existing.Path = input.Path;
existing.Component = input.Component;
existing.Redirect = input.Redirect;
existing.Permission = input.Permission;
existing.Title = input.Title.Trim();
existing.Icon = input.Icon;
existing.IsIframe = input.IsIframe;
existing.OutLink = input.OutLink;
existing.IsHide = input.IsHide;
existing.IsKeepAlive = input.IsKeepAlive;
existing.IsAffix = input.IsAffix;
existing.OrderNo = input.OrderNo;
existing.Status = input.Status;
existing.Remark = input.Remark;
existing.UpdateTime = DateTime.Now;
var n = await _dbContext.Updateable(existing).ExecuteCommandAsync();
return n > 0 ? (true, "保存成功") : (false, "更新失败");
}
/// <inheritdoc />
public async Task<(bool ok, string message)> DeleteMenuAsync(long id)
{
if (id <= 0)
return (false, "无效的菜单 Id");
var childCount = await _dbContext.Queryable<SysMenu>().Where(m => m.Pid == id).CountAsync();
if (childCount > 0)
return (false, "存在子菜单,请先删除子节点");
await _dbContext.Deleteable<SysRoleMenu>().Where(r => r.MenuId == id).ExecuteCommandAsync();
await _dbContext.Deleteable<SysTenantMenu>().Where(t => t.MenuId == id).ExecuteCommandAsync();
var n = await _dbContext.Deleteable<SysMenu>().Where(m => m.Id == id).ExecuteCommandAsync();
return n > 0 ? (true, "已删除") : (false, "删除失败");
}
private async Task TryLinkCurrentTenantMenuAsync(long menuId)
{
var tenantId = AppSession.CurrentUser?.TenantId;
if (tenantId == null || tenantId <= 0)
return;
var exists = await _dbContext.Queryable<SysTenantMenu>()
.AnyAsync(t => t.TenantId == tenantId && t.MenuId == menuId);
if (exists)
return;
await _dbContext.Insertable(new SysTenantMenu
{
Id = SnowflakeId.Next(),
TenantId = tenantId.Value,
MenuId = menuId
}).ExecuteCommandAsync();
}
/// <summary>
/// 判断 newPid 是否位于以 menuId 为根的子树内(含自身),用于防止环状父级
/// </summary>
private static bool NewParentIsInsideMenuSubtree(long menuId, long newPid, List<SysMenu> all)
{
if (newPid == 0)
return false;
if (newPid == menuId)
return true;
var cur = all.FirstOrDefault(x => x.Id == newPid);
for (var i = 0; i < 5000 && cur != null; i++)
{
if (cur.Pid == menuId)
return true;
if (cur.Pid == 0)
return false;
cur = all.FirstOrDefault(x => x.Id == cur.Pid);
}
return false;
}
}
}