feat: add form component registry CRUD endpoints
This commit is contained in:
parent
fa1f8dbef5
commit
d704c02d18
@ -0,0 +1,42 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using MediatR;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
|
||||||
|
namespace Workflow.Api.Endpoints.Form;
|
||||||
|
|
||||||
|
public class CreateFormComponentEndpoint : Endpoint<CreateFormComponentRequest, FormComponentDto>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public CreateFormComponentEndpoint(IMediator mediator) => _mediator = mediator;
|
||||||
|
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Post("/form-components");
|
||||||
|
AllowAnonymous();
|
||||||
|
Summary(s =>
|
||||||
|
{
|
||||||
|
s.Summary = "创建组件注册";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CreateFormComponentRequest req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var command = new CreateFormComponentCommand(
|
||||||
|
req.Name, req.DisplayName, req.Category, req.Icon,
|
||||||
|
req.DefaultSchema, req.SupportedProps);
|
||||||
|
var result = await _mediator.Send(command, ct);
|
||||||
|
await Send.ResponseAsync(result, 201, ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreateFormComponentRequest
|
||||||
|
{
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
public string Category { get; set; } = string.Empty;
|
||||||
|
public string Icon { get; set; } = string.Empty;
|
||||||
|
public string DefaultSchema { get; set; } = string.Empty;
|
||||||
|
public string SupportedProps { get; set; } = "{}";
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using MediatR;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
|
||||||
|
namespace Workflow.Api.Endpoints.Form;
|
||||||
|
|
||||||
|
public class DeleteFormComponentEndpoint : Endpoint<DeleteFormComponentRequest>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public DeleteFormComponentEndpoint(IMediator mediator) => _mediator = mediator;
|
||||||
|
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Delete("/form-components/{Id}");
|
||||||
|
AllowAnonymous();
|
||||||
|
Summary(s =>
|
||||||
|
{
|
||||||
|
s.Summary = "删除组件注册(软删除)";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(DeleteFormComponentRequest req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var command = new DeleteFormComponentCommand(req.Id);
|
||||||
|
await _mediator.Send(command, ct);
|
||||||
|
HttpContext.Response.StatusCode = 200;
|
||||||
|
HttpContext.Response.ContentType = "application/json";
|
||||||
|
await HttpContext.Response.WriteAsync("{}", ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DeleteFormComponentRequest
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using MediatR;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.Queries;
|
||||||
|
|
||||||
|
namespace Workflow.Api.Endpoints.Form;
|
||||||
|
|
||||||
|
public class GetFormComponentByIdEndpoint : Endpoint<GetFormComponentByIdRequest, FormComponentDto>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public GetFormComponentByIdEndpoint(IMediator mediator) => _mediator = mediator;
|
||||||
|
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/form-components/{Id}");
|
||||||
|
AllowAnonymous();
|
||||||
|
Summary(s =>
|
||||||
|
{
|
||||||
|
s.Summary = "根据ID获取组件注册详情";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(GetFormComponentByIdRequest req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var result = await _mediator.Send(new GetFormComponentByIdQuery(req.Id), ct);
|
||||||
|
await Send.OkAsync(result, ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GetFormComponentByIdRequest
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
}
|
||||||
31
src/Workflow.Api/Endpoints/Form/GetFormComponentsEndpoint.cs
Normal file
31
src/Workflow.Api/Endpoints/Form/GetFormComponentsEndpoint.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using MediatR;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.Queries;
|
||||||
|
|
||||||
|
namespace Workflow.Api.Endpoints.Form;
|
||||||
|
|
||||||
|
public class GetFormComponentsEndpoint : EndpointWithoutRequest<List<FormComponentDto>>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public GetFormComponentsEndpoint(IMediator mediator) => _mediator = mediator;
|
||||||
|
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Get("/form-components");
|
||||||
|
AllowAnonymous();
|
||||||
|
Summary(s =>
|
||||||
|
{
|
||||||
|
s.Summary = "获取组件注册列表";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(CancellationToken ct)
|
||||||
|
{
|
||||||
|
var category = Query<string?>("category", isRequired: false);
|
||||||
|
var isActive = Query<bool?>("isActive", isRequired: false);
|
||||||
|
var result = await _mediator.Send(new GetFormComponentsQuery(category, isActive), ct);
|
||||||
|
await Send.OkAsync(result, ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
using FastEndpoints;
|
||||||
|
using MediatR;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
|
||||||
|
namespace Workflow.Api.Endpoints.Form;
|
||||||
|
|
||||||
|
public class UpdateFormComponentEndpoint : Endpoint<UpdateFormComponentRequest, FormComponentDto>
|
||||||
|
{
|
||||||
|
private readonly IMediator _mediator;
|
||||||
|
|
||||||
|
public UpdateFormComponentEndpoint(IMediator mediator) => _mediator = mediator;
|
||||||
|
|
||||||
|
public override void Configure()
|
||||||
|
{
|
||||||
|
Put("/form-components/{Id}");
|
||||||
|
AllowAnonymous();
|
||||||
|
Summary(s =>
|
||||||
|
{
|
||||||
|
s.Summary = "更新组件注册";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task HandleAsync(UpdateFormComponentRequest req, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var command = new UpdateFormComponentCommand(
|
||||||
|
req.Id, req.DisplayName, req.Category, req.Icon,
|
||||||
|
req.DefaultSchema, req.SupportedProps, req.IsActive);
|
||||||
|
var result = await _mediator.Send(command, ct);
|
||||||
|
await Send.OkAsync(result, ct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UpdateFormComponentRequest
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
public string Category { get; set; } = string.Empty;
|
||||||
|
public string Icon { get; set; } = string.Empty;
|
||||||
|
public string DefaultSchema { get; set; } = string.Empty;
|
||||||
|
public string SupportedProps { get; set; } = "{}";
|
||||||
|
public bool IsActive { get; set; } = true;
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Domain.Exceptions;
|
||||||
|
using Workflow.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
namespace Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
|
||||||
|
public record CreateFormComponentCommand(
|
||||||
|
string Name,
|
||||||
|
string DisplayName,
|
||||||
|
string Category,
|
||||||
|
string Icon,
|
||||||
|
string DefaultSchema,
|
||||||
|
string SupportedProps
|
||||||
|
) : IRequest<FormComponentDto>;
|
||||||
|
|
||||||
|
public class CreateFormComponentCommandHandler(WorkflowDbContext db)
|
||||||
|
: IRequestHandler<CreateFormComponentCommand, FormComponentDto>
|
||||||
|
{
|
||||||
|
public async Task<FormComponentDto> Handle(CreateFormComponentCommand request, CancellationToken ct)
|
||||||
|
{
|
||||||
|
if (await db.FormComponentRegistries.AnyAsync(c => c.Name == request.Name, ct))
|
||||||
|
throw new BusinessException($"组件 {request.Name} 已存在");
|
||||||
|
|
||||||
|
var entity = new Domain.Entities.FormComponentRegistry
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid(),
|
||||||
|
Name = request.Name,
|
||||||
|
DisplayName = request.DisplayName,
|
||||||
|
Category = request.Category,
|
||||||
|
Icon = request.Icon,
|
||||||
|
DefaultSchema = request.DefaultSchema,
|
||||||
|
SupportedProps = request.SupportedProps,
|
||||||
|
SortOrder = 100,
|
||||||
|
};
|
||||||
|
|
||||||
|
db.FormComponentRegistries.Add(entity);
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
return MapToDto(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FormComponentDto MapToDto(Domain.Entities.FormComponentRegistry e) => new()
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
Name = e.Name,
|
||||||
|
DisplayName = e.DisplayName,
|
||||||
|
Category = e.Category,
|
||||||
|
Icon = e.Icon,
|
||||||
|
DefaultSchema = e.DefaultSchema,
|
||||||
|
SupportedProps = e.SupportedProps,
|
||||||
|
IsActive = e.IsActive,
|
||||||
|
SortOrder = e.SortOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Workflow.Domain.Exceptions;
|
||||||
|
using Workflow.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
namespace Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
|
||||||
|
public record DeleteFormComponentCommand(Guid Id) : IRequest<Unit>;
|
||||||
|
|
||||||
|
public class DeleteFormComponentCommandHandler(WorkflowDbContext db)
|
||||||
|
: IRequestHandler<DeleteFormComponentCommand, Unit>
|
||||||
|
{
|
||||||
|
public async Task<Unit> Handle(DeleteFormComponentCommand request, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var entity = await db.FormComponentRegistries.FindAsync([request.Id], ct)
|
||||||
|
?? throw new NotFoundException("组件不存在");
|
||||||
|
|
||||||
|
entity.IsDeleted = true;
|
||||||
|
entity.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
return Unit.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Domain.Exceptions;
|
||||||
|
using Workflow.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
namespace Workflow.Application.Form.ComponentRegistry.Commands;
|
||||||
|
|
||||||
|
public record UpdateFormComponentCommand(
|
||||||
|
Guid Id,
|
||||||
|
string DisplayName,
|
||||||
|
string Category,
|
||||||
|
string Icon,
|
||||||
|
string DefaultSchema,
|
||||||
|
string SupportedProps,
|
||||||
|
bool IsActive
|
||||||
|
) : IRequest<FormComponentDto>;
|
||||||
|
|
||||||
|
public class UpdateFormComponentCommandHandler(WorkflowDbContext db)
|
||||||
|
: IRequestHandler<UpdateFormComponentCommand, FormComponentDto>
|
||||||
|
{
|
||||||
|
public async Task<FormComponentDto> Handle(UpdateFormComponentCommand request, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var entity = await db.FormComponentRegistries.FindAsync([request.Id], ct)
|
||||||
|
?? throw new NotFoundException("组件不存在");
|
||||||
|
|
||||||
|
entity.DisplayName = request.DisplayName;
|
||||||
|
entity.Category = request.Category;
|
||||||
|
entity.Icon = request.Icon;
|
||||||
|
entity.DefaultSchema = request.DefaultSchema;
|
||||||
|
entity.SupportedProps = request.SupportedProps;
|
||||||
|
entity.IsActive = request.IsActive;
|
||||||
|
entity.UpdatedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await db.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
return MapToDto(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FormComponentDto MapToDto(Domain.Entities.FormComponentRegistry e) => new()
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
Name = e.Name,
|
||||||
|
DisplayName = e.DisplayName,
|
||||||
|
Category = e.Category,
|
||||||
|
Icon = e.Icon,
|
||||||
|
DefaultSchema = e.DefaultSchema,
|
||||||
|
SupportedProps = e.SupportedProps,
|
||||||
|
IsActive = e.IsActive,
|
||||||
|
SortOrder = e.SortOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
namespace Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
|
||||||
|
public class FormComponentDto
|
||||||
|
{
|
||||||
|
public Guid Id { get; set; }
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
public string DisplayName { get; set; } = string.Empty;
|
||||||
|
public string Category { get; set; } = string.Empty;
|
||||||
|
public string Icon { get; set; } = string.Empty;
|
||||||
|
public string DefaultSchema { get; set; } = string.Empty;
|
||||||
|
public string SupportedProps { get; set; } = "{}";
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
public int SortOrder { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Domain.Exceptions;
|
||||||
|
using Workflow.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
namespace Workflow.Application.Form.ComponentRegistry.Queries;
|
||||||
|
|
||||||
|
public record GetFormComponentByIdQuery(Guid Id) : IRequest<FormComponentDto>;
|
||||||
|
|
||||||
|
public class GetFormComponentByIdQueryHandler(WorkflowDbContext db)
|
||||||
|
: IRequestHandler<GetFormComponentByIdQuery, FormComponentDto>
|
||||||
|
{
|
||||||
|
public async Task<FormComponentDto> Handle(GetFormComponentByIdQuery request, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var entity = await db.FormComponentRegistries
|
||||||
|
.AsNoTracking()
|
||||||
|
.FirstOrDefaultAsync(c => c.Id == request.Id, ct)
|
||||||
|
?? throw new NotFoundException("组件不存在");
|
||||||
|
|
||||||
|
return MapToDto(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FormComponentDto MapToDto(Domain.Entities.FormComponentRegistry e) => new()
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
Name = e.Name,
|
||||||
|
DisplayName = e.DisplayName,
|
||||||
|
Category = e.Category,
|
||||||
|
Icon = e.Icon,
|
||||||
|
DefaultSchema = e.DefaultSchema,
|
||||||
|
SupportedProps = e.SupportedProps,
|
||||||
|
IsActive = e.IsActive,
|
||||||
|
SortOrder = e.SortOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
using MediatR;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Workflow.Application.Form.ComponentRegistry.DTOs;
|
||||||
|
using Workflow.Infrastructure.Persistence;
|
||||||
|
|
||||||
|
namespace Workflow.Application.Form.ComponentRegistry.Queries;
|
||||||
|
|
||||||
|
public record GetFormComponentsQuery(
|
||||||
|
string? Category,
|
||||||
|
bool? IsActive
|
||||||
|
) : IRequest<List<FormComponentDto>>;
|
||||||
|
|
||||||
|
public class GetFormComponentsQueryHandler(WorkflowDbContext db)
|
||||||
|
: IRequestHandler<GetFormComponentsQuery, List<FormComponentDto>>
|
||||||
|
{
|
||||||
|
public async Task<List<FormComponentDto>> Handle(GetFormComponentsQuery request, CancellationToken ct)
|
||||||
|
{
|
||||||
|
var query = db.FormComponentRegistries.AsNoTracking();
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(request.Category))
|
||||||
|
query = query.Where(c => c.Category == request.Category);
|
||||||
|
|
||||||
|
if (request.IsActive.HasValue)
|
||||||
|
query = query.Where(c => c.IsActive == request.IsActive.Value);
|
||||||
|
|
||||||
|
var entities = await query
|
||||||
|
.OrderBy(c => c.SortOrder)
|
||||||
|
.ToListAsync(ct);
|
||||||
|
|
||||||
|
return entities.Select(MapToDto).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static FormComponentDto MapToDto(Domain.Entities.FormComponentRegistry e) => new()
|
||||||
|
{
|
||||||
|
Id = e.Id,
|
||||||
|
Name = e.Name,
|
||||||
|
DisplayName = e.DisplayName,
|
||||||
|
Category = e.Category,
|
||||||
|
Icon = e.Icon,
|
||||||
|
DefaultSchema = e.DefaultSchema,
|
||||||
|
SupportedProps = e.SupportedProps,
|
||||||
|
IsActive = e.IsActive,
|
||||||
|
SortOrder = e.SortOrder,
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user