Procházet zdrojové kódy

添加数据资源功能后端接口,用于构建行政区或多级目录树

kenny před 4 roky
rodič
revize
da89207832

+ 150 - 0
Admin.NET/Admin.NET.Core/Admin.NET.Core.xml

@@ -511,6 +511,51 @@
             备注
             </summary>
         </member>
+        <member name="T:Admin.NET.Core.SysDataResource">
+             <summary>
+              数据资源表
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Pid">
+             <summary>
+             父节点Id 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Name">
+             <summary>
+             名称 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Value">
+             <summary>
+             值 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Code">
+             <summary>
+             节点编码 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Order">
+             <summary>
+             排序 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Remark">
+             <summary>
+             备注 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Status">
+             <summary>
+             状态:是否启用 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.SysDataResource.Children">
+            <summary>
+            数据资源子项
+            </summary>
+        </member>
         <member name="T:Admin.NET.Core.SysDictData">
             <summary>
             系统字典值表
@@ -2062,6 +2107,21 @@
             父菜单不存在
             </summary>
         </member>
+        <member name="F:Admin.NET.Core.ErrorCodeEnum.D1600">
+            <summary>
+            父资源不存在
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.ErrorCodeEnum.D1601">
+            <summary>
+            当前资源Id不能与父资源Id相同
+            </summary>
+        </member>
+        <member name="F:Admin.NET.Core.ErrorCodeEnum.D1602">
+            <summary>
+            已有相同数据资源,编码或名称相同
+            </summary>
+        </member>
         <member name="F:Admin.NET.Core.ErrorCodeEnum.xg1000">
             <summary>
             已存在同名或同编码项目
@@ -2728,6 +2788,17 @@
             </summary>
             <returns></returns>
         </member>
+        <member name="T:Admin.NET.Core.SeedData.SysDataResourceSeedData">
+            <summary>
+            系统数据资源种子数据
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.SeedData.SysDataResourceSeedData.HasData">
+            <summary>
+            种子数据
+            </summary>
+            <returns></returns>
+        </member>
         <member name="T:Admin.NET.Core.SeedData.SysDictDataSeedData">
             <summary>
             系统字典值表种子数据
@@ -3888,6 +3959,85 @@
              </summary>
              <example>Magic.Application</example>
         </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Pid">
+            <summary>
+            父Id
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Value">
+             <summary>
+             值 
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Code">
+            <summary>
+            编码
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Order">
+            <summary>
+            排序
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Remark">
+            <summary>
+            备注
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.DataResourceInput.Status">
+            <summary>
+            状态
+            </summary>
+        </member>
+        <member name="P:Admin.NET.Core.Service.DataResources.Dto.AddDataResourceInput.Name">
+            <summary>
+            名称
+            </summary>
+        </member>
+        <member name="T:Admin.NET.Core.Service.DataResource.SysDataResourceService">
+            <summary>
+            系统数据资源服务
+            </summary>
+        </member>
+        <member name="M:Admin.NET.Core.Service.DataResource.SysDataResourceService.GetDataResourceList(Admin.NET.Core.Service.DataResources.Dto.DataResourceInput)">
+            <summary>
+            获取数据资源列表
+            </summary>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.DataResource.SysDataResourceService.AddDataResource(Admin.NET.Core.Service.DataResources.Dto.AddDataResourceInput)">
+            <summary>
+            增加数据资源
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.DataResource.SysDataResourceService.UpdateDataResource(Admin.NET.Core.Service.DataResources.Dto.UpdateDataResourceInput)">
+            <summary>
+            更新数据资源
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.DataResource.SysDataResourceService.DeleteDataResource(Admin.NET.Core.Service.DataResources.Dto.DeleteDataResourceInput)">
+            <summary>
+            删除数据资源
+            </summary>
+            <param name="input"></param>
+            <returns></returns>
+        </member>
+        <member name="M:Admin.NET.Core.Service.DataResource.SysDataResourceService.GetChildIdListWithSelfById(System.Int64)">
+            <summary>
+            根据节点Id获取子节点Id集合(包含自己)
+            </summary>
+            <param name="pid"></param>
+            <returns></returns>
+        </member>
         <member name="P:Admin.NET.Core.Service.GetDataDictDataInput.DictTypeId">
             <summary>
             字典类型Id

+ 62 - 0
Admin.NET/Admin.NET.Core/Entity/SysDataResource.cs

@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using Admin.NET.Core;
+using SqlSugar;
+namespace Admin.NET.Core
+{
+    /// <summary>
+    ///  数据资源表
+    ///</summary>
+    [SugarTable("sys_data_resource", "数据资源表")]
+    [SqlSugarEntity]
+    public class SysDataResource : EntityBase
+    {
+        /// <summary>
+        /// 父节点Id 
+        ///</summary>
+        [SugarColumn(ColumnName = "pid", ColumnDescription = "父Id")]
+        public long Pid { get; set; }
+        /// <summary>
+        /// 名称 
+        ///</summary>
+        [SugarColumn(ColumnName = "name", ColumnDescription = "名称", Length = 200)]
+        [MaxLength(200)]
+        public string Name { get; set; }
+        /// <summary>
+        /// 值 
+        ///</summary>
+        [SugarColumn(ColumnName = "value", ColumnDescription = "值", Length = 200)]
+        [MaxLength(200)]
+        public string Value { get; set; }
+        /// <summary>
+        /// 节点编码 
+        ///</summary>
+        [SugarColumn(ColumnName = "code", ColumnDescription = "节点编码", Length = 100)]
+        [MaxLength(100)]
+        public string Code { get; set; }
+        /// <summary>
+        /// 排序 
+        ///</summary>
+        [SugarColumn(ColumnName = "order", ColumnDescription = "排序")]
+        public int Order { get; set; }
+        /// <summary>
+        /// 备注 
+        ///</summary>
+        [SugarColumn(ColumnName = "remark", ColumnDescription = "备注", Length = 200)]
+        [MaxLength(200)]
+        public string Remark { get; set; }
+        /// <summary>
+        /// 状态:是否启用 
+        ///</summary>
+        [SugarColumn(ColumnName = "status", ColumnDescription = "状态")]
+        public StatusEnum Status { get; set; } = StatusEnum.Enable;
+
+        /// <summary>
+        /// 数据资源子项
+        /// </summary>
+        [SugarColumn(IsIgnore = true)]
+        public List<SysDataResource> Children { get; set; }
+    }
+}

+ 18 - 0
Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs

@@ -428,6 +428,24 @@ namespace Admin.NET.Core
         [ErrorCodeItemMetadata("父菜单不存在")]
         D1505,
 
+        /// <summary>
+        /// 父资源不存在
+        /// </summary>
+        [ErrorCodeItemMetadata("父资源不存在")]
+        D1600,
+
+        /// <summary>
+        /// 当前资源Id不能与父资源Id相同
+        /// </summary>
+        [ErrorCodeItemMetadata("当前资源Id不能与父资源Id相同")]
+        D1601,
+
+        /// <summary>
+        /// 已有相同数据资源,编码或名称相同
+        /// </summary>
+        [ErrorCodeItemMetadata("已有相同数据资源,编码或名称相同")]
+        D1602,
+
         /// <summary>
         /// 已存在同名或同编码项目
         /// </summary>

+ 30 - 0
Admin.NET/Admin.NET.Core/SeedData/SysDataResourceSeedData.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Admin.NET.Core.SeedData
+{
+    /// <summary>
+    /// 系统数据资源种子数据
+    /// </summary>
+    public class SysDataResourceSeedData : ISqlSugarEntitySeedData<SysDataResource>
+    {
+        /// <summary>
+        /// 种子数据
+        /// </summary>
+        /// <returns></returns>
+        public IEnumerable<SysDataResource> HasData()
+        {
+            return new[]
+            {
+                new SysDataResource{ Id=243848612100001, Pid=0, Name="行政区",Value="district", Code="1001", CreateTime=DateTime.Parse("2022-05-30 00:00:00"), Remark="行政区"},
+                new SysDataResource{ Id=243848612100002, Pid=243848612100001, Name="北京市",Value="110000", Code="1001001", CreateTime=DateTime.Parse("2022-05-30 00:00:00"), Remark="北京市"},
+                new SysDataResource{ Id=243848612100003, Pid=243848612100002, Name="东城区",Value="110101", Code="1001001001", CreateTime=DateTime.Parse("2022-05-30 00:00:00"), Remark="东城区"},
+
+            };
+        }
+
+    }
+}

+ 6 - 0
Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs

@@ -99,6 +99,12 @@ namespace Admin.NET.Core
                 new SysMenu{ Id=252885263003881, Pid=252885263003880, Title="缓存查询", Permission="cache:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
                 new SysMenu{ Id=252885263003882, Pid=252885263003880, Title="缓存删除", Permission="cache:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
 
+                new SysMenu{ Id=252885263003890, Pid=252885263003780, Title="数据资源管理", Path="dataResource", Name="DataResourceManagement", Component="/sys/admin/dataResource/index", Icon="ant-design:funnel-plot-filled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-05-30 00:00:00"), OrderNo=100 },
+                new SysMenu{ Id=252885263003891, Pid=252885263003890, Title="数据资源查询", Permission="sysDataResource:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-05-30 00:00:00"), OrderNo=100 },
+                new SysMenu{ Id=252885263003892, Pid=252885263003890, Title="数据资源编辑", Permission="sysDataResource:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-05-30 00:00:00"), OrderNo=100 },
+                new SysMenu{ Id=252885263003893, Pid=252885263003890, Title="数据资源增加", Permission="sysDataResource:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-05-30 00:00:00"), OrderNo=100 },
+                new SysMenu{ Id=252885263003894, Pid=252885263003890, Title="数据资源删除", Permission="sysDataResource:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-05-30 00:00:00"), OrderNo=100 },
+
                 new SysMenu{ Id=252885263003900, Pid=0, Title="日志管理", Path="/log", Name="log", Component="LAYOUT", Redirect="", Icon="ant-design:carry-out-outlined", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=300 },
                 new SysMenu{ Id=252885263003910, Pid=252885263003900, Title="访问日志", Path="vislog", Name="VislogManagement", Component="/sys/admin/log/vislog/index", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
                 new SysMenu{ Id=252885263003911, Pid=252885263003910, Title="日志查询", Permission="sysVislog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },

+ 64 - 0
Admin.NET/Admin.NET.Core/Service/DataResources/Dto/DataResourceInput.cs

@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Admin.NET.Core.Service.DataResources.Dto
+{
+    public class DataResourceInput : BaseIdInput
+    {
+        /// <summary>
+        /// 父Id
+        /// </summary>
+        public virtual long Pid { get; set; }
+
+        /// <summary>
+        /// 名称
+        /// </summary>
+        public virtual string Name { get; set; }
+
+        /// <summary>
+        /// 值 
+        ///</summary>
+        public virtual string Value { get; set; }
+
+        /// <summary>
+        /// 编码
+        /// </summary>
+        public virtual string Code { get; set; }
+
+        /// <summary>
+        /// 排序
+        /// </summary>
+        public virtual int Order { get; set; }
+
+        /// <summary>
+        /// 备注
+        /// </summary>
+        public virtual string Remark { get; set; }
+
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public virtual int Status { get; set; }
+    }
+
+    public class AddDataResourceInput : DataResourceInput
+    {
+        /// <summary>
+        /// 名称
+        /// </summary>
+        [Required(ErrorMessage = "资源名称不能为空")]
+        public override string Name { get; set; }
+    }
+
+    public class UpdateDataResourceInput : AddDataResourceInput
+    {
+    }
+
+    public class DeleteDataResourceInput : BaseIdInput
+    {
+    }
+}

+ 162 - 0
Admin.NET/Admin.NET.Core/Service/DataResources/SysDataResourceService.cs

@@ -0,0 +1,162 @@
+using Admin.NET.Core.Service.DataResources.Dto;
+using Furion.DependencyInjection;
+using Furion.DynamicApiController;
+using Furion.FriendlyException;
+using Mapster;
+using Microsoft.AspNetCore.Mvc;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Admin.NET.Core.Service.DataResource
+{
+    /// <summary>
+    /// 系统数据资源服务
+    /// </summary>
+    [ApiDescriptionSettings(Name = "系统数据资源", Order = 201)]
+    public class SysDataResourceService : IDynamicApiController, ITransient
+    {
+        private readonly SqlSugarRepository<SysDataResource> _sysDataResourceRep;
+        private readonly ISysCacheService _sysCacheService;
+
+        public SysDataResourceService(SqlSugarRepository<SysDataResource> sysDataResourceRep, ISysCacheService sysCacheService)
+        {
+            _sysDataResourceRep = sysDataResourceRep;
+            _sysCacheService = sysCacheService;
+        }
+
+        /// <summary>
+        /// 获取数据资源列表
+        /// </summary>
+        /// <returns></returns>
+        [HttpGet("/sysDataResource/list")]
+        public async Task<List<SysDataResource>> GetDataResourceList([FromQuery] DataResourceInput input)
+        {
+            var idList = new List<long>();
+
+            if (input.Id > 0)
+            {
+                idList = await GetChildIdListWithSelfById(input.Id);
+            }
+
+
+            var iSugarQueryable = _sysDataResourceRep.AsQueryable().OrderBy(u => u.Order)
+                .WhereIF(idList.Count > 0, u => idList.Contains(u.Id)); // 非超级管理员限制
+
+            if (!string.IsNullOrWhiteSpace(input.Name) || !string.IsNullOrWhiteSpace(input.Code) || !string.IsNullOrWhiteSpace(input.Value) || input.Id > 0)
+            {
+                return await iSugarQueryable
+                    .WhereIF(!string.IsNullOrWhiteSpace(input.Name), u => u.Name.Contains(input.Name))
+                    .WhereIF(!string.IsNullOrWhiteSpace(input.Value), u => u.Value.Contains(input.Value))
+                    .WhereIF(!string.IsNullOrWhiteSpace(input.Code), u => u.Code.Contains(input.Code))
+                    .ToListAsync();
+            }
+            return await iSugarQueryable.ToTreeAsync(u => u.Children, u => u.Pid, input.Id > 0 ? input.Id : 0);
+        }
+
+        /// <summary>
+        /// 增加数据资源
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost("/sysDataResource/add")]
+        public async Task<long> AddDataResource(AddDataResourceInput input)
+        {
+            var isExist = await _sysDataResourceRep.IsAnyAsync(u => u.Code == input.Code && u.Name == input.Name);
+            if (isExist)
+                throw Oops.Oh(ErrorCodeEnum.D1602);
+
+            var newCode = "";
+            // 生成编码Code和排序(每级2位编码)
+            SysDataResource sysDataResource = await _sysDataResourceRep.AsQueryable().OrderByDescending(o => o.Code)
+                    .FirstAsync(u => u.Pid == input.Pid);
+
+            if (sysDataResource != null)
+            {
+                newCode = sysDataResource.Code[0..^3] + string.Format("{0:d3}", int.Parse(sysDataResource.Code[^3..]) + 1);
+            }
+            else
+            {
+                //如果没有根节点,默认为1001
+                if (input.Pid == 0)
+                {
+                    newCode = "1001";
+                }
+                else
+                {
+                    sysDataResource = await _sysDataResourceRep.GetFirstAsync(u => u.Id == input.Pid);
+                    newCode = sysDataResource.Code + "01";
+                }
+
+            }
+            var newDataResource = input.Adapt<SysDataResource>();
+            newDataResource.Code = newCode;
+            newDataResource.Order = int.Parse(newCode[^3..]);
+            newDataResource = await _sysDataResourceRep.AsInsertable(newDataResource).ExecuteReturnEntityAsync();
+
+            return newDataResource.Id;
+        }
+
+        /// <summary>
+        /// 更新数据资源
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost("/sysDataResource/update")]
+        [SqlSugarUnitOfWork]
+        public async Task UpdateDataResource(UpdateDataResourceInput input)
+        {
+            if (input.Pid != 0)
+            {
+                var pDataResource = await _sysDataResourceRep.GetFirstAsync(u => u.Id == input.Pid);
+                _ = pDataResource ?? throw Oops.Oh(ErrorCodeEnum.D1600);
+            }
+            if (input.Id == input.Pid)
+                throw Oops.Oh(ErrorCodeEnum.D1601);
+
+            var sysDataResource = await _sysDataResourceRep.GetFirstAsync(u => u.Id == input.Id);
+            var isExist = await _sysDataResourceRep.IsAnyAsync(u => (u.Name == input.Name && u.Code == input.Code) && u.Id != sysDataResource.Id);
+            if (isExist)
+                throw Oops.Oh(ErrorCodeEnum.D1602);
+
+            // 父Id不能为自己的子节点
+            var childIdList = await GetChildIdListWithSelfById(input.Id);
+            if (childIdList.Contains(input.Pid))
+                throw Oops.Oh(ErrorCodeEnum.D1601);
+
+
+            var dataResource = input.Adapt<SysDataResource>();
+            await _sysDataResourceRep.AsUpdateable(dataResource).IgnoreColumns(true).ExecuteCommandAsync();
+        }
+
+        /// <summary>
+        /// 删除数据资源
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        [HttpPost("/sysDataResource/delete")]
+        public async Task DeleteDataResource(DeleteDataResourceInput input)
+        {
+            var sysDataResource = await _sysDataResourceRep.GetFirstAsync(u => u.Id == input.Id);
+
+            // 获取本节点对应所有子节点id列表
+            var treeList = await _sysDataResourceRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id);
+            var idList = treeList.Select(u => u.Id).ToList();
+
+            // 级联删除数据资源子节点
+            await _sysDataResourceRep.DeleteAsync(u => idList.Contains(u.Id));
+        }
+
+        /// <summary>
+        /// 根据节点Id获取子节点Id集合(包含自己)
+        /// </summary>
+        /// <param name="pid"></param>
+        /// <returns></returns>
+        [NonAction]
+        public async Task<List<long>> GetChildIdListWithSelfById(long pid)
+        {
+            var treeList = await _sysDataResourceRep.AsQueryable().ToChildListAsync(u => u.Pid, pid);
+            return treeList.Select(u => u.Id).ToList();
+        }
+    }
+}