From b69c6d86c157267f81955f0d63ac590fe1c8a4ae Mon Sep 17 00:00:00 2001 From: wcg Date: Sun, 4 Jan 2026 10:23:42 +0800 Subject: [PATCH] =?UTF-8?q?feat(dept):=20=E6=B7=BB=E5=8A=A0=E9=83=A8?= =?UTF-8?q?=E9=97=A8=E6=A0=91=E5=BD=A2=E7=BB=93=E6=9E=84=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=92=8C=E7=9B=B8=E5=85=B3API=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/System/DeptService.cs | 107 ++++++++++++++++++ .../Dtos/DeptTreeDto.cs | 42 +++++++ .../Entities/DeptAggregateRoot.cs | 38 +++++++ 3 files changed, 187 insertions(+) create mode 100644 Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/DeptTreeDto.cs diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/DeptService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/DeptService.cs index cc9898c3..6b442ca6 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/DeptService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/System/DeptService.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.Mvc; using SqlSugar; using Volo.Abp.Application.Dtos; using Yi.Framework.Ddd.Application; @@ -6,6 +7,7 @@ using Yi.Framework.Rbac.Application.Contracts.IServices; using Yi.Framework.Rbac.Domain.Entities; using Yi.Framework.Rbac.Domain.Repositories; using Yi.Framework.Rbac.Domain.Shared.Consts; +using Yi.Framework.Rbac.Domain.Shared.Dtos; namespace Yi.Framework.Rbac.Application.Services.System { @@ -78,5 +80,110 @@ namespace Yi.Framework.Rbac.Application.Services.System throw new UserFriendlyException(DeptConst.Exist); } } + + /// + /// 多查 + /// + /// + /// + [Route("dept/list")] + public async Task> GetAllListAsync(DeptGetListInputVo input) + { + var entities = await _repository._DbQueryable + .WhereIF(!string.IsNullOrEmpty(input.DeptName), u => u.DeptName.Contains(input.DeptName!)) + .WhereIF(input.State is not null, u => u.State == input.State) + .OrderBy(u => u.OrderNum, OrderByType.Asc) + .ToListAsync(); + + return await MapToGetListOutputDtosAsync(entities); + } + + /// + /// 获取树形结构的部门列表 + /// + /// 树形结构的部门列表 + public async Task> GetTreeAsync() + { + // 获取所有启用的部门 + var entities = await _repository._DbQueryable + .Where(x => x.State == true) + .OrderBy(x => x.OrderNum, OrderByType.Asc) + .ToListAsync(); + return entities.DeptTreeBuild(); + } + + /// + /// 获取排除指定部门及其子孙部门的部门列表 + /// + /// 要排除的部门ID + /// 排除后的部门列表 + [HttpGet] + [Route("dept/list/exclude/{id}")] + public async Task> GetListExcludeAsync(Guid id) + { + // 获取要排除的部门及其所有子孙部门的ID + var excludeIds = await GetAllChildrenIdsAsync(id); + excludeIds.Add(id); // 同时排除自己 + + // 查询并过滤掉排除的部门 + var result = await _repository._DbQueryable + .Where(x => !excludeIds.Contains(x.Id)) + .OrderBy(dept => dept.OrderNum, OrderByType.Asc) + .Select(dept => new DeptGetListOutputDto + { + Id = dept.Id, + CreationTime = dept.CreationTime, + CreatorId = dept.CreatorId, + State = dept.State, + DeptName = dept.DeptName, + DeptCode = dept.DeptCode, + Leader = dept.Leader, + ParentId = dept.ParentId, + Remark = dept.Remark, + OrderNum = dept.OrderNum + }) + .ToListAsync(); + + return result; + } + + /// + /// 递归获取指定部门的所有子孙部门ID + /// + /// 部门ID + /// 所有子孙部门ID列表 + private async Task> GetAllChildrenIdsAsync(Guid deptId) + { + var result = new List(); + + // 获取所有部门 + var allDepts = await _repository._DbQueryable.ToListAsync(); + + // 递归获取子孙部门ID + GetChildrenIdsRecursive(deptId, allDepts, result); + + return result; + } + + /// + /// 递归辅助方法:获取子孙部门ID + /// + /// 父部门ID + /// 所有部门列表 + /// 结果列表 + private void GetChildrenIdsRecursive(Guid parentId, List allDepts, List result) + { + // 查找直接子部门 + var children = allDepts.Where(x => x.ParentId == parentId).ToList(); + + foreach (var child in children) + { + // 添加子部门ID + result.Add(child.Id); + + // 递归获取子部门的子部门 + GetChildrenIdsRecursive(child.Id, allDepts, result); + } + } } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/DeptTreeDto.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/DeptTreeDto.cs new file mode 100644 index 00000000..e768ba22 --- /dev/null +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/DeptTreeDto.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using static Yi.Framework.Core.Helper.TreeHelper; + +namespace Yi.Framework.Rbac.Domain.Shared.Dtos +{ + /// + /// 部门树形DTO + /// + public class DeptTreeDto : ITreeModel + { + /// + /// 部门ID + /// + public Guid Id { get; set; } + + /// + /// 父部门ID + /// + public Guid ParentId { get; set; } + + /// + /// 排序号 + /// + public int OrderNum { get; set; } + + /// + /// 部门名称 + /// + public string DeptName { get; set; } = string.Empty; + + /// + /// 状态 + /// + public bool State { get; set; } + + /// + /// 子部门列表 + /// + public List? Children { get; set; } + } +} + diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/DeptAggregateRoot.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/DeptAggregateRoot.cs index 17fc6ac6..3dc2022f 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/DeptAggregateRoot.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Entities/DeptAggregateRoot.cs @@ -3,6 +3,8 @@ using Volo.Abp; using Volo.Abp.Auditing; using Volo.Abp.Domain.Entities; using Yi.Framework.Core.Data; +using Yi.Framework.Core.Helper; +using Yi.Framework.Rbac.Domain.Shared.Dtos; namespace Yi.Framework.Rbac.Domain.Entities { @@ -87,4 +89,40 @@ namespace Yi.Framework.Rbac.Domain.Entities public string? Remark { get; set; } } + + /// + /// 部门实体扩展 + /// + public static class DeptEntityExtensions + { + /// + /// 构建部门树形列表 + /// + /// 部门列表 + /// 树形结构的部门列表 + public static List DeptTreeBuild(this List depts) + { + // 过滤启用的部门 + var filteredDepts = depts + .Where(d => d.State == true) + .ToList(); + + List deptTrees = new(); + foreach (var dept in filteredDepts) + { + var deptTree = new DeptTreeDto + { + Id = dept.Id, + OrderNum = dept.OrderNum, + DeptName = dept.DeptName, + State = dept.State, + ParentId = dept.ParentId, + }; + + deptTrees.Add(deptTree); + } + + return TreeHelper.SetTree(deptTrees); + } + } }