fix: 云端保存API配置写入/data并避免文件不存在

This commit is contained in:
meoacgx committed 2025-12-20 03:55:09 +08:00
1 parent 202130d153
commit 5753d22e50
3 files changed
+66 -10

No files matched your search

@@ -10,6 +10,7 @@
@inject ISnackbar Snackbar
@inject IDialogService DialogService
@inject IWebHostEnvironment Environment
@using TelegramPanel.Web.Services
<PageTitle>系统设置 - Telegram Panel</PageTitle>
@@ -150,7 +151,7 @@
private int logRetentionDays = 30;
private bool syncing = false;
private string LocalConfigPath => System.IO.Path.Combine(Environment.ContentRootPath, "appsettings.local.json");
private string LocalConfigPath => LocalConfigFile.ResolvePath(Configuration, Environment);
private bool LocalConfigExists => System.IO.File.Exists(LocalConfigPath);
protected override void OnInitialized()
@@ -188,8 +189,18 @@
// 配置变更后清理客户端缓存,确保后续操作使用新 ApiId/ApiHash
await TelegramClientPool.RemoveAllClientsAsync();
var fileInfo = new System.IO.FileInfo(localConfigPath);
Snackbar.Add($"API 配置已保存:{localConfigPath}({fileInfo.Length} bytes)。已清理 Telegram 客户端缓存,后续操作将使用新配置。", Severity.Success);
string sizeHint;
try
{
var fileInfo = new System.IO.FileInfo(localConfigPath);
sizeHint = $"({fileInfo.Length} bytes)";
}
catch
{
sizeHint = "";
}
Snackbar.Add($"API 配置已保存:{localConfigPath}{sizeHint}。已清理 Telegram 客户端缓存,后续操作将使用新配置。", Severity.Success);
StateHasChanged();
}
catch (Exception ex)
@@ -240,11 +251,9 @@
private async Task SaveLocalConfigAsync(System.Text.Json.Nodes.JsonObject root)
{
var json = root.ToJsonString(new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
await System.IO.File.WriteAllTextAsync(
LocalConfigPath,
json,
new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false)
);
var path = LocalConfigPath;
await LocalConfigFile.EnsureExistsAsync(path);
await LocalConfigFile.WriteJsonAtomicallyAsync(path, json);
}
private static System.Text.Json.Nodes.JsonObject EnsureObject(System.Text.Json.Nodes.JsonObject root, string key)
+3 -2
View File
@@ -18,7 +18,7 @@ var builder = WebApplication.CreateBuilder(args);
// 直接加载会抛 FileNotFoundException 导致容器不断重启,因此这里先确保文件存在一个空 JSON。
try
{
var localOverridePath = Path.Combine(builder.Environment.ContentRootPath, "appsettings.local.json");
var localOverridePath = LocalConfigFile.ResolvePath(builder.Configuration, builder.Environment);
if (!File.Exists(localOverridePath))
File.WriteAllText(localOverridePath, "{}", new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
}
@@ -31,7 +31,8 @@ try
{
// 注意:如果该路径是“悬空符号链接”,配置系统可能会认为文件存在并尝试打开,从而抛 FileNotFoundException。
// 本地覆盖配置不应该阻塞启动,因此这里兜底吞掉 FileNotFoundException。
builder.Configuration.AddJsonFile("appsettings.local.json", optional: true, reloadOnChange: true);
var localOverridePath = LocalConfigFile.ResolvePath(builder.Configuration, builder.Environment);
builder.Configuration.AddJsonFile(localOverridePath, optional: true, reloadOnChange: true);
}
catch (FileNotFoundException ex)
{
@@ -0,0 +1,46 @@
using System.Text;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
namespace TelegramPanel.Web.Services;
public static class LocalConfigFile
{
public static string ResolvePath(IConfiguration configuration, IWebHostEnvironment environment)
{
var configured = (configuration["LocalConfig:Path"] ?? "").Trim();
if (!string.IsNullOrWhiteSpace(configured))
return configured;
// Docker 部署默认持久化目录为 /data(docker-compose 挂载 ./docker-data:/data)
// 即便没有显式配置,也优先写到 /data,避免写入镜像层 /app 导致丢失或权限问题。
if (Directory.Exists("/data"))
return "/data/appsettings.local.json";
return Path.Combine(environment.ContentRootPath, "appsettings.local.json");
}
public static async Task EnsureExistsAsync(string path, CancellationToken cancellationToken = default)
{
var dir = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(dir))
Directory.CreateDirectory(dir);
if (File.Exists(path))
return;
await File.WriteAllTextAsync(path, "{}", new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), cancellationToken);
}
public static async Task WriteJsonAtomicallyAsync(string path, string json, CancellationToken cancellationToken = default)
{
var dir = Path.GetDirectoryName(path);
if (!string.IsNullOrWhiteSpace(dir))
Directory.CreateDirectory(dir);
var tmp = $"{path}.tmp";
await File.WriteAllTextAsync(tmp, json, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), cancellationToken);
File.Move(tmp, path, overwrite: true);
}
}