插件系统初步

This commit is contained in:
biss committed 2026-10-01 08:24:32 +08:00
1 parent ae4447841a
commit 7e3f138875
17 files changed
+9921 -12

No files matched your search

@@ -0,0 +1,41 @@
using System.Security.Claims;
using Jiaowu.Api.Domain.Identity;
using Jiaowu.Api.Infrastructure.Plugins;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Jiaowu.Api.Controllers;
[ApiController]
[Authorize]
[Route("api/plugins")]
public sealed class PluginsController(PluginRuntimeService runtime) : ControllerBase
{
[HttpGet("runtime")]
public async Task<ActionResult<IReadOnlyList<PluginRuntimeItem>>> GetRuntime(
CancellationToken cancellationToken) =>
Ok(await runtime.GetAllAsync(cancellationToken));
[HttpGet]
[Authorize(Roles = SystemRoles.SuperAdmin)]
public async Task<ActionResult<IReadOnlyList<PluginRuntimeItem>>> GetAll(
CancellationToken cancellationToken) =>
Ok(await runtime.GetAllAsync(cancellationToken));
[HttpPut("{pluginId}/state")]
[Authorize(Roles = SystemRoles.SuperAdmin)]
public async Task<ActionResult<PluginRuntimeItem>> SetState(
string pluginId,
UpdatePluginStateRequest request,
CancellationToken cancellationToken)
{
var result = await runtime.SetEnabledAsync(
pluginId,
request.IsEnabled,
User.FindFirstValue(ClaimTypes.NameIdentifier),
cancellationToken);
return result is null ? NotFound() : Ok(result);
}
}
public sealed record UpdatePluginStateRequest(bool IsEnabled);
@@ -0,0 +1,11 @@
using Jiaowu.Api.Domain.Common;
namespace Jiaowu.Api.Domain.System;
public sealed class PluginInstallation : EntityBase
{
public required string PluginId { get; set; }
public required string InstalledVersion { get; set; }
public bool IsEnabled { get; set; } = true;
public string? ChangedByUserId { get; set; }
}
@@ -0,0 +1,26 @@
using Jiaowu.Api.Infrastructure.Plugins;
namespace Jiaowu.Api.Infrastructure.Middleware;
public sealed class PluginAvailabilityMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(
HttpContext context,
BuiltInPluginCatalog catalog,
PluginRuntimeService runtime)
{
var plugin = catalog.FindByApiPath(context.Request.Path);
if (plugin is not null &&
!await runtime.IsEnabledAsync(plugin.Id, context.RequestAborted))
{
await Results.Problem(
statusCode: StatusCodes.Status404NotFound,
title: "功能暂未开放",
detail: $"“{plugin.Name}”插件当前已停用。")
.ExecuteAsync(context);
return;
}
await next(context);
}
}
Loaded 3 of 17 files, more files were not shown because too many files have changed in this diff. Show more