using Betalgo.Ranul.OpenAI.ObjectModels.RealtimeModels; using LMS.Repository.MJPackage; using LMS.service.Extensions.Attributes; using LMS.service.Service.MJPackage; using LMS.Tools.MJPackage; using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using System.Text; using System.Text.Json; namespace LMS.service.Controllers { [Route("api/[controller]")] [ApiController] public class MJPackageController(TokenUsageTracker usageTracker, ITaskConcurrencyManager taskConcurrencyManager, ILogger logger, IMJPackageService mJPackageService, ITokenService tokenService) : ControllerBase { private readonly TokenUsageTracker _usageTracker = usageTracker; private readonly ILogger _logger = logger; private readonly ITaskConcurrencyManager _taskConcurrencyManager = taskConcurrencyManager; private readonly IMJPackageService _mJPackageService = mJPackageService; private readonly ITokenService _tokenService = tokenService; [HttpPost("mj/submit/imagine")] [RateLimit] public async Task Imagine([FromBody] MJSubmitImageModel model) { string token = (string)(HttpContext.Items["UseToken"] ?? string.Empty); string requestToken = (string)(HttpContext.Items["RequestToken"] ?? string.Empty); if (string.IsNullOrWhiteSpace(token)) { return Unauthorized("API token is empty"); } if (string.IsNullOrWhiteSpace(requestToken)) { return Unauthorized("API token is empty"); } using HttpClient client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer sk-" + token); model.NotifyHook = "https://lms.laitool.cn/api/MJPackage/mj/mj-notify-hook"; string body = JsonConvert.SerializeObject(model); client.Timeout = Timeout.InfiniteTimeSpan; string mjAPIBasicUrl = await _tokenService.GetMJAPIBasicUrl(); string mjUrl = $"{mjAPIBasicUrl}/mj/submit/imagine"; var response = await client.PostAsync(mjUrl, new StringContent(body, Encoding.UTF8, "application/json")); // 读取响应内容 string content = await response.Content.ReadAsStringAsync(); // 直接返回原始响应,包括状态码和内容 var res = new ContentResult { Content = content, ContentType = response.Content.Headers.ContentType?.ToString() ?? "application/json", StatusCode = (int)response.StatusCode }; // 判断请求任务的状态,判断是不是需要释放 if (res.StatusCode != 200 && res.StatusCode != 201) { // 标记释放 HttpContext.Items["ReleaseConcurrencyPermit"] = true; _logger.LogInformation($"请求失败,Token并发许可已释放: {token}, 状态码: {res.StatusCode}"); return res; } // 判断是不是提交成功,并且记录请求返回的ID // 把 Content 转换为 匿名 对象 var result = JsonConvert.DeserializeAnonymousType(content, new { code = 1, description = "提交成功", result = 1320098173412546 }); if (result == null || (result.code != 1 && result.code != 22)) { HttpContext.Items["ReleaseConcurrencyPermit"] = true; _logger.LogInformation($"业务逻辑失败,返回结果为空或者返回请求码不是 1 或 22, 标记释放Token并发许可: {token}"); return res; } // 开始写入任务 await _taskConcurrencyManager.CreateTaskAsync(requestToken, result.result.ToString()); return res; } [HttpGet("mj/task/{id}/fetch")] public async Task> Fetch(string id) { string token = HttpContext.Request.Headers.Authorization.ToString() .Replace("Bearer ", "", StringComparison.OrdinalIgnoreCase) .Trim(); var res = await _mJPackageService.FetchTaskAsync(id, token); return res; } [HttpPost("mj/mj-notify-hook")] //[Route("mjPackage/mj/mj-notify-hook")] public async Task MJNotifyHook([FromBody] JsonElement model) { return await _mJPackageService.MJNotifyHookAsync(model); } } }