sunpengfei
2025-08-07 177aa6f1c4601e4fb34aff04c4e328c98b489888
FlexJobApi.User.Application/Menus/Commands/SaveMenuCommandHandler.cs
@@ -1,4 +1,5 @@
using FlexJobApi.Core;
using Consul;
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Furion.DataValidation;
using Furion.FriendlyException;
@@ -29,35 +30,29 @@
        /// <inheritdoc/>
        public async Task<Guid> Handle(SaveMenuCommand request, CancellationToken cancellationToken)
        {
            if (request.Id.HasValue)
            {
                var entity = await rep.AsQueryable()
                    .Include(it => it.Children)
                    .FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
                if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "菜单");
                if (entity.UserType != request.UserType) throw Oops.Oh(EnumErrorCodeType.s410, "用户类型");
                if (entity.ClientType != request.ClientType) throw Oops.Oh(EnumErrorCodeType.s410, "客户端类型");
                var path = await GetPathAsync(request.ParentId, request.Code, cancellationToken);
                if (await CheckExist(entity, request.ParentId, request.Code)) throw Oops.Oh(EnumErrorCodeType.s405, "菜单编号");
                await UpdateChildrensPath($"{entity.Path}/{entity.Code}", $"{path}/{request.Code}", cancellationToken);
                request.Adapt(entity);
                SaveChildrens(entity, request);
                await rep.UpdateAsync(entity);
                return entity.Id;
            }
            else
            {
                var entity = new Menu();
                request.Adapt(entity);
                entity.Path = await GetPathAsync(entity.ParentId, entity.Code, cancellationToken);
                if (await CheckExist(entity, request.ParentId, request.Code)) throw Oops.Oh(EnumErrorCodeType.s405, "菜单编号");
                SaveChildrens(entity, request);
                await rep.InsertAsync(entity);
                return entity.Id;
            }
            return await request.SaveData<Menu, SaveMenuCommand>(
                it =>
                    it.UserType == request.UserType
                    && it.ClientType == request.ClientType
                    && it.ParentId == request.ParentId
                    && it.Code == request.Code
                    && it.Id != request.Id,
                (entity) =>
                {
                    entity.Path = DbUtils.GetTreeDataPath<Menu>(request.ParentId, cancellationToken).Result;
                    if (request.Id.HasValue)
                    {
                        if (entity.UserType != request.UserType) throw Oops.Oh(EnumErrorCodeType.s410, "用户类型");
                        if (entity.ClientType != request.ClientType) throw Oops.Oh(EnumErrorCodeType.s410, "客户端类型");
                        DbUtils.UpdateTreeDataChildrenPath<DictionaryData>(
                           $"{entity.Path}/{entity.Code}/",
                           $"{entity.Path}/{request.Code}/",
                           cancellationToken).Wait();
                    }
                    request.Adapt(entity);
                    SaveChildrens(entity, request);
                },
                cancellationToken);
        }
        /// <summary>
@@ -72,10 +67,10 @@
            var childrenIds = GetRequestChildrenIds(request);
            // 删除子级
            entity.Children = entity.Children
                .Where(it =>
                    it.Type == EnumMenuType.Menu
                    || it.Type == EnumMenuType.Page
                    || it.Type == EnumMenuType.Modal
                .Where(it =>
                    it.Type == EnumMenuType.Menu
                    || it.Type == EnumMenuType.Page
                    || it.Type == EnumMenuType.Modal
                    || childrenIds.Contains(it.Id))
                .ToList();
@@ -98,6 +93,7 @@
                                UserType = entity.UserType,
                                ClientType = entity.ClientType,
                                Type = EnumMenuType.Button,
                                VisitLevel = entity.VisitLevel,
                            };
                            entity.Children.Add(buttonEntity);
                        }
@@ -121,6 +117,7 @@
                            UserType = entity.UserType,
                            ClientType = entity.ClientType,
                            Type = EnumMenuType.Field,
                            VisitLevel = entity.VisitLevel,
                        };
                        entity.Children.Add(fieldEntity);
                    }
@@ -170,75 +167,6 @@
                    g.Fields.Where(f => f.Id.HasValue).Select(f => f.Id!.Value)))
                .SelectMany(it => it)
                .ToList();
        }
        /// <summary>
        /// 校验菜单是否重复
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="parentId"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        private async Task<bool> CheckExist(Menu entity, Guid? parentId, string code)
        {
            return await rep.AsQueryable().AsNoTracking()
                .AnyAsync(it =>
                    it.UserType == entity.UserType
                    && it.ClientType == entity.ClientType
                    && it.ParentId == parentId
                    && it.Code == code
                    && it.Id != entity.Id);
        }
        /// <summary>
        /// 获取地址
        /// </summary>
        /// <param name="parentId"></param>
        /// <param name="code"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task<string> GetPathAsync(Guid? parentId, string code, CancellationToken cancellationToken)
        {
            if (parentId.HasValue)
            {
                var parent = await rep.AsQueryable().AsNoTracking()
                    .Where(it => it.Id == parentId)
                    .Select(it => new
                    {
                        it.Path,
                        it.Code
                    })
                    .FirstOrDefaultAsync(cancellationToken);
                if (parent == null) throw Oops.Oh(EnumErrorCodeType.s404, "上级菜单");
                return $"{parent.Path}{parent.Code}/";
            }
            else
            {
                return "/";
            }
        }
        /// <summary>
        /// 更新下级菜单路径
        /// </summary>
        /// <param name="oldPath"></param>
        /// <param name="newPath"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        private async Task UpdateChildrensPath(string oldPath, string newPath, CancellationToken cancellationToken)
        {
            var models = await rep.AsQueryable()
                .Where(it => it.Path.StartsWith(oldPath))
                .Where(it => it.Type == EnumMenuType.Menu || it.Type == EnumMenuType.Page || it.Type == EnumMenuType.Modal)
                .ToListAsync(cancellationToken);
            if (models.IsNotNull())
            {
                foreach (var model in models)
                {
                    model.Path = model.Path.Replace(oldPath, newPath);
                }
                await rep.UpdateAsync(models);
            }
        }
    }
}