新增 POST /api/admin/notices、PATCH /api/admin/notices/{id}

保留超级管理员权限边界
支持草稿、发布、置顶、自动摘要
HTML 净化,拦截脚本和危险链接
公告更新与审计日志同事务提交
新增开关 ADMIN_NATIVE_NOTICE_WRITES_ENABLED=false
管理端公告列表和系统自动公告暂时仍由 Node 处理
This commit is contained in:
2026-07-23 08:41:53 +08:00 Unverified
parent 3665aa3aa9
commit 9e21a277f0
14 changed files with 350 additions and 21 deletions
@@ -4,7 +4,8 @@ public sealed record AdminMigrationOptions(
bool NativeReadsEnabled,
bool NativeOrganizationWritesEnabled = false,
bool NativeAccountBatchesEnabled = false,
bool NativeConfigurationEnabled = false)
bool NativeConfigurationEnabled = false,
bool NativeNoticeWritesEnabled = false)
{
public static AdminMigrationOptions FromEnvironment(
bool configuredNativeReadsEnabled,
@@ -12,7 +13,8 @@ public sealed record AdminMigrationOptions(
bool sharesLegacySessions,
bool configuredNativeOrganizationWritesEnabled = false,
bool configuredNativeAccountBatchesEnabled = false,
bool configuredNativeConfigurationEnabled = false)
bool configuredNativeConfigurationEnabled = false,
bool configuredNativeNoticeWritesEnabled = false)
{
var readsEnabled = ParseBoolean(
Environment.GetEnvironmentVariable("ADMIN_NATIVE_READS_ENABLED"),
@@ -26,12 +28,15 @@ public sealed record AdminMigrationOptions(
var configurationEnabled = ParseBoolean(
Environment.GetEnvironmentVariable("ADMIN_NATIVE_CONFIGURATION_ENABLED"),
configuredNativeConfigurationEnabled);
if ((organizationWritesEnabled || accountBatchesEnabled || configurationEnabled) && !readsEnabled)
var noticeWritesEnabled = ParseBoolean(
Environment.GetEnvironmentVariable("ADMIN_NATIVE_NOTICE_WRITES_ENABLED"),
configuredNativeNoticeWritesEnabled);
if ((organizationWritesEnabled || accountBatchesEnabled || configurationEnabled || noticeWritesEnabled) && !readsEnabled)
{
throw new InvalidOperationException(
"启用原生组织维护接口前必须同时设置 ADMIN_NATIVE_READS_ENABLED=true");
}
var anyNativeAdminEndpointEnabled = readsEnabled || organizationWritesEnabled || accountBatchesEnabled || configurationEnabled;
var anyNativeAdminEndpointEnabled = readsEnabled || organizationWritesEnabled || accountBatchesEnabled || configurationEnabled || noticeWritesEnabled;
if (anyNativeAdminEndpointEnabled && !authenticationNativeEnabled)
{
throw new InvalidOperationException(
@@ -47,7 +52,7 @@ public sealed record AdminMigrationOptions(
"管理端仍有接口需要转发给 Node;启用原生管理端接口必须配置共享 Redis 会话");
}
return new AdminMigrationOptions(readsEnabled, organizationWritesEnabled, accountBatchesEnabled, configurationEnabled);
return new AdminMigrationOptions(readsEnabled, organizationWritesEnabled, accountBatchesEnabled, configurationEnabled, noticeWritesEnabled);
}
private static bool ParseBoolean(string? value, bool fallback) => value?.Trim().ToLowerInvariant() switch