diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/AgentSendInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/AgentSendInput.cs index 85425145..e2eed240 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/AgentSendInput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/AgentSendInput.cs @@ -15,7 +15,7 @@ public class AgentSendInput /// /// api密钥Id /// - public string Token { get; set; } + public Guid TokenId { get; set; } /// /// 模型id diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageGenerationInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageGenerationInput.cs index c9bade65..7526b00f 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageGenerationInput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageGenerationInput.cs @@ -5,6 +5,11 @@ namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Chat; /// public class ImageGenerationInput { + /// + /// 密钥id + /// + public Guid? TokenId { get; set; } + /// /// 提示词 /// @@ -16,7 +21,7 @@ public class ImageGenerationInput public string ModelId { get; set; } = string.Empty; /// - /// 参考图Base64列表(可选,包含前缀如 data:image/png;base64,...) + /// 参考图PrefixBase64列表(可选,包含前缀如 data:image/png;base64,...) /// - public List? ReferenceImagesBase64 { get; set; } + public List? ReferenceImagesPrefixBase64 { get; set; } } diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageTaskOutput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageTaskOutput.cs index 1834b5a0..aba37169 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageTaskOutput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/ImageTaskOutput.cs @@ -18,19 +18,19 @@ public class ImageTaskOutput public string Prompt { get; set; } = string.Empty; /// - /// 参考图Base64列表 + /// 参考图PrefixBase64列表(带前缀) /// - public List? ReferenceImagesBase64 { get; set; } + // public List? ReferenceImagesPrefixBase64 { get; set; } /// /// 参考图URL列表 /// - public List? ReferenceImagesUrl { get; set; } + // public List? ReferenceImagesUrl { get; set; } /// - /// 生成图片Base64(包含前缀) + /// 生成图片PrefixBase64(包含前缀) /// - public string? StoreBase64 { get; set; } + public string? StorePrefixBase64 { get; set; } /// /// 生成图片URL @@ -42,6 +42,16 @@ public class ImageTaskOutput /// public TaskStatusEnum TaskStatus { get; set; } + /// + /// 发布状态 + /// + public PublishStatusEnum PublishStatus { get; set; } + + /// + /// 分类标签 + /// + public List Categories { get; set; } = new(); + /// /// 创建时间 /// diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/PublishImageInput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/PublishImageInput.cs new file mode 100644 index 00000000..9300d7df --- /dev/null +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/Chat/PublishImageInput.cs @@ -0,0 +1,17 @@ +namespace Yi.Framework.AiHub.Application.Contracts.Dtos.Chat; + +/// +/// 发布图片输入 +/// +public class PublishImageInput +{ + /// + /// 任务ID + /// + public Guid TaskId { get; set; } + + /// + /// 分类标签 + /// + public List Categories { get; set; } = new(); +} diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/ModelGetListOutput.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/ModelGetListOutput.cs index 6ebf2f2c..b89560aa 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/ModelGetListOutput.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application.Contracts/Dtos/ModelGetListOutput.cs @@ -6,13 +6,7 @@ public class ModelGetListOutput /// 模型ID /// public Guid Id { get; set; } - - /// - /// 模型分类 - /// - public string Category { get; set; } - - + /// /// 模型id /// @@ -28,36 +22,6 @@ public class ModelGetListOutput /// public string? ModelDescribe { get; set; } - /// - /// 模型价格 - /// - public double ModelPrice { get; set; } - - /// - /// 模型类型 - /// - public string ModelType { get; set; } - - /// - /// 模型展示状态 - /// - public string ModelShow { get; set; } - - /// - /// 系统提示 - /// - public string SystemPrompt { get; set; } - - /// - /// API 主机地址 - /// - public string ApiHost { get; set; } - - /// - /// API 密钥 - /// - public string ApiKey { get; set; } - /// /// 备注信息 /// diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJob.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJob.cs index fca09694..c1c81660 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJob.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJob.cs @@ -30,32 +30,93 @@ public class ImageGenerationJob : AsyncBackgroundJob, IT public override async Task ExecuteAsync(ImageGenerationJobArgs args) { - _logger.LogInformation("开始执行图片生成任务,TaskId: {TaskId}, ModelId: {ModelId}, UserId: {UserId}", - args.TaskId, args.ModelId, args.UserId); + var task = await _imageStoreTaskRepository.GetFirstAsync(x => x.Id == args.TaskId); + if (task is null) + { + throw new UserFriendlyException($"{args.TaskId} 图片生成任务不存在"); + } + _logger.LogInformation("开始执行图片生成任务,TaskId: {TaskId}, ModelId: {ModelId}, UserId: {UserId}", + task.Id, task.ModelId, task.UserId); try { - var request = JsonSerializer.Deserialize(args.RequestJson); + // 构建 Gemini API 请求对象 + var parts = new List + { + new { text = task.Prompt } + }; + // 添加参考图(如果有) + foreach (var prefixBase64 in task.ReferenceImagesPrefixBase64) + { + var (mimeType, base64Data) = ParsePrefixBase64(prefixBase64); + parts.Add(new + { + inline_data = new + { + mime_type = mimeType, + data = base64Data + } + }); + } + + var requestObj = new + { + contents = new[] + { + new { parts } + } + }; + + var request = JsonSerializer.Deserialize( + JsonSerializer.Serialize(requestObj)); + + //里面生成成功已经包含扣款了 await _aiGateWayManager.GeminiGenerateContentImageForStatisticsAsync( - args.TaskId, - args.ModelId, + task.Id, + task.ModelId, request, - args.UserId); + task.UserId, + tokenId:task.TokenId); + _logger.LogInformation("图片生成任务完成,TaskId: {TaskId}", args.TaskId); } catch (Exception ex) { _logger.LogError(ex, "图片生成任务失败,TaskId: {TaskId}, Error: {Error}", args.TaskId, ex.Message); - // 更新任务状态为失败 - var task = await _imageStoreTaskRepository.GetFirstAsync(x => x.Id == args.TaskId); - if (task != null) - { - task.TaskStatus = TaskStatusEnum.Fail; - await _imageStoreTaskRepository.UpdateAsync(task); - } + task.TaskStatus = TaskStatusEnum.Fail; + task.ErrorInfo = ex.Message; + + await _imageStoreTaskRepository.UpdateAsync(task); } } -} + + /// + /// 解析带前缀的 Base64 字符串,提取 mimeType 和纯 base64 数据 + /// + private static (string mimeType, string base64Data) ParsePrefixBase64(string prefixBase64) + { + // 默认值 + var mimeType = "image/png"; + var base64Data = prefixBase64; + + if (prefixBase64.Contains(",")) + { + var parts = prefixBase64.Split(','); + if (parts.Length == 2) + { + var header = parts[0]; + if (header.Contains(":") && header.Contains(";")) + { + mimeType = header.Split(':')[1].Split(';')[0]; + } + + base64Data = parts[1]; + } + } + + return (mimeType, base64Data); + } +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJobArgs.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJobArgs.cs index 666b6b59..7da50f81 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJobArgs.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Jobs/ImageGenerationJobArgs.cs @@ -9,19 +9,4 @@ public class ImageGenerationJobArgs /// 图片任务ID /// public Guid TaskId { get; set; } - - /// - /// 模型ID - /// - public string ModelId { get; set; } = string.Empty; - - /// - /// 请求JSON字符串 - /// - public string RequestJson { get; set; } = string.Empty; - - /// - /// 用户ID - /// - public Guid UserId { get; set; } } diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs index 341638ce..e24d5aca 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiChatService.cs @@ -86,7 +86,7 @@ public class AiChatService : ApplicationService } /// - /// 获取模型列表 + /// 获取对话模型列表 /// /// public async Task> GetModelAsync() @@ -98,16 +98,9 @@ public class AiChatService : ApplicationService .Select(x => new ModelGetListOutput { Id = x.Id, - Category = "chat", ModelId = x.ModelId, ModelName = x.Name, ModelDescribe = x.Description, - ModelPrice = 0, - ModelType = "1", - ModelShow = "0", - SystemPrompt = null, - ApiHost = null, - ApiKey = null, Remark = x.Description, IsPremiumPackage = PremiumPackageConst.ModeIds.Contains(x.ModelId) }).ToListAsync(); @@ -202,7 +195,7 @@ public class AiChatService : ApplicationService [HttpPost("ai-chat/agent/send")] public async Task PostAgentSendAsync([FromBody] AgentSendInput input, CancellationToken cancellationToken) { - var tokenValidation = await _tokenManager.ValidateTokenAsync(input.Token, input.ModelId); + var tokenValidation = await _tokenManager.ValidateTokenAsync(input.TokenId, input.ModelId); await _aiBlacklistManager.VerifiyAiBlacklist(tokenValidation.UserId); // 验证用户是否为VIP @@ -232,7 +225,7 @@ public class AiChatService : ApplicationService await _chatManager.AgentCompleteChatStreamAsync(_httpContextAccessor.HttpContext, input.SessionId, input.Content, - input.Token, + tokenValidation.Token, tokenValidation.TokenId, input.ModelId, tokenValidation.UserId, diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiImageService.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiImageService.cs index 5bffa03d..59098622 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiImageService.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Application/Services/Chat/AiImageService.cs @@ -31,14 +31,14 @@ public class AiImageService : ApplicationService private readonly PremiumPackageManager _premiumPackageManager; private readonly IGuidGenerator _guidGenerator; private readonly IWebHostEnvironment _webHostEnvironment; - + private readonly TokenManager _tokenManager; public AiImageService( ISqlSugarRepository imageTaskRepository, IBackgroundJobManager backgroundJobManager, AiBlacklistManager aiBlacklistManager, PremiumPackageManager premiumPackageManager, IGuidGenerator guidGenerator, - IWebHostEnvironment webHostEnvironment) + IWebHostEnvironment webHostEnvironment, TokenManager tokenManager) { _imageTaskRepository = imageTaskRepository; _backgroundJobManager = backgroundJobManager; @@ -46,6 +46,7 @@ public class AiImageService : ApplicationService _premiumPackageManager = premiumPackageManager; _guidGenerator = guidGenerator; _webHostEnvironment = webHostEnvironment; + _tokenManager = tokenManager; } /// @@ -58,10 +59,17 @@ public class AiImageService : ApplicationService public async Task GenerateAsync([FromBody] ImageGenerationInput input) { var userId = CurrentUser.GetId(); - + // 黑名单校验 await _aiBlacklistManager.VerifiyAiBlacklist(userId); + //校验token + if (input.TokenId is not null) + { + await _tokenManager.ValidateTokenAsync(input.TokenId, input.ModelId); + } + + // VIP校验 if (!CurrentUser.IsAiVip()) { @@ -82,32 +90,21 @@ public class AiImageService : ApplicationService var task = new ImageStoreTaskAggregateRoot { Prompt = input.Prompt, - ReferenceImagesBase64 = input.ReferenceImagesBase64 ?? new List(), + ReferenceImagesPrefixBase64 = input.ReferenceImagesPrefixBase64 ?? new List(), ReferenceImagesUrl = new List(), TaskStatus = TaskStatusEnum.Processing, - UserId = userId + UserId = userId, + TokenId = input.TokenId }; await _imageTaskRepository.InsertAsync(task); - var taskId = task.Id; - - // 构建请求JSON - var requestJson = JsonSerializer.Serialize(new - { - prompt = input.Prompt, - referenceImages = input.ReferenceImagesBase64 - }); - // 入队后台任务 await _backgroundJobManager.EnqueueAsync(new ImageGenerationJobArgs { - TaskId = taskId, - ModelId = input.ModelId, - RequestJson = requestJson, - UserId = userId + TaskId = task.Id, }); - return taskId; + return task.Id; } /// @@ -130,9 +127,9 @@ public class AiImageService : ApplicationService { Id = task.Id, Prompt = task.Prompt, - ReferenceImagesBase64 = task.ReferenceImagesBase64, - ReferenceImagesUrl = task.ReferenceImagesUrl, - StoreBase64 = task.StoreBase64, + // ReferenceImagesBase64 = task.ReferenceImagesBase64, + // ReferenceImagesUrl = task.ReferenceImagesUrl, + // StoreBase64 = task.StoreBase64, StoreUrl = task.StoreUrl, TaskStatus = task.TaskStatus, CreationTime = task.CreationTime @@ -234,9 +231,9 @@ public class AiImageService : ApplicationService { Id = x.Id, Prompt = x.Prompt, - ReferenceImagesBase64 = x.ReferenceImagesBase64, - ReferenceImagesUrl = x.ReferenceImagesUrl, - StoreBase64 = x.StoreBase64, + // ReferenceImagesBase64 = x.ReferenceImagesBase64, + // ReferenceImagesUrl = x.ReferenceImagesUrl, + // StoreBase64 = x.StoreBase64, StoreUrl = x.StoreUrl, TaskStatus = x.TaskStatus, CreationTime = x.CreationTime diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs index d06eb1c2..c678013e 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Dtos/Gemini/GeminiGenerateContentAcquirer.cs @@ -36,10 +36,32 @@ public static class GeminiGenerateContentAcquirer /// /// /// - public static string GetImageBase64(JsonElement response) + public static string GetImagePrefixBase64(JsonElement response) { - //todo - //获取他的base64字符串 - return string.Empty; + // 获取 candidates[0].content.parts[0].text + var text = response.GetPath("candidates", 0, "content", "parts", 0, "text").GetString(); + if (string.IsNullOrEmpty(text)) + { + return string.Empty; + } + + // 解析 markdown 图片格式: ![image](data:image/png;base64,xxx) + // 提取括号内的 data:image/xxx;base64,xxx 部分 + var startMarker = "(data:image/"; + var startIndex = text.IndexOf(startMarker); + if (startIndex < 0) + { + return string.Empty; + } + + // 从 "data:" 开始 + startIndex += 1; // 跳过 "(" + var endIndex = text.IndexOf(')', startIndex); + if (endIndex < 0) + { + return string.Empty; + } + + return text.Substring(startIndex, endIndex - startIndex); } } \ No newline at end of file diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/PublishStatusEnum.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/PublishStatusEnum.cs new file mode 100644 index 00000000..45792255 --- /dev/null +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain.Shared/Enums/PublishStatusEnum.cs @@ -0,0 +1,17 @@ +namespace Yi.Framework.AiHub.Domain.Shared.Enums; + +/// +/// 发布状态枚举 +/// +public enum PublishStatusEnum +{ + /// + /// 未发布 + /// + Unpublished = 0, + + /// + /// 已发布 + /// + Published = 1 +} diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/ImageStoreTaskAggregateRoot.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/ImageStoreTaskAggregateRoot.cs index c23cdfa4..379333cd 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/ImageStoreTaskAggregateRoot.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Entities/Chat/ImageStoreTaskAggregateRoot.cs @@ -14,22 +14,22 @@ public class ImageStoreTaskAggregateRoot : FullAuditedAggregateRoot public string Prompt { get; set; } /// - /// 参考图Base64 + /// 参考图PrefixBase64(带前缀,如 data:image/png;base64,xxx) /// [SugarColumn(IsJson = true)] - public List ReferenceImagesBase64 { get; set; } + public List ReferenceImagesPrefixBase64 { get; set; } /// /// 参考图url /// [SugarColumn(IsJson = true)] public List ReferenceImagesUrl { get; set; } - - + + /// - /// 图片base64 + /// 生成图片PrefixBase64(带前缀,如 data:image/png;base64,xxx) /// - public string? StoreBase64 { get; set; } + public string? StorePrefixBase64 { get; set; } /// /// 图片绝对路径 @@ -46,6 +46,34 @@ public class ImageStoreTaskAggregateRoot : FullAuditedAggregateRoot /// public Guid UserId { get; set; } + /// + /// 模型id + /// + public string ModelId { get; set; } + + /// + /// 错误信息 + /// + [SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)] + public string? ErrorInfo { get; set; } + + /// + /// 发布状态 + /// + public PublishStatusEnum PublishStatus { get; set; } = PublishStatusEnum.Unpublished; + + /// + /// 分类标签 + /// + [SugarColumn(IsJson = true)] + public List Categories { get; set; } = new(); + + + /// + /// 密钥id + /// + public Guid? TokenId { get; set; } + /// /// 设置成功 /// diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs index 971fef75..22bc92a0 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/AiGateWayManager.cs @@ -984,11 +984,12 @@ public class AiGateWayManager : DomainService var data = await chatService.GenerateContentAsync(modelDescribe, request, cancellationToken); //解析json,获取base64字符串 - var imageBase64 = GeminiGenerateContentAcquirer.GetImageBase64(data); + var imageBase64 = GeminiGenerateContentAcquirer.GetImagePrefixBase64(data); //远程调用上传接口,将base64转换为URL var httpClient = LazyServiceProvider.LazyGetRequiredService().CreateClient(); - var uploadUrl = $"https://ccnetcore.com/prod-api/ai-hub/ai-image/upload-base64"; + // var uploadUrl = $"https://ccnetcore.com/prod-api/ai-hub/ai-image/upload-base64"; + var uploadUrl = $"http://localhost:19001/api/app/ai-image/upload-base64"; var content = new StringContent(JsonSerializer.Serialize(imageBase64), Encoding.UTF8, "application/json"); var uploadResponse = await httpClient.PostAsync(uploadUrl, content, cancellationToken); uploadResponse.EnsureSuccessStatusCode(); @@ -1020,7 +1021,7 @@ public class AiGateWayManager : DomainService } //设置存储base64和url - imageStoreTask.StoreBase64 = imageBase64; + imageStoreTask.StorePrefixBase64 = imageBase64; imageStoreTask.SetSuccess(storeUrl); await _imageStoreTaskRepository.UpdateAsync(imageStoreTask); } diff --git a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/TokenManager.cs b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/TokenManager.cs index dd2ae774..fc9ee5f7 100644 --- a/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/TokenManager.cs +++ b/Yi.Abp.Net8/module/ai-hub/Yi.Framework.AiHub.Domain/Managers/TokenManager.cs @@ -21,6 +21,11 @@ public class TokenValidationResult /// Token Id /// public Guid TokenId { get; set; } + + /// + /// token + /// + public string Token { get; set; } } public class TokenManager : DomainService @@ -39,25 +44,36 @@ public class TokenManager : DomainService /// /// 验证Token并返回用户Id和TokenId /// - /// Token密钥 + /// Token密钥或者TokenId /// 模型Id(用于判断是否是尊享模型需要检查额度) /// Token验证结果 - public async Task ValidateTokenAsync(string? token, string? modelId = null) + public async Task ValidateTokenAsync(object tokenOrId, string? modelId = null) { - if (token is null) + + if (tokenOrId is null) { throw new UserFriendlyException("当前请求未包含token", "401"); } - - if (!token.StartsWith("yi-")) + + TokenAggregateRoot entity; + if (tokenOrId is Guid tokenId) { - throw new UserFriendlyException("当前请求token非法", "401"); + entity = await _tokenRepository._DbQueryable + .Where(x => x.Id == tokenId) + .FirstAsync(); } - - var entity = await _tokenRepository._DbQueryable - .Where(x => x.Token == token) - .FirstAsync(); - + else + { + var tokenStr = tokenOrId.ToString(); + if (!tokenStr.StartsWith("yi-")) + { + throw new UserFriendlyException("当前请求token非法", "401"); + } + entity = await _tokenRepository._DbQueryable + .Where(x => x.Token == tokenStr) + .FirstAsync(); + } + if (entity is null) { throw new UserFriendlyException("当前请求token无效", "401"); @@ -90,7 +106,8 @@ public class TokenManager : DomainService return new TokenValidationResult { UserId = entity.UserId, - TokenId = entity.Id + TokenId = entity.Id, + Token = entity.Token }; }