feat: add recovery center and daily reviews

This commit is contained in:
2026-04-26 11:03:08 +08:00
parent 94f6e08dea
commit 79047b5488
33 changed files with 3127 additions and 40 deletions
@@ -43,6 +43,9 @@ public sealed class SystemSettingsService : ISystemSettingsService
private const string SegmentCompletedScriptPathKey = "event_scripts.segment_completed.path";
private const string SegmentCompletedScriptContentKey = "event_scripts.segment_completed.content";
private const string EventScriptTimeoutSecondsKey = "event_scripts.timeout_seconds";
private const string EnableRetentionCleanupKey = "retention.cleanup.enabled";
private const string RetentionDaysKey = "retention.cleanup.days";
private const string RetentionDeleteFilesKey = "retention.cleanup.delete_files";
private const string EnableEmailNotificationKey = "notification.email.enabled";
private const string EmailSmtpHostKey = "notification.email.smtp_host";
private const string EmailSmtpPortKey = "notification.email.smtp_port";
@@ -58,6 +61,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
private const string EmailLiveStartedBodyTemplateHtmlKey = "notification.email.live_started.body_template_html";
private const string EmailExceptionSubjectTemplateKey = "notification.email.exception.subject_template";
private const string EmailExceptionBodyTemplateHtmlKey = "notification.email.exception.body_template_html";
private const string EnableWebhookNotificationKey = "notification.webhook.enabled";
private const string WebhookUrlKey = "notification.webhook.url";
private const string WebhookHeadersKey = "notification.webhook.headers";
private const string WebhookTimeoutSecondsKey = "notification.webhook.timeout_seconds";
private const string NotifyWebhookOnLiveStartedKey = "notification.webhook.notify_live_started";
private const string NotifyWebhookOnExceptionKey = "notification.webhook.notify_exception";
private const string DouyinUserAgentKey = "douyin.user_agent";
private const string DouyinRefererKey = "douyin.referer";
private const string DouyinCookieKey = "douyin.cookie";
@@ -119,6 +128,9 @@ public sealed class SystemSettingsService : ISystemSettingsService
SegmentCompletedScriptPath = GetValue(lookup, SegmentCompletedScriptPathKey, string.Empty),
SegmentCompletedScriptContent = GetValue(lookup, SegmentCompletedScriptContentKey, string.Empty),
EventScriptTimeoutSeconds = GetIntValue(lookup, EventScriptTimeoutSecondsKey, 60, 1, 3600),
EnableRetentionCleanup = bool.TryParse(GetValue(lookup, EnableRetentionCleanupKey, "false"), out var enableRetentionCleanup) && enableRetentionCleanup,
RetentionDays = GetIntValue(lookup, RetentionDaysKey, 30, 1, 3650),
RetentionDeleteFiles = bool.TryParse(GetValue(lookup, RetentionDeleteFilesKey, "false"), out var retentionDeleteFiles) && retentionDeleteFiles,
EnableEmailNotification = bool.TryParse(GetValue(lookup, EnableEmailNotificationKey, "false"), out var enableEmailNotification) && enableEmailNotification,
EmailSmtpHost = GetValue(lookup, EmailSmtpHostKey, string.Empty),
EmailSmtpPort = GetIntValue(lookup, EmailSmtpPortKey, 587, 1, 65535),
@@ -167,6 +179,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
<div style="margin-top: 16px; padding: 12px 14px; border-radius: 8px; background: #f5f5f5; white-space: pre-wrap;">{{detail}}</div>
</div>
"""),
EnableWebhookNotification = bool.TryParse(GetValue(lookup, EnableWebhookNotificationKey, "false"), out var enableWebhookNotification) && enableWebhookNotification,
WebhookUrl = GetValue(lookup, WebhookUrlKey, string.Empty),
WebhookHeaders = GetValue(lookup, WebhookHeadersKey, string.Empty),
WebhookTimeoutSeconds = GetIntValue(lookup, WebhookTimeoutSecondsKey, 15, 1, 300),
NotifyWebhookOnLiveStarted = bool.TryParse(GetValue(lookup, NotifyWebhookOnLiveStartedKey, "true"), out var notifyWebhookOnLiveStarted) && notifyWebhookOnLiveStarted,
NotifyWebhookOnException = bool.TryParse(GetValue(lookup, NotifyWebhookOnExceptionKey, "true"), out var notifyWebhookOnException) && notifyWebhookOnException,
DouyinUserAgent = GetValue(
lookup,
DouyinUserAgentKey,
@@ -233,6 +251,9 @@ public sealed class SystemSettingsService : ISystemSettingsService
await UpsertAsync(SegmentCompletedScriptPathKey, request.SegmentCompletedScriptPath.Trim(), now, cancellationToken);
await UpsertAsync(SegmentCompletedScriptContentKey, request.SegmentCompletedScriptContent, now, cancellationToken);
await UpsertAsync(EventScriptTimeoutSecondsKey, Math.Clamp(request.EventScriptTimeoutSeconds, 1, 3600).ToString(), now, cancellationToken);
await UpsertAsync(EnableRetentionCleanupKey, request.EnableRetentionCleanup.ToString(), now, cancellationToken);
await UpsertAsync(RetentionDaysKey, Math.Clamp(request.RetentionDays, 1, 3650).ToString(), now, cancellationToken);
await UpsertAsync(RetentionDeleteFilesKey, request.RetentionDeleteFiles.ToString(), now, cancellationToken);
await UpsertAsync(EnableEmailNotificationKey, request.EnableEmailNotification.ToString(), now, cancellationToken);
await UpsertAsync(EmailSmtpHostKey, request.EmailSmtpHost.Trim(), now, cancellationToken);
await UpsertAsync(EmailSmtpPortKey, request.EmailSmtpPort.ToString(), now, cancellationToken);
@@ -248,6 +269,12 @@ public sealed class SystemSettingsService : ISystemSettingsService
await UpsertAsync(EmailLiveStartedBodyTemplateHtmlKey, request.EmailLiveStartedBodyTemplateHtml.Trim(), now, cancellationToken);
await UpsertAsync(EmailExceptionSubjectTemplateKey, request.EmailExceptionSubjectTemplate.Trim(), now, cancellationToken);
await UpsertAsync(EmailExceptionBodyTemplateHtmlKey, request.EmailExceptionBodyTemplateHtml.Trim(), now, cancellationToken);
await UpsertAsync(EnableWebhookNotificationKey, request.EnableWebhookNotification.ToString(), now, cancellationToken);
await UpsertAsync(WebhookUrlKey, request.WebhookUrl.Trim(), now, cancellationToken);
await UpsertAsync(WebhookHeadersKey, request.WebhookHeaders, now, cancellationToken);
await UpsertAsync(WebhookTimeoutSecondsKey, Math.Clamp(request.WebhookTimeoutSeconds, 1, 300).ToString(), now, cancellationToken);
await UpsertAsync(NotifyWebhookOnLiveStartedKey, request.NotifyWebhookOnLiveStarted.ToString(), now, cancellationToken);
await UpsertAsync(NotifyWebhookOnExceptionKey, request.NotifyWebhookOnException.ToString(), now, cancellationToken);
await UpsertAsync(DouyinUserAgentKey, request.DouyinUserAgent.Trim(), now, cancellationToken);
await UpsertAsync(DouyinRefererKey, request.DouyinReferer.Trim(), now, cancellationToken);
await UpsertAsync(DouyinCookieKey, request.DouyinCookie.Trim(), now, cancellationToken);