sunpengfei
2025-08-04 138943603ac70f25500d8daba79e58c302cbd817
feat:角色开发
4个文件已添加
14个文件已修改
665 ■■■■■ 已修改文件
FlexJobApi.Application/Dictionaries/DictionaryAppService.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Application/FlexJobApi.Application.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Entities/Users/RoleResource.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/FlexJobApi.Core.xml 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Auths/Commands/PasswordLoginCommand.cs 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Menus/Commands/DeleteMenuCommand.cs 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Roles/Commands/DeleteRoleCommand.cs 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Roles/Commands/SaveRoleCommand.cs 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Models/User/Roles/Queries/GetRoleQuery.cs 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/DeleteUtils/DeleteCommand.cs 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/PagedListUtils/PagedListQuery.cs 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Core/Utils/PagedListUtils/PagedListUtils.cs 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Auths/Commands/PasswordLoginCommandHandler.cs 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/FlexJobApi.User.Application.xml 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Roles/Commands/DeleteRoleCommandHandler.cs 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Roles/Commands/SaveRoleCommandHandler.cs 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Roles/Queries/GetRoleQueryHandler.cs 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.User.Application/Roles/Queries/GetRolesQueryHandler.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
FlexJobApi.Application/Dictionaries/DictionaryAppService.cs
@@ -18,7 +18,7 @@
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public Task<GetDictionaryDatasQueryResult> GetDictionaryDatasQuery(GetDictionaryDatasQuery query)
        public Task<GetDictionaryDatasQueryResult> GetDictionaryDatas(GetDictionaryDatasQuery query)
        {
            return mediator.Send(query);
        }
FlexJobApi.Application/FlexJobApi.Application.xml
@@ -14,7 +14,7 @@
            资源
            </summary>
        </member>
        <member name="M:FlexJobApi.Application.DictionaryAppService.GetDictionaryDatasQuery(FlexJobApi.Core.GetDictionaryDatasQuery)">
        <member name="M:FlexJobApi.Application.DictionaryAppService.GetDictionaryDatas(FlexJobApi.Core.GetDictionaryDatasQuery)">
            <summary>
            获取字典数据分页列表
            </summary>
FlexJobApi.Core/Entities/Users/RoleResource.cs
@@ -22,18 +22,18 @@
        public Role Role { get; set; }
        /// <summary>
        /// 菜单Id
        /// 资源Id
        /// </summary>
        public Guid MenuId { get; set; }
        public Guid ResourceId { get; set; }
        /// <summary>
        /// 菜单
        /// 资源
        /// </summary>
        public Menu Menu { get; set; }
        public Resource Resource { get; set; }
        /// <summary>
        /// 数据权限
        /// </summary>
        public EnumRoleWebApiDataPower? DataPower { get; set; }
        public EnumRoleWebApiDataPower DataPower { get; set; }
    }
}
FlexJobApi.Core/FlexJobApi.Core.xml
@@ -989,14 +989,14 @@
            角色
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.RoleResource.MenuId">
        <member name="P:FlexJobApi.Core.RoleResource.ResourceId">
            <summary>
            菜单Id
            资源Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.RoleResource.Menu">
        <member name="P:FlexJobApi.Core.RoleResource.Resource">
            <summary>
            菜单
            资源
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.RoleResource.DataPower">
@@ -1969,11 +1969,6 @@
            删除菜单
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.DeleteMenuCommand.Ids">
            <summary>
            Id
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.SaveMenuCommand">
            <summary>
            保存菜单
@@ -2604,6 +2599,116 @@
            响应类型名称
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.DeleteRoleCommand">
            <summary>
            删除角色
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.SaveRoleCommand">
            <summary>
            保存角色
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.Id">
            <summary>
            Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.Name">
            <summary>
            名称
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.UserType">
            <summary>
            用户类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.ClientType">
            <summary>
            客户端类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.MinLevel">
            <summary>
            最低级别
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.MenuIds">
            <summary>
            菜单Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.SaveRoleCommand.Resources">
            <summary>
            资源
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.GetRoleQuery">
            <summary>
            查询角色详情
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQuery.Id">
            <summary>
            Id
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.GetRoleQueryResult">
            <summary>
            查询角色详情-结果
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.Id">
            <summary>
            Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.Name">
            <summary>
            名称
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.UserType">
            <summary>
            用户类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.ClientType">
            <summary>
            客户端类型
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.MinLevel">
            <summary>
            最低级别
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.MenuIds">
            <summary>
            菜单Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResult.Resources">
            <summary>
            资源
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.GetRoleQueryResultResource">
            <summary>
            查询角色详情-结果-资源
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResultResource.ResourceId">
            <summary>
            资源Id
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.GetRoleQueryResultResource.DataPower">
            <summary>
            数据权限
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.GetRolesQuery">
            <summary>
            查询角色分页列表
@@ -2757,6 +2862,11 @@
            <param name="modelBuilder"></param>
            <param name="dbContextLocator"></param>
            <returns></returns>
        </member>
        <member name="T:FlexJobApi.Core.DeleteCommand">
            <summary>
            删除命令
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.EnumModel.Name">
            <summary>
@@ -3036,7 +3146,7 @@
            <summary>
            查询分页列表
            </summary>
            <typeparam name="TCallback"></typeparam>
            <typeparam name="TResult"></typeparam>
            <typeparam name="TItem"></typeparam>
        </member>
        <member name="P:FlexJobApi.Core.PagedListQuery`2.PageModel">
@@ -3059,9 +3169,9 @@
            页码
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.PagedListQueryPageModel.TotalCount">
        <member name="P:FlexJobApi.Core.PagedListQueryPageModel.OrderInput">
            <summary>
            总数
            排序
            </summary>
        </member>
        <member name="T:FlexJobApi.Core.PagedListQueryPageModelOrderInput">
@@ -3100,11 +3210,35 @@
            查询分页列表-分页信息
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.PagedListQueryResultPageModel.TotalCount">
            <summary>
            总数
            </summary>
        </member>
        <member name="P:FlexJobApi.Core.PagedListQueryResultPageModel.TotalPage">
            <summary>
            页数
            </summary>
        </member>
        <member name="M:FlexJobApi.Core.PagedListUtils.ToPagedListAsync``1(System.Linq.IQueryable{``0},FlexJobApi.Core.PagedListQueryPageModel,System.Threading.CancellationToken)">
            <summary>
            查询分页列表数据
            </summary>
            <typeparam name="TItem"></typeparam>
            <param name="q"></param>
            <param name="page"></param>
            <param name="cancellationToken"></param>
            <returns></returns>
        </member>
        <member name="M:FlexJobApi.Core.PagedListUtils.OrderBy``1(System.Linq.IQueryable{``0},System.Collections.Generic.List{FlexJobApi.Core.PagedListQueryPageModelOrderInput})">
            <summary>
            排序
            </summary>
            <typeparam name="T"></typeparam>
            <param name="q"></param>
            <param name="orders"></param>
            <returns></returns>
        </member>
        <member name="P:FlexJobApi.Core.ResourceModel.TraceId">
            <summary>
            跟踪Id
FlexJobApi.Core/Models/User/Auths/Commands/PasswordLoginCommand.cs
@@ -43,6 +43,15 @@
    /// </summary>
    public class PasswordLoginCommandCallback
    {
        /// <summary>
        /// 用户访问令牌
        /// </summary>
        public string AccessToken { get; set; }
        /// <summary>
        /// 刷新令牌
        /// </summary>
        public string RefreshToken { get; set; }
    }
}
FlexJobApi.Core/Models/User/Menus/Commands/DeleteMenuCommand.cs
@@ -11,17 +11,8 @@
    /// <summary>
    /// 删除菜单
    /// </summary>
    public class DeleteMenuCommand : IRequest<int>
    public class DeleteMenuCommand : DeleteCommand, IRequest<int>
    {
        public DeleteMenuCommand()
        {
            Ids = [];
        }
        /// <summary>
        /// Id
        /// </summary>
        [Required]
        public List<Guid> Ids { get; set; }
    }
}
FlexJobApi.Core/Models/User/Roles/Commands/DeleteRoleCommand.cs
@@ -1,12 +1,17 @@
using System;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core.Models.User.Roles.Commands
namespace FlexJobApi.Core
{
    internal class DeleteRoleCommand
    /// <summary>
    /// 删除角色
    /// </summary>
    public class DeleteRoleCommand : DeleteCommand, IRequest<int>
    {
    }
}
FlexJobApi.Core/Models/User/Roles/Commands/SaveRoleCommand.cs
@@ -1,12 +1,56 @@
using System;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core.Models.User.Roles.Commands
namespace FlexJobApi.Core
{
    internal class SaveRoleCommand
    /// <summary>
    /// 保存角色
    /// </summary>
    public class SaveRoleCommand : IRequest<Guid>
    {
        public SaveRoleCommand()
        {
            MenuIds = [];
            Resources = [];
        }
        /// <summary>
        /// Id
        /// </summary>
        public Guid? Id { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 用户类型
        /// </summary>
        public EnumUserType UserType { get; set; }
        /// <summary>
        /// 客户端类型
        /// </summary>
        public EnumClientType ClientType { get; set; }
        /// <summary>
        /// 最低级别
        /// </summary>
        public int MinLevel { get; set; }
        /// <summary>
        /// 菜单Id
        /// </summary>
        public List<Guid> MenuIds { get; set; }
        /// <summary>
        /// 资源
        /// </summary>
        public List<GetRoleQueryResultResource> Resources { get; set; }
    }
}
FlexJobApi.Core/Models/User/Roles/Queries/GetRoleQuery.cs
@@ -1,12 +1,83 @@
using System;
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core.Models.User.Roles.Queries
namespace FlexJobApi.Core
{
    internal class GetRoleQuery
    /// <summary>
    /// 查询角色详情
    /// </summary>
    public class GetRoleQuery : IRequest<GetRoleQueryResult>
    {
        /// <summary>
        /// Id
        /// </summary>
        public Guid Id { get; set; }
    }
    /// <summary>
    /// 查询角色详情-结果
    /// </summary>
    public class GetRoleQueryResult
    {
        public GetRoleQueryResult()
        {
            MenuIds = [];
            Resources = [];
        }
        /// <summary>
        /// Id
        /// </summary>
        public Guid Id { get; set; }
        /// <summary>
        /// 名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 用户类型
        /// </summary>
        public EnumUserType UserType { get; set; }
        /// <summary>
        /// 客户端类型
        /// </summary>
        public EnumClientType ClientType { get; set; }
        /// <summary>
        /// 最低级别
        /// </summary>
        public int MinLevel { get; set; }
        /// <summary>
        /// 菜单Id
        /// </summary>
        public List<Guid> MenuIds { get; set; }
        /// <summary>
        /// 资源
        /// </summary>
        public List<GetRoleQueryResultResource> Resources { get; set; }
    }
    /// <summary>
    /// 查询角色详情-结果-资源
    /// </summary>
    public class GetRoleQueryResultResource
    {
        /// <summary>
        /// 资源Id
        /// </summary>
        public Guid ResourceId { get; set; }
        /// <summary>
        /// 数据权限
        /// </summary>
        public EnumRoleWebApiDataPower DataPower { get; set; }
    }
}
FlexJobApi.Core/Utils/DeleteUtils/DeleteCommand.cs
New file
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    /// <summary>
    /// 删除命令
    /// </summary>
    public abstract class DeleteCommand
    {
        protected DeleteCommand()
        {
            Ids = [];
        }
        [Required]
        public List<Guid> Ids { get; set; }
    }
}
FlexJobApi.Core/Utils/PagedListUtils/PagedListQuery.cs
@@ -10,12 +10,17 @@
    /// <summary>
    /// 查询分页列表
    /// </summary>
    /// <typeparam name="TCallback"></typeparam>
    /// <typeparam name="TResult"></typeparam>
    /// <typeparam name="TItem"></typeparam>
    public abstract class PagedListQuery<TCallback, TItem>
        where TCallback : PagedListQueryResult<TItem>, new()
    public abstract class PagedListQuery<TResult, TItem>
        where TResult : PagedListQueryResult<TItem>, new()
        where TItem : class, new()
    {
        protected PagedListQuery()
        {
            PageModel = new PagedListQueryPageModel();
        }
        /// <summary>
        /// 分页信息
        /// </summary>
@@ -27,6 +32,13 @@
    /// </summary>
    public class PagedListQueryPageModel
    {
        public PagedListQueryPageModel()
        {
            Page = 1;
            Rows = 40;
            OrderInput = [];
        }
        /// <summary>
        /// 行数
        /// </summary>
@@ -38,9 +50,9 @@
        public int Page { get; set; }
        /// <summary>
        /// 总数
        /// 排序
        /// </summary>
        public int TotalCount { get; set; }
        public List<PagedListQueryPageModelOrderInput> OrderInput { get; set; }
    }
    /// <summary>
@@ -88,6 +100,11 @@
    public class PagedListQueryResultPageModel : PagedListQueryPageModel
    {
        /// <summary>
        /// 总数
        /// </summary>
        public int TotalCount { get; set; }
        /// <summary>
        /// 页数
        /// </summary>
        public int TotalPage { get; set; }
FlexJobApi.Core/Utils/PagedListUtils/PagedListUtils.cs
@@ -1,12 +1,99 @@
using System;
using FlexJobApi.User.Application;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using Mapster;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace FlexJobApi.Core
{
    public class PagedListUtils
    public static class PagedListUtils
    {
        /// <summary>
        /// 查询分页列表数据
        /// </summary>
        /// <typeparam name="TItem"></typeparam>
        /// <param name="q"></param>
        /// <param name="page"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task<PagedListQueryResult<TItem>> ToPagedListAsync<TItem>(this IQueryable<TItem> q, PagedListQueryPageModel page, CancellationToken cancellationToken = default)
            where TItem : class, new()
        {
            var pagedList = await q
                .OrderBy(page.OrderInput)
                .ToPagedListAsync(page.Page, page.Rows, cancellationToken);
            var result = new PagedListQueryResult<TItem>();
            result.PageModel = page.Adapt<PagedListQueryResultPageModel>();
            result.PageModel.TotalCount = pagedList.TotalCount;
            result.PageModel.TotalPage = pagedList.TotalPages;
            result.Data = pagedList.Items.ToList();
            return result;
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="q"></param>
        /// <param name="orders"></param>
        /// <returns></returns>
        public static IQueryable<T> OrderBy<T>(this IQueryable<T> q, List<PagedListQueryPageModelOrderInput> orders)
        {
            if (orders.IsNull()) return q;
            var entityType = typeof(T);
            int index = 0;
            foreach (var order in orders)
            {
                if (string.IsNullOrEmpty(order.Property)) continue;
                // 获取排序字段的属性信息
                var propertyInfo = entityType.GetProperty(order.Property);
                if (propertyInfo == null) throw Oops.Oh(EnumErrorCodeType.s404, $"该排序字段{order.Property}");
                // 创建表达式树
                var parameter = Expression.Parameter(entityType, "x");
                var propertyAccess = Expression.Property(parameter, propertyInfo);
                var lambda = Expression.Lambda(propertyAccess, parameter);
                string methodName;
                if (index == 0)
                {
                    // 首次排序
                    methodName = order.Order == EnumPagedListOrder.Ascending
                        ? "OrderBy"
                        : "OrderByDescending";
                }
                else
                {
                    // 二次及以后排序
                    methodName = order.Order == EnumPagedListOrder.Ascending
                        ? "ThenBy"
                        : "ThenByDescending";
                }
                // 调用相应的排序方法
                var resultExpression = Expression.Call(
                    typeof(Queryable),
                    methodName,
                    [entityType, propertyInfo.PropertyType],
                    q.Expression,
                    Expression.Quote(lambda)
                );
                q = q.Provider.CreateQuery<T>(resultExpression);
                index++;
            }
            return q;
        }
    }
}
FlexJobApi.User.Application/Auths/Commands/PasswordLoginCommandHandler.cs
@@ -54,7 +54,11 @@
            };
            JwtUtils.GenerateToken(logier);
            return new PasswordLoginCommandCallback();
            return new PasswordLoginCommandCallback
            {
                AccessToken = logier.AccessToken,
                RefreshToken = logier.RefreshToken,
            };
        }
    }
}
FlexJobApi.User.Application/FlexJobApi.User.Application.xml
@@ -236,6 +236,45 @@
            <param name="query"></param>
            <returns></returns>
        </member>
        <member name="T:FlexJobApi.User.Application.DeleteRoleCommandHandler">
            <summary>
            删除角色
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.DeleteRoleCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Role})">
            <summary>
            删除角色
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.DeleteRoleCommandHandler.Handle(FlexJobApi.Core.DeleteRoleCommand,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="T:FlexJobApi.User.Application.SaveRoleCommandHandler">
            <summary>
            保存角色
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.SaveRoleCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Role})">
            <summary>
            保存角色
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.SaveRoleCommandHandler.Handle(FlexJobApi.Core.SaveRoleCommand,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="T:FlexJobApi.User.Application.GetRoleQueryHandler">
            <summary>
            获取角色详情
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.GetRoleQueryHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Role})">
            <summary>
            获取角色详情
            </summary>
        </member>
        <member name="M:FlexJobApi.User.Application.GetRoleQueryHandler.Handle(FlexJobApi.Core.GetRoleQuery,System.Threading.CancellationToken)">
            <inheritdoc/>
        </member>
        <member name="T:FlexJobApi.User.Application.GetRolesQueryHandler">
            <summary>
            查询角色分页列表
FlexJobApi.User.Application/Roles/Commands/DeleteRoleCommandHandler.cs
New file
@@ -0,0 +1,35 @@
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.User.Application
{
    /// <summary>
    /// 删除角色
    /// </summary>
    public class DeleteRoleCommandHandler(
            IRepository<Role> rep
        ) : IRequestHandler<DeleteRoleCommand, int>
    {
        private readonly IRepository<Role> rep = rep;
        /// <inheritdoc/>
        public async Task<int> Handle(DeleteRoleCommand request, CancellationToken cancellationToken)
        {
            var entities = await rep.AsQueryable()
                .Include(it => it.RoleMenus)
                .Include(it => it.RoleResources)
                .Where(it => request.Ids.Contains(it.Id))
                .ToListAsync(cancellationToken);
            return entities.Any()
                ? await rep.DeleteNowAsync(entities, cancellationToken)
                : 0;
        }
    }
}
FlexJobApi.User.Application/Roles/Commands/SaveRoleCommandHandler.cs
New file
@@ -0,0 +1,60 @@
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using Mapster;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.User.Application
{
    /// <summary>
    /// 保存角色
    /// </summary>
    public class SaveRoleCommandHandler(
            IRepository<Role> rep
        ) : IRequestHandler<SaveRoleCommand, Guid>
    {
        private readonly IRepository<Role> rep = rep;
        /// <inheritdoc/>
        public async Task<Guid> Handle(SaveRoleCommand request, CancellationToken cancellationToken)
        {
            if (request.Id.HasValue)
            {
                var entity = await rep.AsQueryable()
                    .Include(it => it.RoleMenus)
                    .Include(it => it.RoleResources)
                    .FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken);
                if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "角色");
                request.Adapt(entity);
                await rep.UpdateAsync(entity);
                return entity.Id;
            }
            else
            {
                var entity = new Role();
                request.Adapt(entity);
                entity.RoleMenus = request.MenuIds
                    .Select(it => new RoleMenu
                    {
                        MenuId = it
                    })
                    .ToList();
                entity.RoleResources = request.Resources
                    .Select(it => new RoleResource
                    {
                        ResourceId = it.ResourceId,
                        DataPower = it.DataPower
                    })
                    .ToList();
                await rep.InsertAsync(entity);
                return entity.Id;
            }
        }
    }
}
FlexJobApi.User.Application/Roles/Queries/GetRoleQueryHandler.cs
New file
@@ -0,0 +1,47 @@
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Furion.FriendlyException;
using Mapster;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FlexJobApi.User.Application
{
    /// <summary>
    /// 获取角色详情
    /// </summary>
    public class GetRoleQueryHandler(
            IRepository<Role> rep
        ) : IRequestHandler<GetRoleQuery, GetRoleQueryResult>
    {
        private readonly IRepository<Role> rep = rep;
        /// <inheritdoc/>
        public async Task<GetRoleQueryResult> Handle(GetRoleQuery request, CancellationToken cancellationToken)
        {
            var entity = await rep.AsQueryable().AsNoTracking()
                .Where(it => it.Id == request.Id)
                .ProjectToType<GetRoleQueryResult>()
                .FirstOrDefaultAsync(cancellationToken);
            if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "该角色");
            entity.MenuIds = await rep.Change<RoleMenu>().AsQueryable().AsNoTracking()
                .Where(it => it.RoleId == request.Id)
                .Select(it => it.MenuId)
                .ToListAsync(cancellationToken);
            entity.Resources = await rep.Change<RoleResource>().AsQueryable().AsNoTracking()
                .Where(it => it.RoleId == request.Id)
                .ProjectToType<GetRoleQueryResultResource>()
                .ToListAsync(cancellationToken);
            return entity;
        }
    }
}
FlexJobApi.User.Application/Roles/Queries/GetRolesQueryHandler.cs
@@ -1,5 +1,6 @@
using FlexJobApi.Core;
using Furion.DatabaseAccessor;
using Mapster;
using MediatR;
using Microsoft.EntityFrameworkCore;
using System;
@@ -32,7 +33,11 @@
            {
                q = q.Where(it => it.ClientType == request.ClientType);
            }
            throw new NotImplementedException();
            var result = q
                .ProjectToType<GetRolesQueryResultItem>()
                .ToPagedListAsync(request.PageModel, cancellationToken);
            return result;
        }
    }
}