mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-09-05 07:36:53 +08:00
refactor: 统一命名空间为Foxel.Api,移除不必要的using语句,优化代码结构
This commit is contained in:
@@ -1,11 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Request.Album;
|
using Foxel.Models.Request.Album;
|
||||||
using Foxel.Models.Response.Album;
|
using Foxel.Models.Response.Album;
|
||||||
using Foxel.Services.Media;
|
using Foxel.Services.Media;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers;
|
namespace Foxel.Api;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/album")]
|
[Route("api/album")]
|
||||||
|
|||||||
+15
-15
@@ -1,12 +1,12 @@
|
|||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models.Request.Auth;
|
using Foxel.Models.Request.Auth;
|
||||||
using Foxel.Models.Response.Auth;
|
using Foxel.Models.Response.Auth;
|
||||||
using Foxel.Services.Auth;
|
using Foxel.Services.Auth;
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers;
|
namespace Foxel.Api;
|
||||||
|
|
||||||
[Route("api/auth")]
|
[Route("api/auth")]
|
||||||
public class AuthController(IAuthService authService, IConfigService configuration) : BaseApiController
|
public class AuthController(IAuthService authService, IConfigService configuration) : BaseApiController
|
||||||
@@ -119,15 +119,15 @@ public class AuthController(IAuthService authService, IConfigService configurati
|
|||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case GitHubAuthResult.Success:
|
case OAuthResult.Success:
|
||||||
return Redirect($"/login?token={Uri.EscapeDataString(data!)}");
|
return Redirect($"/login?token={Uri.EscapeDataString(data!)}");
|
||||||
|
|
||||||
case GitHubAuthResult.UserNotBound:
|
case OAuthResult.UserNotBound:
|
||||||
return Redirect($"/bind?githubId={data}");
|
return Redirect($"/bind?githubId={data}");
|
||||||
case GitHubAuthResult.InvalidCode:
|
case OAuthResult.InvalidCode:
|
||||||
case GitHubAuthResult.TokenRequestFailed:
|
case OAuthResult.TokenRequestFailed:
|
||||||
case GitHubAuthResult.UserInfoFailed:
|
case OAuthResult.UserInfoFailed:
|
||||||
case GitHubAuthResult.InvalidUserId:
|
case OAuthResult.InvalidUserId:
|
||||||
default:
|
default:
|
||||||
return Redirect($"/login?error=github_auth_failed&message={Uri.EscapeDataString(message)}");
|
return Redirect($"/login?error=github_auth_failed&message={Uri.EscapeDataString(message)}");
|
||||||
}
|
}
|
||||||
@@ -147,15 +147,15 @@ public class AuthController(IAuthService authService, IConfigService configurati
|
|||||||
|
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case LinuxDoAuthResult.Success:
|
case OAuthResult.Success:
|
||||||
return Redirect($"/login?token={Uri.EscapeDataString(data!)}");
|
return Redirect($"/login?token={Uri.EscapeDataString(data!)}");
|
||||||
|
|
||||||
case LinuxDoAuthResult.UserNotBound:
|
case OAuthResult.UserNotBound:
|
||||||
return Redirect($"/bind?linuxdoId={data}");
|
return Redirect($"/bind?linuxdoId={data}");
|
||||||
case LinuxDoAuthResult.InvalidCode:
|
case OAuthResult.InvalidCode:
|
||||||
case LinuxDoAuthResult.TokenRequestFailed:
|
case OAuthResult.TokenRequestFailed:
|
||||||
case LinuxDoAuthResult.UserInfoFailed:
|
case OAuthResult.UserInfoFailed:
|
||||||
case LinuxDoAuthResult.InvalidUserId:
|
case OAuthResult.InvalidUserId:
|
||||||
default:
|
default:
|
||||||
return Redirect($"/login?error=linuxdo_auth_failed&message={Uri.EscapeDataString(message)}");
|
return Redirect($"/login?error=linuxdo_auth_failed&message={Uri.EscapeDataString(message)}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Services.Background;
|
using Foxel.Services.Background;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers;
|
namespace Foxel.Api;
|
||||||
|
|
||||||
[Authorize]
|
[Authorize]
|
||||||
[Route("api/background-tasks")]
|
[Route("api/background-tasks")]
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models;
|
|
||||||
using System.Security.Claims;
|
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using Foxel.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers
|
namespace Foxel.Api
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
[Route("api/[controller]")]
|
[Route("api/[controller]")]
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Models.Request.Config;
|
using Foxel.Models.Request.Config;
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers;
|
namespace Foxel.Api;
|
||||||
|
|
||||||
[Authorize(Roles = "Administrator")]
|
[Authorize(Roles = "Administrator")]
|
||||||
[Route("api/config")]
|
[Route("api/config")]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Response.Face;
|
using Foxel.Models.Response.Face;
|
||||||
using Foxel.Models.Response.Picture;
|
using Foxel.Models.Response.Picture;
|
||||||
|
using Foxel.Services.AI;
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Request.Album;
|
using Foxel.Models.Request.Album;
|
||||||
using Foxel.Models.Response.Album;
|
using Foxel.Models.Response.Album;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Response.Face;
|
using Foxel.Models.Response.Face;
|
||||||
using Foxel.Models.Response.Picture;
|
using Foxel.Models.Response.Picture;
|
||||||
|
using Foxel.Services.AI;
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Response.Log;
|
using Foxel.Models.Response.Log;
|
||||||
using Foxel.Models.Request.Log;
|
using Foxel.Models.Request.Log;
|
||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
|
|
||||||
namespace Foxel.Api.Management;
|
namespace Foxel.Api.Management;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Response.Picture;
|
using Foxel.Models.Response.Picture;
|
||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
|
|
||||||
namespace Foxel.Api.Management;
|
namespace Foxel.Api.Management;
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Request.Storage;
|
using Foxel.Models.Request.Storage;
|
||||||
using Foxel.Models.Response.Storage;
|
using Foxel.Models.Response.Storage;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
|
using Foxel.Services.Storage;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Services.VectorDB;
|
using Foxel.Services.VectorDb;
|
||||||
|
|
||||||
namespace Foxel.Api.Management;
|
namespace Foxel.Api.Management;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Request.User;
|
using Foxel.Models.Request.User;
|
||||||
using Foxel.Models.Response.User;
|
using Foxel.Models.Response.User;
|
||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
|
|
||||||
namespace Foxel.Api.Management;
|
namespace Foxel.Api.Management;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Foxel.Controllers;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Models.Request.Picture;
|
using Foxel.Models.Request.Picture;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Request.Tag;
|
using Foxel.Models.Request.Tag;
|
||||||
using Foxel.Models.Response.Tag;
|
using Foxel.Models.Response.Tag;
|
||||||
using Foxel.Services.Media;
|
using Foxel.Services.Media;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
namespace Foxel.Controllers;
|
namespace Foxel.Api;
|
||||||
|
|
||||||
[Route("api/tag")]
|
[Route("api/tag")]
|
||||||
public class TagController(ITagService tagService) : BaseApiController
|
public class TagController(ITagService tagService) : BaseApiController
|
||||||
|
|||||||
@@ -12,9 +12,9 @@ using Foxel.Services.Initializer;
|
|||||||
using Foxel.Services.Management;
|
using Foxel.Services.Management;
|
||||||
using Foxel.Services.Media;
|
using Foxel.Services.Media;
|
||||||
using Foxel.Services.Storage;
|
using Foxel.Services.Storage;
|
||||||
using Foxel.Services.VectorDB;
|
|
||||||
using Foxel.Services.Background.Processors;
|
using Foxel.Services.Background.Processors;
|
||||||
using Foxel.Services.Mapping;
|
using Foxel.Services.Mapping;
|
||||||
|
using Foxel.Services.VectorDb;
|
||||||
|
|
||||||
namespace Foxel.Extensions;
|
namespace Foxel.Extensions;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
|
|
||||||
namespace Foxel.Models.DataBase;
|
namespace Foxel.Models.DataBase;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using Foxel.Services.Attributes;
|
using Foxel.Services.Storage;
|
||||||
|
|
||||||
namespace Foxel.Models.DataBase;
|
namespace Foxel.Models.DataBase;
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,7 @@ namespace Foxel.Models;
|
|||||||
|
|
||||||
public record PaginatedResult<T> : BaseResult<List<T>>
|
public record PaginatedResult<T> : BaseResult<List<T>>
|
||||||
{
|
{
|
||||||
|
public int Page { get; init; } = 1;
|
||||||
|
public int PageSize { get; init; } = 10;
|
||||||
public int Page { get; set; } = 1;
|
public int TotalCount { get; init; }
|
||||||
public int PageSize { get; set; } = 10;
|
|
||||||
public int TotalCount { get; set; }
|
|
||||||
public int TotalPages => (int)Math.Ceiling(TotalCount / (double)PageSize);
|
|
||||||
public bool HasPreviousPage => Page > 1;
|
|
||||||
public bool HasNextPage => Page < TotalPages;
|
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Foxel.Services.Attributes; // For StorageType enum
|
using Foxel.Services.Storage;
|
||||||
|
|
||||||
|
// For StorageType enum
|
||||||
|
|
||||||
namespace Foxel.Models.Request.Storage;
|
namespace Foxel.Models.Request.Storage;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using Foxel.Services.Attributes; // For StorageType enum
|
using Foxel.Services.Storage;
|
||||||
|
|
||||||
|
// For StorageType enum
|
||||||
|
|
||||||
namespace Foxel.Models.Request.Storage;
|
namespace Foxel.Models.Request.Storage;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Foxel.Services.Attributes; // For StorageType enum
|
using Foxel.Services.Storage;
|
||||||
|
|
||||||
|
// For StorageType enum
|
||||||
|
|
||||||
namespace Foxel.Models.Response.Storage;
|
namespace Foxel.Models.Response.Storage;
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
using Foxel.Extensions;
|
using Foxel.Extensions;
|
||||||
using Foxel.Services.Initializer;
|
using Foxel.Services.Initializer;
|
||||||
using Foxel.Services.VectorDB;
|
using Foxel.Services.VectorDb;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
|
|
||||||
|
namespace Foxel.Services.AI;
|
||||||
|
|
||||||
public interface IFaceClusteringService
|
public interface IFaceClusteringService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -10,7 +10,10 @@ using static Foxel.Utils.AuthHelper;
|
|||||||
|
|
||||||
namespace Foxel.Services.Auth;
|
namespace Foxel.Services.Auth;
|
||||||
|
|
||||||
public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfigService configuration, ILogger<AuthService> logger)
|
public class AuthService(
|
||||||
|
IDbContextFactory<MyDbContext> dbContextFactory,
|
||||||
|
IConfigService configuration,
|
||||||
|
ILogger<AuthService> logger)
|
||||||
: IAuthService
|
: IAuthService
|
||||||
{
|
{
|
||||||
public async Task<(bool success, string message, User? user)> RegisterUserAsync(RegisterRequest request)
|
public async Task<(bool success, string message, User? user)> RegisterUserAsync(RegisterRequest request)
|
||||||
@@ -196,11 +199,11 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
$"https://github.com/login/oauth/authorize?client_id={Uri.EscapeDataString(githubClientId)}&redirect_uri={Uri.EscapeDataString(githubCallback)}";
|
$"https://github.com/login/oauth/authorize?client_id={Uri.EscapeDataString(githubClientId)}&redirect_uri={Uri.EscapeDataString(githubCallback)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(GitHubAuthResult result, string message, string? data)> ProcessGitHubCallbackAsync(string code)
|
public async Task<(OAuthResult result, string message, string? data)> ProcessGitHubCallbackAsync(string code)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(code))
|
if (string.IsNullOrEmpty(code))
|
||||||
{
|
{
|
||||||
return (GitHubAuthResult.InvalidCode, "GitHub授权码无效", null);
|
return (OAuthResult.InvalidCode, "GitHub授权码无效", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
string githubClientId = configuration["Authentication:GitHubClientId"];
|
string githubClientId = configuration["Authentication:GitHubClientId"];
|
||||||
@@ -219,7 +222,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
{
|
{
|
||||||
var errorContent = await tokenResponse.Content.ReadAsStringAsync();
|
var errorContent = await tokenResponse.Content.ReadAsStringAsync();
|
||||||
logger.LogError("获取GitHub访问令牌失败: {StatusCode}, {ErrorContent}", tokenResponse.StatusCode, errorContent);
|
logger.LogError("获取GitHub访问令牌失败: {StatusCode}, {ErrorContent}", tokenResponse.StatusCode, errorContent);
|
||||||
return (GitHubAuthResult.TokenRequestFailed, $"获取GitHub访问令牌失败: {errorContent}", null);
|
return (OAuthResult.TokenRequestFailed, $"获取GitHub访问令牌失败: {errorContent}", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tokenResponseContent = await tokenResponse.Content.ReadAsStringAsync();
|
var tokenResponseContent = await tokenResponse.Content.ReadAsStringAsync();
|
||||||
@@ -229,7 +232,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
accessTokenElement.GetString() == null)
|
accessTokenElement.GetString() == null)
|
||||||
{
|
{
|
||||||
logger.LogError("GitHub响应中未找到access_token: {TokenResponseContent}", tokenResponseContent);
|
logger.LogError("GitHub响应中未找到access_token: {TokenResponseContent}", tokenResponseContent);
|
||||||
return (GitHubAuthResult.TokenRequestFailed, "获取GitHub访问令牌失败,响应中未包含令牌。", null);
|
return (OAuthResult.TokenRequestFailed, "获取GitHub访问令牌失败,响应中未包含令牌。", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var accessToken = accessTokenElement.GetString();
|
var accessToken = accessTokenElement.GetString();
|
||||||
@@ -242,7 +245,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
{
|
{
|
||||||
var errorContent = await userResponse.Content.ReadAsStringAsync();
|
var errorContent = await userResponse.Content.ReadAsStringAsync();
|
||||||
logger.LogError("获取GitHub用户信息失败: {StatusCode}, {ErrorContent}", userResponse.StatusCode, errorContent);
|
logger.LogError("获取GitHub用户信息失败: {StatusCode}, {ErrorContent}", userResponse.StatusCode, errorContent);
|
||||||
return (GitHubAuthResult.UserInfoFailed, $"获取GitHub用户信息失败: {errorContent}", null);
|
return (OAuthResult.UserInfoFailed, $"获取GitHub用户信息失败: {errorContent}", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var userContent = await userResponse.Content.ReadAsStringAsync();
|
var userContent = await userResponse.Content.ReadAsStringAsync();
|
||||||
@@ -275,34 +278,34 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(githubUserId))
|
if (string.IsNullOrEmpty(githubUserId))
|
||||||
{
|
{
|
||||||
return (GitHubAuthResult.InvalidUserId, "无法从GitHub获取用户ID", null);
|
return (OAuthResult.InvalidUserId, "无法从GitHub获取用户ID", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (isSuccess, message, user) = await FindGitHubUserAsync(githubUserId);
|
var (isSuccess, message, user) = await FindGitHubUserAsync(githubUserId);
|
||||||
|
|
||||||
if (!isSuccess || user == null)
|
if (!isSuccess || user == null)
|
||||||
{
|
{
|
||||||
return (GitHubAuthResult.UserNotBound, "GitHub用户未绑定到系统账户", githubUserId);
|
return (OAuthResult.UserNotBound, "GitHub用户未绑定到系统账户", githubUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var jwtToken = await GenerateJwtTokenAsync(user);
|
var jwtToken = await GenerateJwtTokenAsync(user);
|
||||||
return (GitHubAuthResult.Success, "GitHub授权成功", jwtToken);
|
return (OAuthResult.Success, "GitHub授权成功", jwtToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetLinuxDoLoginUrl()
|
public string GetLinuxDoLoginUrl()
|
||||||
{
|
{
|
||||||
string linuxdoClientId = configuration["Authentication:LinuxDoClientId"];
|
string linuxdoClientId = configuration["Authentication:LinuxDoClientId"];
|
||||||
string linuxdoCallback = configuration["Authentication:LinuxDoCallbackUrl"];
|
string linuxdoCallback = configuration["Authentication:LinuxDoCallbackUrl"];
|
||||||
string state = Guid.NewGuid().ToString();
|
string state = Guid.NewGuid().ToString();
|
||||||
return
|
return
|
||||||
$"https://connect.linux.do/oauth2/authorize?response_type=code&client_id={Uri.EscapeDataString(linuxdoClientId)}&redirect_uri={Uri.EscapeDataString(linuxdoCallback)}&state={Uri.EscapeDataString(state)}";
|
$"https://connect.linux.do/oauth2/authorize?response_type=code&client_id={Uri.EscapeDataString(linuxdoClientId)}&redirect_uri={Uri.EscapeDataString(linuxdoCallback)}&state={Uri.EscapeDataString(state)}";
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(LinuxDoAuthResult result, string message, string? data)> ProcessLinuxDoCallbackAsync(string code)
|
public async Task<(OAuthResult result, string message, string? data)> ProcessLinuxDoCallbackAsync(string code)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(code))
|
if (string.IsNullOrEmpty(code))
|
||||||
{
|
{
|
||||||
return (LinuxDoAuthResult.InvalidCode, "LinuxDo授权码无效", null);
|
return (OAuthResult.InvalidCode, "LinuxDo授权码无效", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
string linuxdoClientId = configuration["Authentication:LinuxDoClientId"];
|
string linuxdoClientId = configuration["Authentication:LinuxDoClientId"];
|
||||||
@@ -331,7 +334,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
{
|
{
|
||||||
var errorContent = await tokenResponse.Content.ReadAsStringAsync();
|
var errorContent = await tokenResponse.Content.ReadAsStringAsync();
|
||||||
logger.LogError("获取LinuxDo访问令牌失败: {StatusCode}, {ErrorContent}", tokenResponse.StatusCode, errorContent);
|
logger.LogError("获取LinuxDo访问令牌失败: {StatusCode}, {ErrorContent}", tokenResponse.StatusCode, errorContent);
|
||||||
return (LinuxDoAuthResult.TokenRequestFailed, $"获取LinuxDo访问令牌失败: {errorContent}", null);
|
return (OAuthResult.TokenRequestFailed, $"获取LinuxDo访问令牌失败: {errorContent}", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tokenResponseContent = await tokenResponse.Content.ReadAsStringAsync();
|
var tokenResponseContent = await tokenResponse.Content.ReadAsStringAsync();
|
||||||
@@ -341,7 +344,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
accessTokenElement.GetString() == null)
|
accessTokenElement.GetString() == null)
|
||||||
{
|
{
|
||||||
logger.LogError("LinuxDo响应中未找到access_token: {TokenResponseContent}", tokenResponseContent);
|
logger.LogError("LinuxDo响应中未找到access_token: {TokenResponseContent}", tokenResponseContent);
|
||||||
return (LinuxDoAuthResult.TokenRequestFailed, "获取LinuxDo访问令牌失败,响应中未包含令牌。", null);
|
return (OAuthResult.TokenRequestFailed, "获取LinuxDo访问令牌失败,响应中未包含令牌。", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var accessToken = accessTokenElement.GetString();
|
var accessToken = accessTokenElement.GetString();
|
||||||
@@ -355,7 +358,7 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
{
|
{
|
||||||
var errorContent = await userResponse.Content.ReadAsStringAsync();
|
var errorContent = await userResponse.Content.ReadAsStringAsync();
|
||||||
logger.LogError("获取LinuxDo用户信息失败: {StatusCode}, {ErrorContent}", userResponse.StatusCode, errorContent);
|
logger.LogError("获取LinuxDo用户信息失败: {StatusCode}, {ErrorContent}", userResponse.StatusCode, errorContent);
|
||||||
return (LinuxDoAuthResult.UserInfoFailed, $"获取LinuxDo用户信息失败: {errorContent}", null);
|
return (OAuthResult.UserInfoFailed, $"获取LinuxDo用户信息失败: {errorContent}", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var userContent = await userResponse.Content.ReadAsStringAsync();
|
var userContent = await userResponse.Content.ReadAsStringAsync();
|
||||||
@@ -382,18 +385,18 @@ public class AuthService(IDbContextFactory<MyDbContext> dbContextFactory, IConfi
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(linuxdoUserId))
|
if (string.IsNullOrEmpty(linuxdoUserId))
|
||||||
{
|
{
|
||||||
return (LinuxDoAuthResult.InvalidUserId, "无法从LinuxDo获取用户ID", null);
|
return (OAuthResult.InvalidUserId, "无法从LinuxDo获取用户ID", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
var (isSuccess, message, user) = await FindLinuxDoUserAsync(linuxdoUserId);
|
var (isSuccess, message, user) = await FindLinuxDoUserAsync(linuxdoUserId);
|
||||||
|
|
||||||
if (!isSuccess || user == null)
|
if (!isSuccess || user == null)
|
||||||
{
|
{
|
||||||
return (LinuxDoAuthResult.UserNotBound, "LinuxDo用户未绑定到系统账户", linuxdoUserId);
|
return (OAuthResult.UserNotBound, "LinuxDo用户未绑定到系统账户", linuxdoUserId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var jwtToken = await GenerateJwtTokenAsync(user);
|
var jwtToken = await GenerateJwtTokenAsync(user);
|
||||||
return (LinuxDoAuthResult.Success, "LinuxDo授权成功", jwtToken);
|
return (OAuthResult.Success, "LinuxDo授权成功", jwtToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<(bool success, string message, User? user)> BindAccountAsync(BindAccountRequest request)
|
public async Task<(bool success, string message, User? user)> BindAccountAsync(BindAccountRequest request)
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Foxel.Services.Auth;
|
|
||||||
|
|
||||||
public enum GitHubAuthResult
|
|
||||||
{
|
|
||||||
Success, // 授权成功并找到绑定用户
|
|
||||||
UserNotBound, // 授权成功但用户未绑定
|
|
||||||
InvalidCode, // 授权码无效
|
|
||||||
TokenRequestFailed, // 获取访问令牌失败
|
|
||||||
UserInfoFailed, // 获取用户信息失败
|
|
||||||
InvalidUserId // 无法获取GitHub用户ID
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,16 @@ using Foxel.Models.Request.Auth;
|
|||||||
|
|
||||||
namespace Foxel.Services.Auth;
|
namespace Foxel.Services.Auth;
|
||||||
|
|
||||||
|
public enum OAuthResult
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
UserNotBound,
|
||||||
|
InvalidCode,
|
||||||
|
TokenRequestFailed,
|
||||||
|
UserInfoFailed,
|
||||||
|
InvalidUserId
|
||||||
|
}
|
||||||
|
|
||||||
public interface IAuthService
|
public interface IAuthService
|
||||||
{
|
{
|
||||||
Task<(bool success, string message, User? user)> RegisterUserAsync(RegisterRequest request);
|
Task<(bool success, string message, User? user)> RegisterUserAsync(RegisterRequest request);
|
||||||
@@ -14,7 +24,7 @@ public interface IAuthService
|
|||||||
Task<(bool success, string message, User? user)> UpdateUserInfoAsync(int userId, UpdateUserRequest request);
|
Task<(bool success, string message, User? user)> UpdateUserInfoAsync(int userId, UpdateUserRequest request);
|
||||||
string GetGitHubLoginUrl();
|
string GetGitHubLoginUrl();
|
||||||
string GetLinuxDoLoginUrl();
|
string GetLinuxDoLoginUrl();
|
||||||
Task<(GitHubAuthResult result, string message, string? data)> ProcessGitHubCallbackAsync(string code);
|
Task<(OAuthResult result, string message, string? data)> ProcessGitHubCallbackAsync(string code);
|
||||||
Task<(LinuxDoAuthResult result, string message, string? data)> ProcessLinuxDoCallbackAsync(string code);
|
Task<(OAuthResult result, string message, string? data)> ProcessLinuxDoCallbackAsync(string code);
|
||||||
Task<(bool success, string message, User? user)> BindAccountAsync(BindAccountRequest request);
|
Task<(bool success, string message, User? user)> BindAccountAsync(BindAccountRequest request);
|
||||||
}
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
namespace Foxel.Services.Auth;
|
|
||||||
|
|
||||||
public enum LinuxDoAuthResult
|
|
||||||
{
|
|
||||||
Success, // 授权成功并找到绑定用户
|
|
||||||
UserNotBound, // 授权成功但用户未绑定
|
|
||||||
InvalidCode, // 授权码无效
|
|
||||||
TokenRequestFailed, // 获取访问令牌失败
|
|
||||||
UserInfoFailed, // 获取用户信息失败
|
|
||||||
InvalidUserId // 无法获取LinuxDo用户ID
|
|
||||||
}
|
|
||||||
@@ -85,7 +85,7 @@ namespace Foxel.Services.Background.Processors
|
|||||||
using var scope = serviceProvider.CreateScope();
|
using var scope = serviceProvider.CreateScope();
|
||||||
var storageService = scope.ServiceProvider.GetRequiredService<IStorageService>();
|
var storageService = scope.ServiceProvider.GetRequiredService<IStorageService>();
|
||||||
|
|
||||||
if (picture.StorageMode.StorageType == Attributes.StorageType.Local)
|
if (picture.StorageMode.StorageType == StorageType.Local)
|
||||||
{
|
{
|
||||||
logger.LogInformation(
|
logger.LogInformation(
|
||||||
"Picture {PictureId} is Local. Attempting to download via StorageService for consistency.",
|
"Picture {PictureId} is Local. Attempting to download via StorageService for consistency.",
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Services.AI;
|
using Foxel.Services.AI;
|
||||||
using Foxel.Services.Storage;
|
using Foxel.Services.Storage;
|
||||||
using Foxel.Services.VectorDB;
|
|
||||||
using Foxel.Utils;
|
using Foxel.Utils;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using Foxel.Services.VectorDb;
|
||||||
// using Foxel.Services.Attributes; // StorageType enum might not be directly needed here anymore
|
// using Foxel.Services.Attributes; // StorageType enum might not be directly needed here anymore
|
||||||
using Microsoft.Extensions.DependencyInjection; // For CreateScope
|
using Microsoft.Extensions.DependencyInjection; // For CreateScope
|
||||||
using Microsoft.AspNetCore.Hosting; // For IWebHostEnvironment
|
using Microsoft.AspNetCore.Hosting; // For IWebHostEnvironment
|
||||||
@@ -117,7 +117,7 @@ namespace Foxel.Services.Background.Processors
|
|||||||
string actualThumbnailPathForAI;
|
string actualThumbnailPathForAI;
|
||||||
|
|
||||||
// Check the StorageType of the associated StorageMode
|
// Check the StorageType of the associated StorageMode
|
||||||
if (picture.StorageMode.StorageType == Attributes.StorageType.Local)
|
if (picture.StorageMode.StorageType == StorageType.Local)
|
||||||
{
|
{
|
||||||
// As with PictureTaskProcessor, safer to use DownloadFileAsync for consistency
|
// As with PictureTaskProcessor, safer to use DownloadFileAsync for consistency
|
||||||
_logger.LogInformation("Picture {PictureId} thumbnail is Local. Attempting to download via StorageService for AI.", pictureId);
|
_logger.LogInformation("Picture {PictureId} thumbnail is Local. Attempting to download via StorageService for AI.", pictureId);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Foxel.Services.Logging;
|
using Foxel.Services.Logging;
|
||||||
|
using Foxel.Services.Storage;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Foxel.Services.Initializer;
|
namespace Foxel.Services.Initializer;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using Foxel.Models; // For PaginatedResult
|
using Foxel.Models; // For PaginatedResult
|
||||||
using Foxel.Models.Request.Storage;
|
using Foxel.Models.Request.Storage;
|
||||||
using Foxel.Models.Response.Storage;
|
using Foxel.Models.Response.Storage;
|
||||||
using Foxel.Services.Attributes; // For StorageType
|
using Foxel.Services.Storage;
|
||||||
|
|
||||||
|
// For StorageType
|
||||||
|
|
||||||
namespace Foxel.Services.Management;
|
namespace Foxel.Services.Management;
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ using Foxel.Models;
|
|||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Models.Request.Storage;
|
using Foxel.Models.Request.Storage;
|
||||||
using Foxel.Models.Response.Storage;
|
using Foxel.Models.Response.Storage;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Storage.Providers; // Required for config types like LocalStorageConfig, etc.
|
using Foxel.Services.Storage.Providers; // Required for config types like LocalStorageConfig, etc.
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Foxel.Services.Configuration; // Added for IConfigService
|
using Foxel.Services.Configuration;
|
||||||
|
using Foxel.Services.Storage; // Added for IConfigService
|
||||||
|
|
||||||
namespace Foxel.Services.Management;
|
namespace Foxel.Services.Management;
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ using Foxel.Services.AI;
|
|||||||
using Foxel.Services.Background;
|
using Foxel.Services.Background;
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Foxel.Services.Storage;
|
using Foxel.Services.Storage;
|
||||||
using Foxel.Services.VectorDB;
|
|
||||||
using Foxel.Services.Mapping;
|
using Foxel.Services.Mapping;
|
||||||
|
using Foxel.Services.VectorDb;
|
||||||
using Foxel.Utils;
|
using Foxel.Utils;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.DataBase;
|
using Foxel.Models.DataBase;
|
||||||
using Foxel.Models.Response.Tag;
|
using Foxel.Models.Response.Tag;
|
||||||
using Foxel.Services.Media;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Foxel.Services;
|
namespace Foxel.Services.Media;
|
||||||
|
|
||||||
public class TagService(IDbContextFactory<MyDbContext> contextFactory, ILogger<TagService> logger) : ITagService
|
public class TagService(IDbContextFactory<MyDbContext> contextFactory, ILogger<TagService> logger) : ITagService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using Foxel.Services.Attributes;
|
|
||||||
|
|
||||||
namespace Foxel.Services.Storage;
|
namespace Foxel.Services.Storage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using COSXML.CosException;
|
|||||||
using COSXML.Model.Object;
|
using COSXML.Model.Object;
|
||||||
using COSXML.Model.Tag;
|
using COSXML.Model.Tag;
|
||||||
using COSXML.Transfer;
|
using COSXML.Transfer;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Amazon.S3;
|
using Amazon.S3;
|
||||||
using Amazon.S3.Model;
|
using Amazon.S3.Model;
|
||||||
using Amazon.S3.Transfer;
|
using Amazon.S3.Transfer;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
|
|
||||||
namespace Foxel.Services.Storage.Providers;
|
namespace Foxel.Services.Storage.Providers;
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
using Foxel.Models.DataBase;
|
namespace Foxel.Services.Storage;
|
||||||
|
|
||||||
namespace Foxel.Services.Attributes;
|
|
||||||
|
|
||||||
public enum StorageType
|
public enum StorageType
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Foxel.Services.Attributes;
|
|
||||||
using Microsoft.EntityFrameworkCore; // For IDbContextFactory
|
using Microsoft.EntityFrameworkCore; // For IDbContextFactory
|
||||||
using System.Text.Json; // For JsonSerializer
|
using System.Text.Json; // For JsonSerializer
|
||||||
using Foxel.Services.Storage.Providers; // For specific config classes
|
using Foxel.Services.Storage.Providers; // For specific config classes
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Foxel.Models.Vector;
|
using Foxel.Models.Vector;
|
||||||
|
|
||||||
namespace Foxel.Services.VectorDB;
|
namespace Foxel.Services.VectorDb;
|
||||||
|
|
||||||
public interface IVectorDbService
|
public interface IVectorDbService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.VectorData;
|
using Microsoft.Extensions.VectorData;
|
||||||
using Microsoft.SemanticKernel.Connectors.InMemory;
|
using Microsoft.SemanticKernel.Connectors.InMemory;
|
||||||
|
|
||||||
namespace Foxel.Services.VectorDB;
|
namespace Foxel.Services.VectorDb;
|
||||||
|
|
||||||
public class InMemoryVectorDbService : IVectorDbService
|
public class InMemoryVectorDbService : IVectorDbService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using Microsoft.Extensions.VectorData;
|
|||||||
using Microsoft.SemanticKernel.Connectors.Qdrant;
|
using Microsoft.SemanticKernel.Connectors.Qdrant;
|
||||||
using Qdrant.Client;
|
using Qdrant.Client;
|
||||||
|
|
||||||
namespace Foxel.Services.VectorDB;
|
namespace Foxel.Services.VectorDb;
|
||||||
|
|
||||||
public class QdrantVectorDbService(IDbContextFactory<MyDbContext> contextFactory, IConfigService configService)
|
public class QdrantVectorDbService(IDbContextFactory<MyDbContext> contextFactory, IConfigService configService)
|
||||||
: IVectorDbService
|
: IVectorDbService
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
|
|
||||||
namespace Foxel.Services.VectorDB;
|
namespace Foxel.Services.VectorDb;
|
||||||
|
|
||||||
public class VectorDbInitializer : IHostedService
|
public class VectorDbInitializer : IHostedService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ using Foxel.Models.Vector;
|
|||||||
using Foxel.Services.Configuration;
|
using Foxel.Services.Configuration;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Foxel.Services.VectorDB;
|
namespace Foxel.Services.VectorDb;
|
||||||
|
|
||||||
public class VectorDbManager(IServiceProvider serviceProvider, IConfigService configService)
|
public class VectorDbManager(IServiceProvider serviceProvider, IConfigService configService)
|
||||||
: IVectorDbService
|
: IVectorDbService
|
||||||
|
|||||||
+8
-12
@@ -1,5 +1,3 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace Foxel.Utils;
|
namespace Foxel.Utils;
|
||||||
|
|
||||||
public static class AiHelper
|
public static class AiHelper
|
||||||
@@ -10,17 +8,15 @@ public static class AiHelper
|
|||||||
/// <param name="aiResponse">AI生成的响应文本</param>
|
/// <param name="aiResponse">AI生成的响应文本</param>
|
||||||
/// <param name="logger">日志记录器</param>
|
/// <param name="logger">日志记录器</param>
|
||||||
/// <returns>包含标题和描述的元组</returns>
|
/// <returns>包含标题和描述的元组</returns>
|
||||||
public static (string title, string description) ExtractTitleAndDescription(string aiResponse, ILogger? logger = null)
|
public static (string title, string description) ExtractTitleAndDescription(string aiResponse,
|
||||||
|
ILogger? logger = null)
|
||||||
{
|
{
|
||||||
string title = "AI生成的标题";
|
string title = "AI生成的标题";
|
||||||
string description = "AI生成的描述";
|
string description = "AI生成的描述";
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 尝试解析JSON响应
|
|
||||||
if (aiResponse.Contains("{") && aiResponse.Contains("}"))
|
if (aiResponse.Contains("{") && aiResponse.Contains("}"))
|
||||||
{
|
{
|
||||||
// 提取JSON部分
|
|
||||||
int jsonStartIndex = aiResponse.IndexOf('{');
|
int jsonStartIndex = aiResponse.IndexOf('{');
|
||||||
int jsonEndIndex = aiResponse.LastIndexOf('}') + 1;
|
int jsonEndIndex = aiResponse.LastIndexOf('}') + 1;
|
||||||
|
|
||||||
@@ -34,7 +30,8 @@ public static class AiHelper
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = System.Text.Json.JsonSerializer.Deserialize<ImageAnalysisResult>(jsonPart, options);
|
var result =
|
||||||
|
System.Text.Json.JsonSerializer.Deserialize<ImageAnalysisResult>(jsonPart, options);
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrWhiteSpace(result.Title))
|
if (!string.IsNullOrWhiteSpace(result.Title))
|
||||||
@@ -93,15 +90,14 @@ public static class AiHelper
|
|||||||
return (title, description);
|
return (title, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 用于解析JSON的类
|
|
||||||
public class ImageAnalysisResult
|
public class ImageAnalysisResult
|
||||||
{
|
{
|
||||||
public string Title { get; set; } = string.Empty;
|
public string Title { get; init; } = string.Empty;
|
||||||
public string Description { get; set; } = string.Empty;
|
public string Description { get; init; } = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TagsResult
|
public class TagsResult
|
||||||
{
|
{
|
||||||
public string[] Tags { get; set; } = Array.Empty<string>();
|
public string[] Tags { get; init; } = [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,6 @@ using SixLabors.ImageSharp.Metadata.Profiles.Exif;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using Foxel.Models;
|
using Foxel.Models;
|
||||||
using Foxel.Models.Enums;
|
using Foxel.Models.Enums;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
|
||||||
|
|
||||||
namespace Foxel.Utils;
|
namespace Foxel.Utils;
|
||||||
|
|
||||||
@@ -13,21 +12,6 @@ namespace Foxel.Utils;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ImageHelper
|
public static class ImageHelper
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 获取完整URL路径
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="serverUrl">服务器URL</param>
|
|
||||||
/// <param name="relativePath">相对路径</param>
|
|
||||||
/// <returns>完整URL路径</returns>
|
|
||||||
public static string GetFullPath(string serverUrl, string relativePath)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrEmpty(relativePath))
|
|
||||||
return string.Empty;
|
|
||||||
if (relativePath.StartsWith("https://"))
|
|
||||||
return relativePath;
|
|
||||||
return $"{serverUrl.TrimEnd('/')}{relativePath}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 创建缩略图
|
/// 创建缩略图
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -76,58 +60,6 @@ public static class ImageHelper
|
|||||||
return thumbnailFileInfo.Length;
|
return thumbnailFileInfo.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 检查图像是否包含透明像素
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="image">要检查的图像</param>
|
|
||||||
/// <returns>如果图像包含透明像素则返回true</returns>
|
|
||||||
private static bool HasTransparency(Image image)
|
|
||||||
{
|
|
||||||
// 检查图像格式是否支持透明度
|
|
||||||
if (image.PixelType.AlphaRepresentation == PixelAlphaRepresentation.None)
|
|
||||||
{
|
|
||||||
return false; // 图像格式不支持透明度
|
|
||||||
}
|
|
||||||
|
|
||||||
// 对于小图片,逐像素检查是否有透明度
|
|
||||||
if (image.Width * image.Height <= 1000 * 1000) // 对于不超过1000x1000的图片
|
|
||||||
{
|
|
||||||
using var imageWithAlpha = image.CloneAs<Rgba32>();
|
|
||||||
|
|
||||||
for (int y = 0; y < imageWithAlpha.Height; y++)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < imageWithAlpha.Width; x++)
|
|
||||||
{
|
|
||||||
if (imageWithAlpha[x, y].A < 255)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
using var imageWithAlpha = image.CloneAs<Rgba32>();
|
|
||||||
int sampleSize = Math.Max(image.Width, image.Height) / 100;
|
|
||||||
sampleSize = Math.Max(1, sampleSize);
|
|
||||||
|
|
||||||
for (int y = 0; y < imageWithAlpha.Height; y += sampleSize)
|
|
||||||
{
|
|
||||||
for (int x = 0; x < imageWithAlpha.Width; x += sampleSize)
|
|
||||||
{
|
|
||||||
if (imageWithAlpha[x, y].A < 255)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 根据原始文件大小调整质量参数
|
/// 根据原始文件大小调整质量参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
Reference in New Issue
Block a user