sunpengfei
2025-08-01 9fd157a63dfbb8ee9f32fff7540c97eb4a3d3cce
feat:菜单开发
8个文件已修改
212 ■■■■■ 已修改文件
FlexJobApi.Core/Enums/Users/EnumMenuType.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/FlexJobApi.Core.xml 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Menus/Queries/MenuAllQuery.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/EnumUserErrorCodeType.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/FlexJobApi.User.Application.xml 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Menus/Commands/MenuSaveCommandHandler.cs 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Menus/MenuAppService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Menus/Queries/MenuListQueryHandler.cs 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Enums/Users/EnumMenuType.cs
@@ -26,7 +26,7 @@
        /// <summary>
        /// 按钮
        /// </summary>
        Buuton = 40,
        Button = 40,
        /// <summary>
        /// 字段
        /// </summary>
FlexJobApi.Core/FlexJobApi.Core.xml
@@ -1989,92 +1989,107 @@
            备注
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.MenuAllQuery">
        <member name="T:FlexJobApi.Core.MenuListQuery">
            <summary>
            查询所有菜单
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.MenuAllCallback">
            <summary>
            查询所有菜单-结果
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.MenuAllCallbackItem">
            <summary>
            查询所有菜单-结果-项
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Id">
            <summary>
            Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.ParentId">
            <summary>
            上级Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Childrens">
            <summary>
            下级
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Path">
            <summary>
            菜单路径
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Code">
            <summary>
            编号
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Name">
            <summary>
            名称
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Type">
        <member name="P:FlexJobApi.Core.MenuListQuery.Types">
            <summary>
            类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.VisitLevel">
        <member name="P:FlexJobApi.Core.MenuListQuery.ParentId">
            <summary>
            上级Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListQuery.Keywords">
            <summary>
            关键字
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.MenuListCallback">
            <summary>
            查询所有菜单-结果
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.MenuListCallbackItem">
            <summary>
            查询所有菜单-结果-项
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Id">
            <summary>
            Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.ParentId">
            <summary>
            上级Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Childrens">
            <summary>
            下级
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Path">
            <summary>
            菜单路径
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Code">
            <summary>
            编号
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Name">
            <summary>
            名称
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Type">
            <summary>
            类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.VisitLevel">
            <summary>
            访问级别
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Icon">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Icon">
            <summary>
            图标
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Url">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Url">
            <summary>
            链接地址
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.IsDisabled">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.IsDisabled">
            <summary>
            是否禁用
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.IsHidden">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.IsHidden">
            <summary>
            是否隐藏
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.IsCache">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.IsCache">
            <summary>
            是否缓存
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Sort">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Sort">
            <summary>
            排序
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.MenuAllCallbackItem.Remark">
        <member name="P:FlexJobApi.Core.MenuListCallbackItem.Remark">
            <summary>
            备注
            </summary>
FlexJobApi.Core/Models/User/Menus/Queries/MenuAllQuery.cs
@@ -1,4 +1,5 @@
using MediatR;
using Mapster;
using MediatR;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
@@ -13,6 +14,20 @@
    /// </summary>
    public class MenuListQuery : IRequest<MenuListCallback>
    {
        public MenuListQuery()
        {
        }
        /// <summary>
        /// 上级Id
        /// </summary>
        public Guid? ParentId { get; set; }
        /// <summary>
        /// 关键字
        /// </summary>
        public string Keywords { get; set; }
    }
    /// <summary>
@@ -35,7 +50,6 @@
    {
        public MenuListCallbackItem()
        {
            Childrens = [];
        }
        /// <summary>
@@ -47,11 +61,6 @@
        /// 上级Id
        /// </summary>
        public Guid? ParentId { get; set; }
        /// <summary>
        /// 下级
        /// </summary>
        public List<MenuListCallbackItem> Childrens { get; set; }
        /// <summary>
        /// 菜单路径
FlexJobApi.User.Application/EnumUserErrorCodeType.cs
@@ -16,6 +16,11 @@
        [ErrorCodeItemMetadata("{0}不存在")]
        s100 = 100,
        /// <summary>
        /// 参数错误:{0}
        /// </summary>
        [ErrorCodeItemMetadata("参数错误:{0}")]
        s200 = 200,
        /// <summary>
        /// 账号或密码不存在
        /// </summary>
        [ErrorCodeItemMetadata("账号或密码不存在")]
FlexJobApi.User.Application/FlexJobApi.User.Application.xml
@@ -67,9 +67,9 @@
            菜单
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.MenuAppService.AllQuery(FlexJobApi.Core.MenuAllQuery)">
        <member name="M:FlexJobApi.User.Application.MenuAppService.ListQuery(FlexJobApi.Core.MenuListQuery)">
            <summary>
            查询所有菜单
            查询菜单列表
            </summary>
            <param name="query"></param>
            <returns></returns>
@@ -81,17 +81,17 @@
            <param name="command"></param>
            <returns></returns>
        </member>
        <member name="T:FlexJobApi.User.Application.MenuAllQueryHandler">
        <member name="T:FlexJobApi.User.Application.MenuListQueryHandler">
            <summary>
            查询所有菜单
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.MenuAllQueryHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Menu})">
        <member name="M:FlexJobApi.User.Application.MenuListQueryHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Menu})">
            <summary>
            查询所有菜单
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.MenuAllQueryHandler.Handle(FlexJobApi.Core.MenuAllQuery,System.Threading.CancellationToken)">
        <member name="M:FlexJobApi.User.Application.MenuListQueryHandler.Handle(FlexJobApi.Core.MenuListQuery,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
    </members>
FlexJobApi.User.Application/Menus/Commands/MenuSaveCommandHandler.cs
@@ -29,10 +29,30 @@
                ? await menuRep.AsQueryable().FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken)
                : new Menu();
            if (menu == null) throw Oops.Oh(EnumUserErrorCodeType.s100, "菜单");
            if (request.Id.HasValue && menu.Code != request.Code)
            {
                throw Oops.Oh(EnumUserErrorCodeType.s200, "编号不可修改");
            }
            request.Adapt(menu);
            if (menu.ParentId.HasValue)
            {
                menu.Path = await menuRep.AsQueryable().AsNoTracking().Where(it => it.Id == menu.ParentId).Select(it => it.Path).FirstOrDefaultAsync();
                menu.Path = $"{menu.Path}/{menu.Code}";
            }
            else
            {
                menu.Path = "/";
            }
            var result = request.Id == null
                ? await menuRep.InsertNowAsync(menu, cancellationToken: cancellationToken)
                : await menuRep.UpdateNowAsync(menu, cancellationToken: cancellationToken);
                ? await menuRep.InsertAsync(menu, cancellationToken: cancellationToken)
                : await menuRep.UpdateAsync(menu);
            await menuRep.SaveNowAsync(cancellationToken);
            return menu.Id;
        }
    }
FlexJobApi.User.Application/Menus/MenuAppService.cs
@@ -19,7 +19,7 @@
        private readonly IMediator mediator = mediator;
        /// <summary>
        /// 查询菜单列表
        /// 查询菜单/页面/模态框列表
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
FlexJobApi.User.Application/Menus/Queries/MenuListQueryHandler.cs
@@ -12,7 +12,7 @@
namespace FlexJobApi.User.Application
{
    /// <summary>
    /// 查询所有菜单
    /// 查询菜单/页面/模态框列表
    /// </summary>
    public class MenuListQueryHandler(
        IRepository<Menu> menuRep) 
@@ -23,21 +23,22 @@
        /// <inheritdoc/>
        public async Task<MenuListCallback> Handle(MenuListQuery request, CancellationToken cancellationToken)
        {
            var config = new TypeAdapterConfig();
            config.Default.MaxDepth(10);
            var callback = new MenuListCallback();
            callback.Items = await menuRep.AsQueryable()
              .Include(it => it.Childrens.Where(c =>
                    c.Type == EnumMenuType.Menu
                    || c.Type == EnumMenuType.Page
                    || c.Type == EnumMenuType.Modal))
              .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime)
              .Where(it =>
                    it.Type == EnumMenuType.Menu
                    || it.Type == EnumMenuType.Page
                    || it.Type == EnumMenuType.Modal)
              .ProjectToType<MenuListCallbackItem>(config)
              .ToListAsync(cancellationToken);
            var q = menuRep.AsQueryable().AsNoTracking()
                .Where(it => it.Type == EnumMenuType.Menu || it.Type == EnumMenuType.Page || it.Type == EnumMenuType.Modal);
            if (request.ParentId.HasValue)
            {
                q = q.Where(it => it.ParentId == request.ParentId);
            }
            if (!string.IsNullOrEmpty(request.Keywords))
            {
                q = q.Where(it =>
                    it.Name.Contains(request.Keywords)
                    || it.Code.Contains(request.Keywords)
                    || it.Path.Contains(request.Keywords)
                    || it.Remark.Contains(request.Keywords));
            }
            callback.Items = await q.ProjectToType<MenuListCallbackItem>().ToListAsync();
            return callback;
        }
    }