主要成果:
- 新增独立插件 SDK:[PluginContracts.cs (line 11)](E:/jiaowu/src/Jiaowu.Plugin.Abstractions/PluginContracts.cs:11)
- 支持 RSA-PSS/SHA-256 签名插件包、Host API 兼容性和 ZIP 安全检查:[PluginPackageValidator.cs (line 14)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Plugins/PluginPackageValidator.cs:14)
- 支持暂存、待激活、重启装载、失败记录、版本回滚:[PluginPackageService.cs (line 32)](E:/jiaowu/src/Jiaowu.Api/Infrastructure/Plugins/PluginPackageService.cs:32)
- 插件可注册控制器、服务、数据库迁移、后台任务和事件处理器
- 外部插件 API 统一使用 /api/plugin-extensions/{pluginId},并受启用状态中间件控制
- 插件中心新增 ZIP/SIG 上传、状态展示、激活、回滚和删除功能:[PluginsView.vue (line 212)](E:/jiaowu/web/src/views/PluginsView.vue:212)
- 提供可运行示例插件:[SamplePlugin.cs (line 10)](E:/jiaowu/samples/Jiaowu.SamplePlugin/SamplePlugin.cs:10)
- 提供打包签名脚本:[package-plugin.ps1](E:/jiaowu/scripts/package-plugin.ps1)
- 完整开发文档:[plugin-sdk.md (line 1)](E:/jiaowu/docs/plugin-sdk.md:1)
- 系统版本已调整为 3.0.0-beta1
61 lines
2.0 KiB
C#
61 lines
2.0 KiB
C#
using Jiaowu.Plugin.Abstractions;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace Jiaowu.SamplePlugin;
|
|
|
|
public sealed class SamplePluginModule : IJiaowuPluginModule
|
|
{
|
|
public void ConfigureServices(
|
|
IServiceCollection services,
|
|
IConfiguration configuration)
|
|
{
|
|
services.AddSingleton<SampleGreetingService>();
|
|
}
|
|
}
|
|
|
|
public sealed class SampleGreetingService
|
|
{
|
|
public string BuildGreeting() => "签名示例插件已由宿主成功装载。";
|
|
}
|
|
|
|
[ApiController]
|
|
[Authorize(Roles = "SuperAdmin")]
|
|
[Route("api/plugin-extensions/sample.hello")]
|
|
public sealed class SamplePluginController(SampleGreetingService greetings)
|
|
: ControllerBase
|
|
{
|
|
[HttpGet("greeting")]
|
|
public IActionResult GetGreeting() => Ok(new { message = greetings.BuildGreeting() });
|
|
}
|
|
|
|
public sealed class SamplePluginMigration : IPluginDatabaseMigration
|
|
{
|
|
public string PluginId => "sample.hello";
|
|
public string MigrationId => "001_initial";
|
|
|
|
public IReadOnlyList<string> GetStatements(PluginDatabaseProvider provider) =>
|
|
provider == PluginDatabaseProvider.Sqlite
|
|
? ["CREATE TABLE IF NOT EXISTS SamplePluginNotes (Id TEXT NOT NULL PRIMARY KEY, Content TEXT NOT NULL);"]
|
|
: ["CREATE TABLE IF NOT EXISTS `SamplePluginNotes` (`Id` char(36) NOT NULL, `Content` varchar(500) NOT NULL, PRIMARY KEY (`Id`)) CHARACTER SET utf8mb4;"];
|
|
}
|
|
|
|
public sealed class SamplePluginBackgroundTask(
|
|
ILogger<SamplePluginBackgroundTask> logger) : IPluginBackgroundTask
|
|
{
|
|
public string PluginId => "sample.hello";
|
|
public string Name => "sample-heartbeat";
|
|
public TimeSpan Interval => TimeSpan.FromHours(1);
|
|
|
|
public Task ExecuteAsync(
|
|
IServiceProvider services,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
logger.LogInformation("示例插件后台任务正常运行。");
|
|
return Task.CompletedTask;
|
|
}
|
|
}
|