| | |
| | | public Task<Guid> Handle(SaveDictionaryCategoryCommand request, CancellationToken cancellationToken) |
| | | { |
| | | return request.SaveData<DictionaryCategory, SaveDictionaryCategoryCommand>( |
| | | (q, e, r) => q.Any(it => it.Id != request.Id && it.Code == request.Code), |
| | | it => it.Id != request.Id && it.Code == request.Code, |
| | | null, |
| | | cancellationToken); |
| | | } |
| | | } |
| | |
| | | using FlexJobApi.Core; |
| | | using Furion.DatabaseAccessor; |
| | | using Mapster; |
| | | using MediatR; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | |
| | | public Task<Guid> Handle(SaveDictionaryDataCommand request, CancellationToken cancellationToken) |
| | | { |
| | | return request.SaveData<DictionaryData, SaveDictionaryDataCommand>( |
| | | (q, e, r) => q.Any(it => |
| | | it => |
| | | it.CategoryId == request.CategoryId |
| | | && it.ParentId == request.ParentId |
| | | && it.Code == request.Code |
| | | && it.Content == request.Content), cancellationToken); |
| | | && it.Content == request.Content |
| | | && it.Id != request.Id, |
| | | (entity) => |
| | | { |
| | | entity.Path = DbUtils.GetTreeDataPath<DictionaryData>(request.ParentId, cancellationToken).Result; |
| | | if (request.Id.HasValue) |
| | | { |
| | | DbUtils.UpdateTreeDataChildrenPath<DictionaryData>( |
| | | $"{entity.Path}/{entity.Code}/", |
| | | $"{entity.Path}/{request.Code}/", |
| | | cancellationToken).Wait(); |
| | | } |
| | | request.Adapt(entity); |
| | | }, |
| | | cancellationToken); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// <returns></returns> |
| | | public Task<int> Handle(SetDictionaryDataIsDisabledCommand request, CancellationToken cancellationToken) |
| | | { |
| | | return request.SetIsDisable<DictionaryData>(cancellationToken: cancellationToken); |
| | | return request.SetIsDisabled<DictionaryData>(cancellationToken: cancellationToken); |
| | | } |
| | | } |
| | | } |
| | |
| | | public class DictionaryCategoriesQueryHandler( |
| | | IRepository<DictionaryCategory> rep |
| | | ) : IRequestHandler<GetDictionaryCategoriesQuery, PagedListQueryResult<GetDictionaryCategoriesQueryResultItem>>, |
| | | IRequestHandler<GetDictionaryCategorySelectQuery, List<SelectQueryResultItem<Guid>>> |
| | | IRequestHandler<GetDictionaryCategorySelectQuery, List<SelectQueryResultOption<Guid, GetDictionaryCategorySelectQueryOption>>> |
| | | { |
| | | private readonly IRepository<DictionaryCategory> rep = rep; |
| | | |
| | |
| | | /// <returns></returns> |
| | | public Task<PagedListQueryResult<GetDictionaryCategoriesQueryResultItem>> Handle(GetDictionaryCategoriesQuery request, CancellationToken cancellationToken) |
| | | { |
| | | return request.PageModel.ToPagedListAsync<DictionaryCategory, GetDictionaryCategoriesQueryResultItem>( |
| | | return request.PageModel.GetPagedListAsync<DictionaryCategory, GetDictionaryCategoriesQueryResultItem>( |
| | | q => |
| | | { |
| | | q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); |
| | | if (request.Keywords.IsNotNull()) |
| | | { |
| | | q = q.Where(it => |
| | |
| | | /// <param name="request"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public Task<List<SelectQueryResultItem<Guid>>> Handle(GetDictionaryCategorySelectQuery request, CancellationToken cancellationToken) |
| | | public Task<List<SelectQueryResultOption<Guid, GetDictionaryCategorySelectQueryOption>>> Handle(GetDictionaryCategorySelectQuery request, CancellationToken cancellationToken) |
| | | { |
| | | var items = rep.AsQueryable().AsNoTracking() |
| | | .Select(it => new SelectQueryResultItem<Guid> |
| | | { |
| | | Value = it.Id, |
| | | Label = it.Name, |
| | | Data = new |
| | | { |
| | | it.Id, |
| | | it.Name, |
| | | it.Remark, |
| | | it.FieldNames |
| | | } |
| | | }) |
| | | .ToListAsync(cancellationToken); |
| | | return items; |
| | | return request.GetSelect<DictionaryCategory, Guid, GetDictionaryCategorySelectQueryOption>( |
| | | it => it.Id, |
| | | it => it.Name, |
| | | null, |
| | | cancellationToken); |
| | | } |
| | | } |
| | | } |
| | |
| | | using FlexJobApi.Core; |
| | | using Furion.DatabaseAccessor; |
| | | using Furion.FriendlyException; |
| | | using Mapster; |
| | | using MediatR; |
| | | using Microsoft.EntityFrameworkCore; |
| | |
| | | /// </summary> |
| | | public class DictionaryDatasQueryHandler( |
| | | IRepository<DictionaryData> rep |
| | | ) : IRequestHandler<GetDictionaryDatasQuery, PagedListQueryResult<GetDictionaryDatasQueryResultItem>> |
| | | ) : IRequestHandler<GetDictionaryDatasQuery, PagedListQueryResult<GetDictionaryDatasQueryResultItem>>, |
| | | IRequestHandler<GetDictionaryDataSelectQuery, List<SelectQueryResultOption<Guid, GetDictionaryDataSelectQueryResultOption>>> |
| | | { |
| | | private readonly IRepository<DictionaryData> rep = rep; |
| | | |
| | |
| | | /// <returns></returns> |
| | | public Task<PagedListQueryResult<GetDictionaryDatasQueryResultItem>> Handle(GetDictionaryDatasQuery request, CancellationToken cancellationToken) |
| | | { |
| | | return request.PageModel.ToPagedListAsync<DictionaryData, GetDictionaryDatasQueryResultItem>( |
| | | return request.PageModel.GetPagedListAsync<DictionaryData, GetDictionaryDatasQueryResultItem>( |
| | | q => |
| | | { |
| | | q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); |
| | | if (request.CategoryId.HasValue) |
| | | { |
| | | q = q.Where(it => it.CategoryId == request.CategoryId); |
| | | } |
| | | else if (request.CategoryCode.IsNotNull()) |
| | | { |
| | | q = q.Where(it => it.Category.Code == request.CategoryCode); |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Oh(EnumErrorCodeType.s400, "请填写类别Id或编号"); |
| | | } |
| | | if (request.Keywords.IsNotNull()) |
| | | { |
| | |
| | | return q; |
| | | }, cancellationToken: cancellationToken); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询数据字典选择器 |
| | | /// </summary> |
| | | /// <param name="request"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public Task<List<SelectQueryResultOption<Guid, GetDictionaryDataSelectQueryResultOption>>> Handle(GetDictionaryDataSelectQuery request, CancellationToken cancellationToken) |
| | | { |
| | | return request.GetSelect<DictionaryData, Guid, GetDictionaryDataSelectQueryResultOption>( |
| | | it => it.Id, |
| | | it => it.Content, |
| | | q => |
| | | { |
| | | q = q |
| | | .OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime) |
| | | .Where(it => |
| | | it.ParentId == request.ParentId |
| | | && !it.IsDisabled); |
| | | if (request.CategoryId.HasValue) |
| | | { |
| | | q = q.Where(it => it.CategoryId == request.CategoryId); |
| | | } |
| | | else if (request.CategoryCode.IsNotNull()) |
| | | { |
| | | q = q.Where(it => it.Category.Code == request.CategoryCode); |
| | | } |
| | | else |
| | | { |
| | | throw Oops.Oh(EnumErrorCodeType.s400, "请填写类别Id或编号"); |
| | | } |
| | | return q; |
| | | }, |
| | | cancellationToken); |
| | | } |
| | | } |
| | | } |
| | |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Application.DictionaryDatasQueryHandler.Handle(FlexJobApi.Core.GetDictionaryDataSelectQuery,System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 查询数据字典选择器 |
| | | </summary> |
| | | <param name="request"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | </members> |
| | | </doc> |
| | |
| | | /// <summary> |
| | | /// 字典数据 |
| | | /// </summary> |
| | | public class DictionaryData : CommonEntity, IEntityTypeBuilder<DictionaryData>, IIsDisabled |
| | | public class DictionaryData : CommonEntity, IEntityTypeBuilder<DictionaryData>, ITreeData<DictionaryData>, IIsDisabled |
| | | { |
| | | public DictionaryData() |
| | | { |
| | |
| | | /// <summary> |
| | | /// 菜单 |
| | | /// </summary> |
| | | public class Menu : CommonEntity, IEntityTypeBuilder<Menu>, IIsDisabled |
| | | public class Menu : CommonEntity, IEntityTypeBuilder<Menu>, ITreeData<Menu>, IIsDisabled |
| | | { |
| | | public Menu() |
| | | { |
| | |
| | | 物理删除 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.ITreeData`1"> |
| | | <summary> |
| | | 树形数据 |
| | | </summary> |
| | | <typeparam name="TEntity"></typeparam> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.ITreeData`1.ParentId"> |
| | | <summary> |
| | | 上级Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.ITreeData`1.Parent"> |
| | | <summary> |
| | | 上级 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.ITreeData`1.Children"> |
| | | <summary> |
| | | 下级 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.ITreeData`1.Path"> |
| | | <summary> |
| | | 字典路径 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.ITreeData`1.Code"> |
| | | <summary> |
| | | 编号 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.DeleteDictionaryCategoryCommand"> |
| | | <summary> |
| | | 删除数据字典类别 |
| | |
| | | <member name="T:FlexJobApi.Core.GetDictionaryCategorySelectQuery"> |
| | | <summary> |
| | | 查询数据字典类别选择器数据 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption"> |
| | | <summary> |
| | | 查询数据字典类别选择器数据-结果-选项 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption.Id"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption.Code"> |
| | | <summary> |
| | | 编号 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption.Name"> |
| | | <summary> |
| | | 名称 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption.FieldNames"> |
| | | <summary> |
| | | 字段名(逗号隔开) |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryCategorySelectQueryOption.Remark"> |
| | | <summary> |
| | | 备注 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.GetDictionaryDataSelectQuery"> |
| | | <summary> |
| | | 查询数据字典选择器 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQuery.CategoryId"> |
| | | <summary> |
| | | 类别Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQuery.ParentId"> |
| | | <summary> |
| | | 上级Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Id"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Path"> |
| | | <summary> |
| | | 字典路径 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Code"> |
| | | <summary> |
| | | 编号 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Content"> |
| | | <summary> |
| | | 显示内容 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Field1"> |
| | | <summary> |
| | | 字段1 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Field2"> |
| | | <summary> |
| | | 字段2 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Field3"> |
| | | <summary> |
| | | 字段3 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Field4"> |
| | | <summary> |
| | | 字段4 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.GetDictionaryDataSelectQueryResultOption.Field5"> |
| | | <summary> |
| | | 字段5 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.GetDictionaryDatasQuery"> |
| | |
| | | 保存菜单按钮 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuButtonCommand.Id"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuButtonCommand.ParentId"> |
| | | <summary> |
| | | 菜单Id |
| | |
| | | <member name="T:FlexJobApi.Core.SaveMenuCommand"> |
| | | <summary> |
| | | 保存菜单 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuCommand.Id"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuCommand.UserType"> |
| | |
| | | <member name="T:FlexJobApi.Core.SaveMenuFieldCommand"> |
| | | <summary> |
| | | 保存菜单字段 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuFieldCommand.Id"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SaveMenuFieldCommand.ParentId"> |
| | |
| | | 设置角色是否禁用 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SetRoleIsDisabledCommand.Ids"> |
| | | <summary> |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SetRoleIsDisabledCommand.IsDisabled"> |
| | | <summary> |
| | | 是否禁用 |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.SetRoleUserInfosCommand"> |
| | | <summary> |
| | | 设置角色用户 |
| | |
| | | 数据库工具 |
| | | </summary> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.ToPagedListAsync``2(FlexJobApi.Core.PagedListQueryPageModel,System.Func{System.Linq.IQueryable{``0},System.Linq.IQueryable{``0}},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Threading.CancellationToken)"> |
| | | <member name="M:FlexJobApi.Core.DbUtils.GetTreeDataPath``1(System.Nullable{System.Guid},System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 获取树形数据路径 |
| | | </summary> |
| | | <typeparam name="TEntity"></typeparam> |
| | | <param name="parentId"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.UpdateTreeDataChildrenPath``1(System.String,System.String,System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 更新树形数据下级路径 |
| | | </summary> |
| | | <param name="oldPath"></param> |
| | | <param name="newPath"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.GetSelect``3(FlexJobApi.Core.SelectQuery{``1,``2},System.Func{``2,``1},System.Func{``2,System.String},System.Func{System.Linq.IQueryable{``0},System.Linq.IQueryable{``0}},System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 查询选择器数据 |
| | | </summary> |
| | | <typeparam name="TEntity"></typeparam> |
| | | <typeparam name="TValue"></typeparam> |
| | | <typeparam name="TData"></typeparam> |
| | | <param name="request"></param> |
| | | <param name="getValue"></param> |
| | | <param name="getLabel"></param> |
| | | <param name="query"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.GetPagedListAsync``2(FlexJobApi.Core.PagedListQueryPageModel,System.Func{System.Linq.IQueryable{``0},System.Linq.IQueryable{``0}},System.Linq.Expressions.Expression{System.Func{``0,``1}},System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 查询分页列表数据 |
| | | </summary> |
| | |
| | | <param name="orders"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.SetIsDisable``1(FlexJobApi.Core.SetIsDisabledCommand,System.Func{System.Linq.IQueryable{``0},System.Linq.IQueryable{``0}},System.Threading.CancellationToken)"> |
| | | <member name="M:FlexJobApi.Core.DbUtils.SetIsDisabled``1(FlexJobApi.Core.SetIsDisabledCommand,System.Func{System.Linq.IQueryable{``0},System.Linq.IQueryable{``0}},System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 设置是否禁用 |
| | | </summary> |
| | |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.Core.DbUtils.SaveData``2(``1,System.Func{System.Linq.IQueryable{``0},``0,``1,System.Boolean},System.Threading.CancellationToken)"> |
| | | <member name="M:FlexJobApi.Core.DbUtils.SaveData``2(``1,System.Linq.Expressions.Expression{System.Func{``0,System.Boolean}},System.Action{``0},System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 保存数据 |
| | | </summary> |
| | |
| | | <typeparam name="TRequest"></typeparam> |
| | | <param name="request"></param> |
| | | <param name="checkExist"></param> |
| | | <param name="update"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | |
| | | Id |
| | | </summary> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.SelectQuery`1"> |
| | | <member name="T:FlexJobApi.Core.SelectQuery`2"> |
| | | <summary> |
| | | 选择器查询 |
| | | </summary> |
| | | <typeparam name="TValue"></typeparam> |
| | | <typeparam name="TData"></typeparam> |
| | | </member> |
| | | <member name="T:FlexJobApi.Core.SelectQueryResultItem`1"> |
| | | <member name="T:FlexJobApi.Core.SelectQueryResultOption`2"> |
| | | <summary> |
| | | 选择器查询-结果-项 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultItem`1.Value"> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultOption`2.Value"> |
| | | <summary> |
| | | 值 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultItem`1.Label"> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultOption`2.Label"> |
| | | <summary> |
| | | 标签 |
| | | </summary> |
| | | </member> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultItem`1.Data"> |
| | | <member name="P:FlexJobApi.Core.SelectQueryResultOption`2.Data"> |
| | | <summary> |
| | | 数据 |
| | | </summary> |
New file |
| | |
| | | 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> |
| | | /// <typeparam name="TEntity"></typeparam> |
| | | public interface ITreeData<TEntity> |
| | | where TEntity : CommonEntity, ITreeData<TEntity>, new() |
| | | { |
| | | /// <summary> |
| | | /// 上级Id |
| | | /// </summary> |
| | | Guid? ParentId { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 上级 |
| | | /// </summary> |
| | | TEntity Parent { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 下级 |
| | | /// </summary> |
| | | List<TEntity> Children { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字典路径 |
| | | /// </summary> |
| | | string Path { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 编号 |
| | | /// </summary> |
| | | string Code { get; set; } |
| | | } |
| | | } |
| | |
| | | using Newtonsoft.Json.Linq; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.ComponentModel.DataAnnotations; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Threading.Tasks; |
| | |
| | | /// 查询数据字典类别选择器数据 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Dictionary])] |
| | | public class GetDictionaryCategorySelectQuery : SelectQuery<Guid> |
| | | public class GetDictionaryCategorySelectQuery : SelectQuery<Guid, GetDictionaryCategorySelectQueryOption> |
| | | { |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询数据字典类别选择器数据-结果-选项 |
| | | /// </summary> |
| | | public class GetDictionaryCategorySelectQueryOption |
| | | { |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | public Guid Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 编号 |
| | | /// </summary> |
| | | public string Code { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 名称 |
| | | /// </summary> |
| | | public string Name { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段名(逗号隔开) |
| | | /// </summary> |
| | | public string FieldNames { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 备注 |
| | | /// </summary> |
| | | public string Remark { get; set; } |
| | | } |
| | | } |
New file |
| | |
| | | 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> |
| | | [Resource([EnumResourceController.Dictionary])] |
| | | public class GetDictionaryDataSelectQuery : SelectQuery<Guid, GetDictionaryDataSelectQueryResultOption> |
| | | { |
| | | /// <summary> |
| | | /// 类别Id(Id/编号二选一) |
| | | /// </summary> |
| | | public Guid? CategoryId { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 类别编号(Id/编号二选一) |
| | | /// </summary> |
| | | public string CategoryCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 上级Id |
| | | /// </summary> |
| | | public Guid? ParentId { get; set; } |
| | | } |
| | | |
| | | public class GetDictionaryDataSelectQueryResultOption |
| | | { |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | public Guid Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字典路径 |
| | | /// </summary> |
| | | public string Path { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 编号 |
| | | /// </summary> |
| | | [MaxLength(128)] |
| | | public string Code { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 显示内容 |
| | | /// </summary> |
| | | [Required] |
| | | public string Content { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段1 |
| | | /// </summary> |
| | | public string Field1 { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段2 |
| | | /// </summary> |
| | | public string Field2 { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段3 |
| | | /// </summary> |
| | | public string Field3 { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段4 |
| | | /// </summary> |
| | | public string Field4 { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 字段5 |
| | | /// </summary> |
| | | public string Field5 { get; set; } |
| | | } |
| | | } |
| | |
| | | public class GetDictionaryDatasQuery : PagedListQuery<PagedListQueryResult<GetDictionaryDatasQueryResultItem>, GetDictionaryDatasQueryResultItem> |
| | | { |
| | | /// <summary> |
| | | /// 类别Id |
| | | /// 类别Id(Id/编号二选一) |
| | | /// </summary> |
| | | public Guid? CategoryId { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 类别编号(Id/编号二选一) |
| | | /// </summary> |
| | | public string CategoryCode { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 关键字 |
| | | /// </summary> |
| | | public string Keywords { get; set; } |
| | |
| | | /// 保存菜单按钮 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Menu])] |
| | | public class SaveMenuButtonCommand : IRequest<Guid> |
| | | public class SaveMenuButtonCommand : SaveDataCommand |
| | | { |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | public Guid? Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 菜单Id |
| | | /// </summary> |
| | |
| | | /// 保存菜单 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Menu])] |
| | | public class SaveMenuCommand : IRequest<Guid> |
| | | public class SaveMenuCommand : SaveDataCommand |
| | | { |
| | | public SaveMenuCommand() |
| | | { |
| | | Groups = []; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | public Guid? Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 用户类型 |
| | |
| | | /// 保存菜单字段 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Menu])] |
| | | public class SaveMenuFieldCommand : IRequest<Guid> |
| | | public class SaveMenuFieldCommand : SaveDataCommand |
| | | { |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | public Guid? Id { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 菜单Id |
| | | /// </summary> |
| | |
| | | /// 设置角色是否禁用 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Role])] |
| | | public class SetRoleIsDisabledCommand : IRequest<int> |
| | | public class SetRoleIsDisabledCommand : SetIsDisabledCommand |
| | | { |
| | | public SetRoleIsDisabledCommand() |
| | | { |
| | | Ids = []; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Id |
| | | /// </summary> |
| | | [Required] |
| | | public List<Guid> Ids { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 是否禁用 |
| | | /// </summary> |
| | | public bool IsDisabled { get; set; } |
| | | } |
| | | } |
| | |
| | | using System.Text; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using System.Timers; |
| | | |
| | | namespace FlexJobApi.Core |
| | | { |
| | |
| | | /// </summary> |
| | | public static class DbUtils |
| | | { |
| | | /// <summary> |
| | | /// 获取树形数据路径 |
| | | /// </summary> |
| | | /// <typeparam name="TEntity"></typeparam> |
| | | /// <param name="parentId"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<string> GetTreeDataPath<TEntity>( |
| | | Guid? parentId, |
| | | CancellationToken cancellationToken = default) |
| | | where TEntity : CommonEntity, ITreeData<TEntity>, new() |
| | | { |
| | | var rep = Db.GetRepository<TEntity>(); |
| | | if (parentId.HasValue) |
| | | { |
| | | var parent = await rep.AsQueryable().AsNoTracking() |
| | | .Where(it => it.Id == parentId) |
| | | .Select(it => new |
| | | { |
| | | it.Path, |
| | | it.Code |
| | | }) |
| | | .FirstOrDefaultAsync(cancellationToken); |
| | | var summary = typeof(TEntity).GetSummary(); |
| | | if (parent == null) throw Oops.Oh(EnumErrorCodeType.s404, $"上级{summary}"); |
| | | return $"{parent.Path}{parent.Code}/"; |
| | | } |
| | | else |
| | | { |
| | | return "/"; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 更新树形数据下级路径 |
| | | /// </summary> |
| | | /// <param name="oldPath"></param> |
| | | /// <param name="newPath"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task UpdateTreeDataChildrenPath<TEntity>( |
| | | string oldPath, |
| | | string newPath, |
| | | CancellationToken cancellationToken) |
| | | where TEntity : CommonEntity, ITreeData<TEntity>, new() |
| | | { |
| | | var rep = Db.GetRepository<TEntity>(); |
| | | var models = await rep.AsQueryable() |
| | | .Where(it => it.Path.StartsWith(oldPath)) |
| | | .ToListAsync(cancellationToken); |
| | | if (models.IsNotNull()) |
| | | { |
| | | foreach (var model in models) |
| | | { |
| | | model.Path = model.Path.Replace(oldPath, newPath); |
| | | } |
| | | await rep.UpdateAsync(models); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询选择器数据 |
| | | /// </summary> |
| | | /// <typeparam name="TEntity"></typeparam> |
| | | /// <typeparam name="TValue"></typeparam> |
| | | /// <typeparam name="TData"></typeparam> |
| | | /// <param name="request"></param> |
| | | /// <param name="getValue"></param> |
| | | /// <param name="getLabel"></param> |
| | | /// <param name="query"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<List<SelectQueryResultOption<TValue, TData>>> GetSelect<TEntity, TValue, TData>( |
| | | this SelectQuery<TValue, TData> request, |
| | | Func<TData, TValue> getValue, |
| | | Func<TData, string> getLabel, |
| | | Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, |
| | | CancellationToken cancellationToken = default) |
| | | where TEntity : CommonEntity, new() |
| | | { |
| | | var rep = Db.GetRepository<TEntity>(); |
| | | var q = rep.AsQueryable().AsNoTracking(); |
| | | if (query != null) q = query(q); |
| | | else q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); |
| | | var models = await q |
| | | .ProjectToType<TData>() |
| | | .ToListAsync(cancellationToken); |
| | | var options = new List<SelectQueryResultOption<TValue, TData>>(); |
| | | foreach (var model in models) |
| | | { |
| | | var option = new SelectQueryResultOption<TValue, TData>(); |
| | | option.Data = model; |
| | | option.Value = getValue(model); |
| | | option.Label = getLabel(model); |
| | | options.Add(option); |
| | | } |
| | | return options; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 查询分页列表数据 |
| | | /// </summary> |
| | |
| | | /// <param name="selector"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<PagedListQueryResult<TItem>> ToPagedListAsync<TEntity, TItem>( |
| | | public static async Task<PagedListQueryResult<TItem>> GetPagedListAsync<TEntity, TItem>( |
| | | this PagedListQueryPageModel page, |
| | | Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, |
| | | Expression<Func<TEntity, TItem>> selector = null, |
| | |
| | | var rep = Db.GetRepository<TEntity>(); |
| | | var q = rep.AsQueryable().AsNoTracking(); |
| | | if (query != null) q = query(q); |
| | | else q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); |
| | | q = q.OrderBy(page.OrderInput); |
| | | var s = selector == null |
| | | ? q.ProjectToType<TItem>() |
| | |
| | | /// <param name="q"></param> |
| | | /// <param name="orders"></param> |
| | | /// <returns></returns> |
| | | public static IQueryable<T> OrderBy<T>(this IQueryable<T> q, List<PagedListQueryPageModelOrderInput> orders) |
| | | public static IQueryable<T> OrderBy<T>( |
| | | this IQueryable<T> q, |
| | | List<PagedListQueryPageModelOrderInput> orders) |
| | | { |
| | | if (orders.IsNull()) return q; |
| | | |
| | |
| | | /// <param name="query"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<int> SetIsDisable<TEntity>(this SetIsDisabledCommand request, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) |
| | | public static async Task<int> SetIsDisabled<TEntity>( |
| | | this SetIsDisabledCommand request, |
| | | Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, |
| | | CancellationToken cancellationToken = default) |
| | | where TEntity : CommonEntity, IIsDisabled, new() |
| | | { |
| | | var rep = Db.GetRepository<TEntity>(); |
| | |
| | | /// <param name="query"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<int> DeleteData<TEntity>(this DeleteDataCommand request, Func<IQueryable<TEntity>, IQueryable<TEntity>> query = null, CancellationToken cancellationToken = default) |
| | | public static async Task<int> DeleteData<TEntity>( |
| | | this DeleteDataCommand request, Func<IQueryable<TEntity>, |
| | | IQueryable<TEntity>> query = null, |
| | | CancellationToken cancellationToken = default) |
| | | where TEntity : CommonEntity, new() |
| | | { |
| | | var rep = Db.GetRepository<TEntity>(); |
| | |
| | | /// <typeparam name="TRequest"></typeparam> |
| | | /// <param name="request"></param> |
| | | /// <param name="checkExist"></param> |
| | | /// <param name="update"></param> |
| | | /// <param name="cancellationToken"></param> |
| | | /// <returns></returns> |
| | | public static async Task<Guid> SaveData<TEntity, TRequest>(this TRequest request, Func<IQueryable<TEntity>, TEntity, TRequest, bool> checkExist = null, CancellationToken cancellationToken = default) |
| | | public static async Task<Guid> SaveData<TEntity, TRequest>( |
| | | this TRequest request, |
| | | Expression<Func<TEntity, bool>> checkExist = null, |
| | | Action<TEntity> update = null, |
| | | CancellationToken cancellationToken = default) |
| | | where TEntity : CommonEntity, new() |
| | | where TRequest : SaveDataCommand, new() |
| | | { |
| | | var xmlDoc = await XmlDocUtils.GetXmlDocAsync(); |
| | | var summary = await typeof(TEntity).GetSummary(xmlDoc); |
| | | var rep = Db.GetRepository<TEntity>(); |
| | | if (checkExist != null && await rep.AsQueryable().AsNoTracking().AnyAsync(checkExist)) |
| | | throw Oops.Oh(EnumErrorCodeType.s405, $"该{summary ?? "信息"}"); |
| | | if (request.Id.HasValue) |
| | | { |
| | | var entity = await rep.AsQueryable().FirstOrDefaultAsync(it => it.Id == request.Id, cancellationToken); |
| | | if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, $"该{summary ?? "信息"}"); |
| | | if (checkExist != null && checkExist(rep.AsQueryable().AsNoTracking(), entity, request)) throw Oops.Oh(EnumErrorCodeType.s405, $"该{summary ?? "信息"}"); |
| | | request.Adapt(entity); |
| | | if (update != null) update(entity); |
| | | else request.Adapt(entity); |
| | | await rep.UpdateAsync(entity); |
| | | return entity.Id; |
| | | } |
| | | else |
| | | { |
| | | var entity = new TEntity(); |
| | | if (checkExist != null && checkExist(rep.AsQueryable().AsNoTracking(), entity, request)) throw Oops.Oh(EnumErrorCodeType.s405, $"该{summary ?? "信息"}"); |
| | | request.Adapt(entity); |
| | | if (update != null) update(entity); |
| | | else request.Adapt(entity); |
| | | await rep.InsertAsync(entity); |
| | | return entity.Id; |
| | | } |
| | |
| | | /// 选择器查询 |
| | | /// </summary> |
| | | /// <typeparam name="TValue"></typeparam> |
| | | public abstract class SelectQuery<TValue> : IRequest<List<SelectQueryResultItem<TValue>>> |
| | | /// <typeparam name="TData"></typeparam> |
| | | public abstract class SelectQuery<TValue, TData> : IRequest<List<SelectQueryResultOption<TValue, TData>>> |
| | | { |
| | | |
| | | } |
| | |
| | | /// <summary> |
| | | /// 选择器查询-结果-项 |
| | | /// </summary> |
| | | public class SelectQueryResultItem<TValue> |
| | | public class SelectQueryResultOption<TValue, TData> |
| | | { |
| | | /// <summary> |
| | | /// 值 |
| | |
| | | var all = await (from m in repMenu.AsQueryable().AsNoTracking() |
| | | join rm in repRoleMenu.AsQueryable().AsNoTracking() on m.Id equals rm.MenuId |
| | | join ur in repUserInfoRole.AsQueryable().AsNoTracking() on rm.RoleId equals ur.RoleId |
| | | where ur.UserInfoId == logier.UserInfoId |
| | | where ur.UserInfoId == logier.UserInfoId && !m.IsDisabled |
| | | && (m.Type == EnumMenuType.Menu || m.Type == EnumMenuType.Page || m.Type == EnumMenuType.Modal) |
| | | select m).ProjectToType<GetMenusQueryResultItem>().ToListAsync(); |
| | | var models = all.Where(it => it.ParentId == null).ToList(); |
| | |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuButtonCommandHandler.Handle(FlexJobApi.Core.SaveMenuButtonCommand,System.Threading.CancellationToken)"> |
| | | <inheritdoc/> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuButtonCommandHandler.CheckExist(FlexJobApi.Core.Menu)"> |
| | | <summary> |
| | | 校验菜单是否重复 |
| | | </summary> |
| | | <param name="entity"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="T:FlexJobApi.User.Application.SaveMenuCommandHandler"> |
| | | <summary> |
| | | 保存菜单 |
| | |
| | | <param name="request"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuCommandHandler.CheckExist(FlexJobApi.Core.Menu,System.Nullable{System.Guid},System.String)"> |
| | | <summary> |
| | | 校验菜单是否重复 |
| | | </summary> |
| | | <param name="entity"></param> |
| | | <param name="parentId"></param> |
| | | <param name="code"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuCommandHandler.GetPathAsync(System.Nullable{System.Guid},System.String,System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 获取地址 |
| | | </summary> |
| | | <param name="parentId"></param> |
| | | <param name="code"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuCommandHandler.UpdateChildrensPath(System.String,System.String,System.Threading.CancellationToken)"> |
| | | <summary> |
| | | 更新下级菜单路径 |
| | | </summary> |
| | | <param name="oldPath"></param> |
| | | <param name="newPath"></param> |
| | | <param name="cancellationToken"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="T:FlexJobApi.User.Application.SaveMenuFieldCommandHandler"> |
| | | <summary> |
| | | |
| | |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuFieldCommandHandler.Handle(FlexJobApi.Core.SaveMenuFieldCommand,System.Threading.CancellationToken)"> |
| | | <inheritdoc/> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SaveMenuFieldCommandHandler.CheckExist(FlexJobApi.Core.Menu)"> |
| | | <summary> |
| | | 校验菜单是否重复 |
| | | </summary> |
| | | <param name="entity"></param> |
| | | <returns></returns> |
| | | </member> |
| | | <member name="T:FlexJobApi.User.Application.SetMenuSwitchCommandHandler"> |
| | | <summary> |
| | |
| | | 设置角色是否禁用 |
| | | </summary> |
| | | </member> |
| | | <member name="M:FlexJobApi.User.Application.SetRoleIsDisabledCommandHandler.#ctor(Furion.DatabaseAccessor.IRepository{FlexJobApi.Core.Role})"> |
| | | <member name="M:FlexJobApi.User.Application.SetRoleIsDisabledCommandHandler.#ctor"> |
| | | <summary> |
| | | 设置角色是否禁用 |
| | | </summary> |
| | |
| | | { |
| | | var parent = await rep.FirstOrDefaultAsync(it => it.Id == request.ParentId); |
| | | if (parent == null) throw Oops.Oh(EnumErrorCodeType.s404, "上级菜单"); |
| | | return await request.SaveData<Menu, SaveMenuButtonCommand>( |
| | | it => |
| | | it.ParentId == request.ParentId |
| | | && it.Type == EnumMenuType.Button |
| | | && it.Group == request.Group |
| | | && it.Location == request.Location |
| | | && it.Code == request.Code |
| | | && it.Id != request.Id, |
| | | (entity) => |
| | | { |
| | | if (request.Id.HasValue) |
| | | { |
| | | var entity = await rep.FirstOrDefaultAsync(it => it.Id == request.Id); |
| | | if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "该菜单"); |
| | | if (entity.ParentId != request.ParentId) throw Oops.Oh(EnumErrorCodeType.s410, "上级Id"); |
| | | request.Adapt(entity); |
| | | if (await CheckExist(entity)) throw Oops.Oh(EnumErrorCodeType.s406, "菜单编号"); |
| | | await rep.UpdateAsync(entity); |
| | | return entity.Id; |
| | | } |
| | | else |
| | | { |
| | | var entity = new Menu(); |
| | | entity.Path = $"{parent.Path}{parent.Code}/"; |
| | | entity.Type = EnumMenuType.Button; |
| | | entity.VisitLevel = parent.VisitLevel; |
| | | } |
| | | request.Adapt(entity); |
| | | if (await CheckExist(entity)) throw Oops.Oh(EnumErrorCodeType.s406, "菜单编号"); |
| | | await rep.InsertAsync(entity); |
| | | return entity.Id; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 校验菜单是否重复 |
| | | /// </summary> |
| | | /// <param name="entity"></param> |
| | | /// <returns></returns> |
| | | private async Task<bool> CheckExist(Menu entity) |
| | | { |
| | | return await rep.AsQueryable().AsNoTracking() |
| | | .AnyAsync(it => |
| | | it.ParentId == entity.ParentId |
| | | && it.Type == entity.Type |
| | | && it.Group == entity.Group |
| | | && it.Location == entity.Location |
| | | && it.Code == entity.Code |
| | | && it.Id != entity.Id); |
| | | }, |
| | | cancellationToken); |
| | | } |
| | | } |
| | | } |
| | |
| | | using FlexJobApi.Core; |
| | | using Consul; |
| | | using FlexJobApi.Core; |
| | | using Furion.DatabaseAccessor; |
| | | using Furion.DataValidation; |
| | | using Furion.FriendlyException; |
| | |
| | | /// <inheritdoc/> |
| | | public async Task<Guid> Handle(SaveMenuCommand request, CancellationToken cancellationToken) |
| | | { |
| | | 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<DictionaryData>(request.ParentId, cancellationToken).Result; |
| | | 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); |
| | | DbUtils.UpdateTreeDataChildrenPath<DictionaryData>( |
| | | $"{entity.Path}/{entity.Code}/", |
| | | $"{entity.Path}/{request.Code}/", |
| | | cancellationToken).Wait(); |
| | | } |
| | | 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; |
| | | } |
| | | }, |
| | | cancellationToken); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | var parent = await rep.FirstOrDefaultAsync(it => it.Id == request.ParentId); |
| | | if (parent == null) throw Oops.Oh(EnumErrorCodeType.s404, "上级菜单"); |
| | | return await request.SaveData<Menu, SaveMenuFieldCommand>( |
| | | it => |
| | | it.ParentId == request.ParentId |
| | | && it.Type == EnumMenuType.Field |
| | | && it.Group == request.Group |
| | | && it.Code == request.Code |
| | | && it.Id != request.Id, |
| | | (entity) => |
| | | { |
| | | if (request.Id.HasValue) |
| | | { |
| | | var entity = await rep.FirstOrDefaultAsync(it => it.Id == request.Id); |
| | | if (entity == null) throw Oops.Oh(EnumErrorCodeType.s404, "该菜单"); |
| | | if (entity.ParentId != request.ParentId) throw Oops.Oh(EnumErrorCodeType.s410, "上级Id"); |
| | | request.Adapt(entity); |
| | | if (await CheckExist(entity)) throw Oops.Oh(EnumErrorCodeType.s406, "菜单编号"); |
| | | await rep.UpdateAsync(entity); |
| | | return entity.Id; |
| | | } |
| | | else |
| | | { |
| | | var entity = new Menu(); |
| | | entity.Path = $"{parent.Path}{parent.Code}/"; |
| | | entity.Type = EnumMenuType.Field; |
| | | entity.VisitLevel = parent.VisitLevel; |
| | | } |
| | | request.Adapt(entity); |
| | | if (await CheckExist(entity)) throw Oops.Oh(EnumErrorCodeType.s406, "菜单编号"); |
| | | await rep.InsertAsync(entity); |
| | | return entity.Id; |
| | | }, |
| | | cancellationToken); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 校验菜单是否重复 |
| | | /// </summary> |
| | | /// <param name="entity"></param> |
| | | /// <returns></returns> |
| | | private async Task<bool> CheckExist(Menu entity) |
| | | { |
| | | return await rep.AsQueryable().AsNoTracking() |
| | | .AnyAsync(it => |
| | | it.ParentId == entity.ParentId |
| | | && it.Type == entity.Type |
| | | && it.Group == entity.Group |
| | | && it.Code == entity.Code |
| | | && it.Id != entity.Id); |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | /// 设置角色是否禁用 |
| | | /// </summary> |
| | | [Resource([EnumResourceController.Role])] |
| | | public class SetRoleIsDisabledCommandHandler( |
| | | IRepository<Role> rep |
| | | ) : IRequestHandler<SetRoleIsDisabledCommand, int> |
| | | public class SetRoleIsDisabledCommandHandler() : IRequestHandler<SetRoleIsDisabledCommand, int> |
| | | { |
| | | private readonly IRepository<Role> rep = rep; |
| | | |
| | | /// <inheritdoc/> |
| | | public async Task<int> Handle(SetRoleIsDisabledCommand request, CancellationToken cancellationToken) |
| | | public Task<int> Handle(SetRoleIsDisabledCommand request, CancellationToken cancellationToken) |
| | | { |
| | | var entities = await rep.AsQueryable() |
| | | .Where(it => request.Ids.Contains(it.Id) && it.IsDisabled != request.IsDisabled) |
| | | .ToListAsync(); |
| | | foreach (var entity in entities) |
| | | { |
| | | entity.IsDisabled = request.IsDisabled; |
| | | } |
| | | return entities.Count; |
| | | return request.SetIsDisabled<Role>(cancellationToken: cancellationToken); |
| | | } |
| | | } |
| | | } |
| | |
| | | /// <inheritdoc/> |
| | | public async Task<PagedListQueryResult<GetRolesQueryResultItem>> Handle(GetRolesQuery request, CancellationToken cancellationToken) |
| | | { |
| | | var result = await request.PageModel.ToPagedListAsync<Role, GetRolesQueryResultItem>( |
| | | var result = await request.PageModel.GetPagedListAsync<Role, GetRolesQueryResultItem>( |
| | | q => |
| | | { |
| | | q = q.OrderBy(it => it.Sort).ThenBy(it => it.CreatedTime); |
| | |
| | | /// <inheritdoc/> |
| | | public async Task<PagedListQueryResult<GetOperationUserInfosQueryResultItem>> Handle(GetOperationUserInfosQuery request, CancellationToken cancellationToken) |
| | | { |
| | | var result = await request.PageModel.ToPagedListAsync<UserInfo, GetOperationUserInfosQueryResultItem>( |
| | | var result = await request.PageModel.GetPagedListAsync<UserInfo, GetOperationUserInfosQueryResultItem>( |
| | | q => |
| | | { |
| | | q = q.OrderByDescending(it => it.Level).ThenByDescending(it => it.CreatedTime) |