2025-12-22 16:47:15 +08:00

151 lines
5.0 KiB
C#

using CrazyStudio.Core.Common;
using CrazyStudio.Core.Common.AliyunExt.Oss.Tools;
using CrazyStudio.Core.Common.Eitities;
using CrazyStudio.Core.Common.Tools;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Identity.Client;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using System.Threading.Tasks;
using TouchSocket.Core;
using XPrintServer.Api.Dto;
using XPrintServer.Api.Entities;
using XPrintServer.Api.Tools;
using XPrintServer.Business.Services;
using XPrintServer.Business.Workflows;
using XPrintServer.DataModel;
using XPrintServer.DataModel.Models;
using File = System.IO.File;
namespace XPrintServer.Api.Controllers.Ai
{
[Route("api/[controller]/[action]")]
[ApiController]
public class ComfyController : ControllerBase
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly AliyunInfos _aliyunInfos;
private readonly OssTool _ossTool;
private readonly ComfyUIService _compyUIService;
private static ConcurrentDictionary<string, string> _tmpInputPath = new ConcurrentDictionary<string, string>();
public ComfyController(ComfyUIService compyUIService, IHttpContextAccessor httpContextAccessor, AliyunInfos aliyunInfos, OssTool ossTool)
{
_aliyunInfos = aliyunInfos;
_ossTool = ossTool;
_httpContextAccessor = httpContextAccessor;
_compyUIService = compyUIService;
}
[HttpPost]
public async Task<string> GenerationImage([FromBody] PromptRequestInfo requestInfo)
{
return string.Empty;
string promptId = await _compyUIService.QwenWorkflow.GenerateImageAsync(requestInfo.Prompt, "", long.Parse(requestInfo.Seed), requestInfo.Width, requestInfo.Height);
return promptId;
}
[HttpPost]
public async Task<ActionResult<string?>> SplitImage([FromBody] RequestImage requestInfo)
{
byte[]? bytes = await HttpTool.GetBytes(requestInfo.Url);
try
{
_ossTool.DeleteObject(_aliyunInfos.Oss.Bucket, requestInfo.ObjectName);
}
catch (Exception)
{
}
if (bytes == null)
{
return StatusCode(404);
}
string tempFileName = Guid.NewGuid().ToString() + Path.GetExtension(requestInfo.Url);
string tempFilePath = Path.Combine(Workflow.InputTempPath, tempFileName);
System.IO.File.WriteAllBytes(tempFilePath, bytes);
string promptId = await _compyUIService.SplitImageWorkflow.GenerateImageAsync(tempFileName);
if (string.IsNullOrWhiteSpace(promptId))
{
if (System.IO.File.Exists(tempFilePath))
{
System.IO.File.Delete(tempFilePath);
}
}
else
{
_tmpInputPath[promptId] = tempFilePath;
}
return promptId;
}
private void DeleteTempInputFile(string promptId)
{
if (_tmpInputPath.TryRemove(promptId, out string? tempInputPath))
{
if (!string.IsNullOrWhiteSpace(tempInputPath))
{
if (System.IO.File.Exists(tempInputPath))
{
System.IO.File.Delete(tempInputPath);
}
}
}
}
[HttpPost]
public async Task<ActionResult<ImageRequestResult>?> GetGenerationResult([FromBody] RequestTaskPrompt requestInfo)
{
string result = string.Empty;
try
{
result = await _compyUIService.GetGenerationResult(requestInfo.WorkflowType, requestInfo.PromptId);
}
catch (Exception)
{
DeleteTempInputFile(requestInfo.PromptId);
}
if (!string.IsNullOrWhiteSpace(result) && System.IO.File.Exists(result))
{
DeleteTempInputFile(requestInfo.PromptId);
byte[] bytes = System.IO.File.ReadAllBytes(result);
if (System.IO.File.Exists(result))
{
System.IO.File.Delete(result);
}
string ext = Path.GetExtension(result);
var objectName = $"cache/image/{Guid.NewGuid().ToString("N")}{ext}";
using (var mem = new MemoryStream(bytes!))
{
_ossTool.PutObject(_aliyunInfos.Oss.Bucket, objectName, mem, DateTime.UtcNow.AddDays(7));
}
string url = $"https://{_aliyunInfos.Oss.Bucket}.{_aliyunInfos.Oss.Region.Replace("-internal", "")}.aliyuncs.com/{objectName}";
return new ImageRequestResult
{
ImageUrl = url,
ObjectName = objectName,
};
}
return null;
}
}
}