fix.还是在修智教Hub组件

This commit is contained in:
lincube
2026-04-03 22:07:38 +08:00
parent 675096b6c4
commit 021c7ff245
3 changed files with 78 additions and 24 deletions

View File

@@ -135,6 +135,55 @@ public static class ZhiJiaoHubSources
_ => ClassIsland
};
}
public static string GetDisplayName(string source)
{
return source?.ToLowerInvariant() switch
{
Sectl => "SECTL 图库",
RinLit => "Rin's 图库",
_ => "ClassIsland 图库"
};
}
}
// 智教Hub数据源配置
public sealed class ZhiJiaoHubSourceConfig
{
public string Owner { get; init; } = string.Empty;
public string Repo { get; init; } = string.Empty;
public string Path { get; init; } = string.Empty;
public string DisplayName { get; init; } = string.Empty;
public string ApiUrl => $"https://api.github.com/repos/{Owner}/{Repo}/contents/{Path}";
public string RawUrlTemplate => $"https://raw.githubusercontent.com/{Owner}/{Repo}/main/{Path}/{{0}}";
public static ZhiJiaoHubSourceConfig GetConfig(string source)
{
return source?.ToLowerInvariant() switch
{
ZhiJiaoHubSources.Sectl => new ZhiJiaoHubSourceConfig
{
Owner = "SECTL",
Repo = "SECTL-hub",
Path = "docs/.vuepress/public/images",
DisplayName = "SECTL 图库"
},
ZhiJiaoHubSources.RinLit => new ZhiJiaoHubSourceConfig
{
Owner = "RinLit-233-shiroko",
Repo = "Rin-sHub",
Path = "assets/images",
DisplayName = "Rin's 图库"
},
_ => new ZhiJiaoHubSourceConfig
{
Owner = "ClassIsland",
Repo = "classisland-hub",
Path = "images",
DisplayName = "ClassIsland 图库"
}
};
}
}
// 智教Hub镜像加速源常量

View File

@@ -319,6 +319,8 @@ public sealed record RecommendationApiOptions
public string SectlHubApiUrl { get; init; } = "https://api.github.com/repos/SECTL/SECTL-hub/contents/docs/.vuepress/public/images";
public string RinLitHubApiUrl { get; init; } = "https://api.github.com/repos/RinLit-233-shiroko/Rin-sHub/contents/images";
public string ClassIslandHubRawUrlTemplate { get; init; } = "https://raw.githubusercontent.com/ClassIsland/classisland-hub/main/images/{0}";
public string SectlHubRawUrlTemplate { get; init; } = "https://raw.githubusercontent.com/SECTL/SECTL-hub/main/docs/.vuepress/public/images/{0}";

View File

@@ -3244,16 +3244,10 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
private async Task<ZhiJiaoHubSnapshot> FetchZhiJiaoHubSnapshotAsync(string source, string mirrorSource, CancellationToken cancellationToken)
{
var (owner, repo, path, rawUrlTemplate) = source switch
{
ZhiJiaoHubSources.Sectl =&gt; ("SECTL", "SECTL-hub", "docs/.vuepress/public/images", _options.SectlHubRawUrlTemplate),
ZhiJiaoHubSources.RinLit =&gt; ("RinLit-233-shiroko", "Rin-sHub", "images", _options.RinLitHubRawUrlTemplate),
_ =&gt; ("ClassIsland", "classisland-hub", "images", _options.ClassIslandHubRawUrlTemplate)
};
var config = ZhiJiaoHubSourceConfig.GetConfig(source);
var contentsUrl = $"https://api.github.com/repos/{owner}/{repo}/contents/{path}";
var contentsUrl = config.ApiUrl;
// 如果使用镜像加速,代理 GitHub API 请求
if (string.Equals(mirrorSource, ZhiJiaoHubMirrorSources.GhProxy, StringComparison.OrdinalIgnoreCase))
{
contentsUrl = ZhiJiaoHubMirrorSources.GhProxyBaseUrl.TrimEnd('/') + "/" + contentsUrl;
@@ -3261,18 +3255,16 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
try
{
var images = await FetchImagesFromContentsApi(owner, repo, path, rawUrlTemplate, contentsUrl, mirrorSource, cancellationToken);
var images = await FetchImagesFromContentsApi(config, contentsUrl, mirrorSource, cancellationToken);
if (images.Count == 0)
{
throw new InvalidOperationException("未找到图片文件");
throw new InvalidOperationException($"在 {config.DisplayName} 中未找到图片文件");
}
// 随机打乱图片顺序
var random = new Random();
var shuffled = images.OrderBy(_ => random.Next()).ToList();
// 重新设置索引
for (int i = 0; i < shuffled.Count; i++)
{
var item = shuffled[i];
@@ -3287,11 +3279,15 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
}
catch (Exception ex)
{
throw new HttpRequestException($"获取图片列表失败: {ex.Message}");
throw new HttpRequestException($"从 {config.DisplayName} 获取图片列表失败: {ex.Message}");
}
}
private async Task<List<ZhiJiaoHubImageItem>> FetchImagesFromContentsApi(string owner, string repo, string path, string rawUrlTemplate, string contentsUrl, string mirrorSource, CancellationToken cancellationToken)
private async Task<List<ZhiJiaoHubImageItem>> FetchImagesFromContentsApi(
ZhiJiaoHubSourceConfig config,
string contentsUrl,
string mirrorSource,
CancellationToken cancellationToken)
{
var images = new List<ZhiJiaoHubImageItem>();
@@ -3309,7 +3305,17 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
{
throw new HttpRequestException("GitHub API 速率限制,请稍后重试");
}
throw new HttpRequestException($"API 返回错误: {(int)response.StatusCode} - {Truncate(errorText, 200)}");
if ((int)response.StatusCode == 404)
{
throw new HttpRequestException(
$"在 {config.DisplayName} 中找不到图片目录。请检查仓库结构和路径配置。\n" +
$"仓库: {config.Owner}/{config.Repo}\n" +
$"路径: {config.Path}");
}
throw new HttpRequestException(
$"从 {config.DisplayName} 获取数据失败: {(int)response.StatusCode} - {Truncate(errorText, 200)}");
}
var responseText = await response.Content.ReadAsStringAsync(cancellationToken);
@@ -3321,9 +3327,9 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
if (root.ValueKind == JsonValueKind.Object && root.TryGetProperty("message", out var messageNode))
{
var errorMessage = messageNode.GetString();
throw new InvalidOperationException($"GitHub API 错误: {errorMessage}");
throw new InvalidOperationException($"GitHub API 错误 ({config.DisplayName}): {errorMessage}");
}
throw new InvalidOperationException("Invalid response format from GitHub API.");
throw new InvalidOperationException($"从 {config.DisplayName} 返回的数据格式无效");
}
int index = 0;
@@ -3343,18 +3349,15 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
continue;
}
// 只处理图片文件
var extension = Path.GetExtension(name).ToLowerInvariant();
if (extension != ".png" && extension != ".jpg" && extension != ".jpeg" && extension != ".gif" && extension != ".webp")
{
continue;
}
// 解码文件名
var decodedName = Uri.UnescapeDataString(name);
decodedName = Path.GetFileNameWithoutExtension(decodedName);
// 构造图片 URL
string imageUrl;
if (!string.IsNullOrWhiteSpace(downloadUrl))
{
@@ -3362,12 +3365,12 @@ public sealed class RecommendationDataService : IRecommendationInfoService, IDis
}
else
{
// 使用为每个数据源专门配置的 raw URL 模板
// 注意:模板已经包含了正确的路径,只需要传入文件名
imageUrl = string.Format(rawUrlTemplate, Uri.EscapeDataString(name));
imageUrl = string.Format(
CultureInfo.InvariantCulture,
config.RawUrlTemplate,
Uri.EscapeDataString(name));
}
// 应用镜像加速到图片 URL
imageUrl = ZhiJiaoHubMirrorSources.ApplyMirror(imageUrl, mirrorSource);
images.Add(new ZhiJiaoHubImageItem(decodedName, imageUrl, index));