338 lines
14 KiB
C#
338 lines
14 KiB
C#
using ChatMvc.Models;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Net.Http.Headers;
|
|
using System.Net.Http;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Newtonsoft.Json;
|
|
using Microsoft.AspNetCore.Antiforgery;
|
|
using Microsoft.AspNetCore.Authorization;
|
|
using System.Linq;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Chat.Domain.Tools;
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
namespace ChatMvc.Controllers
|
|
{
|
|
[Authorize]
|
|
public class ChatController : Controller
|
|
{
|
|
private readonly IHttpClientFactory _httpClientFactory;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly IAntiforgery _antiforgery;
|
|
|
|
public ChatController(IHttpClientFactory httpClientFactory, IConfiguration configuration, IAntiforgery antiforgery)
|
|
{
|
|
_httpClientFactory = httpClientFactory;
|
|
_configuration = configuration;
|
|
_antiforgery = antiforgery;
|
|
}
|
|
|
|
public IActionResult Index()
|
|
{
|
|
var tokens = _antiforgery.GetAndStoreTokens(HttpContext);
|
|
var token = HttpContext.GetTokenAsync("access_token").Result;
|
|
ViewBag.Token = token;
|
|
return View();
|
|
}
|
|
|
|
[HttpPost("chat/proxy-response")]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> ProxyResponse([FromForm] string sessionId, [FromForm] string message, [FromForm] IFormFile file1 = null, [FromForm] IFormFile file2 = null)
|
|
{
|
|
try
|
|
{
|
|
if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
|
|
{
|
|
return BadRequest("Requisição inválida");
|
|
}
|
|
|
|
var userId = User.Claims.FirstOrDefault(f => f.Type == "UserId")?.Value;
|
|
var name = User.Claims.FirstOrDefault(f => f.Type == "FirstName")?.Value;
|
|
var company = User.Claims.FirstOrDefault(f => f.Type == "CompanyName")?.Value;
|
|
var token = User.Claims.FirstOrDefault(f => f.Type == "TokenExternal")?.Value;
|
|
|
|
if (string.IsNullOrEmpty(token))
|
|
{
|
|
return BadRequest("Token não encontrado");
|
|
}
|
|
|
|
// Verificar se há arquivos e palavras-chave
|
|
var keyWords = new[] { "diferença", "diferenças", "comparação", "comparar", "compare" };
|
|
bool hasKeyword = keyWords.Any(k => message.ToLower().Contains(k.ToLower()));
|
|
bool hasBothFiles = file1 != null && file2 != null;
|
|
bool hasOneFile = file1 != null || file2 != null;
|
|
bool isPDF = file1 != null && file1.ContentType == "application/pdf" && file2 != null && file2.ContentType == "application/pdf";
|
|
bool isImage = file1 != null && file1.ContentType.Contains("image") && file2 != null && file2.ContentType.Contains("image");
|
|
|
|
// Se tem apenas um arquivo ou se tem arquivos mas não tem palavra-chave
|
|
if ((hasOneFile && !hasBothFiles) || (hasBothFiles && !hasKeyword))
|
|
{
|
|
return Ok("Por favor, especifique o que deseja fazer com os arquivos. " +
|
|
"Para comparar dois PDFs, inclua palavras como 'diferença' ou 'comparação' em sua mensagem.");
|
|
}
|
|
|
|
var client = _httpClientFactory.CreateClient();
|
|
client.DefaultRequestHeaders.Authorization =
|
|
new AuthenticationHeaderValue("Bearer", token.Replace("Bearer ", ""));
|
|
|
|
var baseUrl = _configuration["ExternalApiBaseUrl"];
|
|
|
|
if (hasBothFiles && hasKeyword && isPDF)
|
|
{
|
|
var content = await CompareFiles(baseUrl, sessionId, client, file1, file2);
|
|
return Ok(content);
|
|
}
|
|
else if (hasBothFiles && hasKeyword && isImage)
|
|
{
|
|
var content = await CompareFilesImage(baseUrl, sessionId, client, file1, file2);
|
|
return Ok(content);
|
|
}
|
|
|
|
var chatContent = new FormUrlEncodedContent(new[]
|
|
{
|
|
new KeyValuePair<string, string>("sessionId", sessionId),
|
|
new KeyValuePair<string, string>("message", message)
|
|
});
|
|
|
|
var response = await client.PostAsync($"{baseUrl}/chat/response", chatContent);
|
|
|
|
response.EnsureSuccessStatusCode();
|
|
var responseContent = await response.Content.ReadAsStringAsync();
|
|
|
|
return Ok(responseContent);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest($"Erro ao processar mensagem: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private async Task<string> CompareFiles(string? baseUrl, string sessionId, HttpClient? client, [FromForm] IFormFile? file1 = null, [FromForm] IFormFile? file2 = null)
|
|
{
|
|
// Primeiro, comparar os PDFs
|
|
var formData = new MultipartFormDataContent();
|
|
var content1 = new StreamContent(file1.OpenReadStream());
|
|
var content2 = new StreamContent(file2.OpenReadStream());
|
|
content1.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
|
|
content2.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
|
|
formData.Add(content1, "File1", file1.FileName);
|
|
formData.Add(content2, "File2", file2.FileName);
|
|
|
|
var comparisonResponse = await client.PostAsync(
|
|
"https://localhost:7200/api/PdfComparison/compare",
|
|
formData
|
|
);
|
|
|
|
if (!comparisonResponse.IsSuccessStatusCode)
|
|
{
|
|
throw new Exception("Erro ao comparar os PDFs");
|
|
}
|
|
|
|
var differences = await comparisonResponse.Content.ReadAsStringAsync();
|
|
var dynamicContent = JsonConvert.DeserializeObject<dynamic>(differences);
|
|
var formattedDifferences = FormatDifferencesForChat(dynamicContent);
|
|
|
|
var promptMessage = $"Ao comparar dois textos obtive as diferenças do json. Você poderia explicar e resumir: {formattedDifferences}";
|
|
|
|
var chatContentSend = new FormUrlEncodedContent(new[]
|
|
{
|
|
new KeyValuePair<string, string>("sessionId", sessionId),
|
|
new KeyValuePair<string, string>("message", promptMessage)
|
|
});
|
|
|
|
var chatResponse = await client.PostAsync($"{baseUrl}/chat/response-fromia", chatContentSend);
|
|
|
|
chatResponse.EnsureSuccessStatusCode();
|
|
var content = await chatResponse.Content.ReadAsStringAsync();
|
|
|
|
return content;
|
|
}
|
|
|
|
private async Task<string> CompareFilesImage(string? baseUrl, string sessionId, HttpClient? client, [FromForm] IFormFile? file1 = null, [FromForm] IFormFile? file2 = null)
|
|
{
|
|
var formData = new MultipartFormDataContent();
|
|
var content1 = new StreamContent(file1.OpenReadStream());
|
|
var content2 = new StreamContent(file2.OpenReadStream());
|
|
content1.Headers.ContentType = new MediaTypeHeaderValue(file1.ContentType);
|
|
content2.Headers.ContentType = new MediaTypeHeaderValue(file2.ContentType);
|
|
formData.Add(content1, "Drawing1", file1.FileName);
|
|
formData.Add(content2, "Drawing2", file2.FileName);
|
|
|
|
var comparisonResponse = await client.PostAsync(
|
|
"https://localhost:7200/api/TechnicalDrawing/compare-images",
|
|
formData
|
|
);
|
|
|
|
if (!comparisonResponse.IsSuccessStatusCode)
|
|
{
|
|
throw new Exception("Erro ao comparar os PDFs");
|
|
}
|
|
|
|
var differences = await comparisonResponse.Content.ReadAsStringAsync();
|
|
JObject obj = JObject.Parse(differences);
|
|
string image = obj["image"].ToString();
|
|
|
|
var file3 = Base64ToFormFile.ConvertBase64ToFormFile(image, "compared.png");
|
|
|
|
var promptMessage = $"Ao comparar dois desenhos técnicos, obtive as diferenças entre eles. Você precisa explicar e resumir estas diferenças ressaltando mudanças em medidas da peça. O arquivo ";
|
|
|
|
var response = "";
|
|
using (formData = AddFormDataToResponse(sessionId, promptMessage, file1, file2, file3))
|
|
{
|
|
var chatResponse = await client.PostAsync($"{baseUrl}/chat/response-fromia", formData);
|
|
chatResponse.EnsureSuccessStatusCode();
|
|
response = await chatResponse.Content.ReadAsStringAsync();
|
|
}
|
|
return response;
|
|
}
|
|
|
|
private MultipartFormDataContent AddFormDataToResponse(string sessionId, string message, IFormFile? file1 = null, IFormFile? file2 = null, IFormFile? file3 = null)
|
|
{
|
|
var formData = new MultipartFormDataContent();
|
|
formData.Add(new StringContent(sessionId), "SessionId");
|
|
formData.Add(new StringContent(message), "Message");
|
|
|
|
if (file1 != null)
|
|
{
|
|
var streamContent1 = new StreamContent(file1.OpenReadStream());
|
|
formData.Add(streamContent1, "File1", file1.FileName);
|
|
}
|
|
|
|
if (file2 != null)
|
|
{
|
|
var streamContent2 = new StreamContent(file2.OpenReadStream());
|
|
formData.Add(streamContent2, "File2", file2.FileName);
|
|
}
|
|
|
|
if (file3 != null)
|
|
{
|
|
var streamContent3 = new StreamContent(file3.OpenReadStream());
|
|
formData.Add(streamContent3, "File3", file3.FileName);
|
|
}
|
|
|
|
return formData;
|
|
}
|
|
|
|
[HttpPost("chat/authenticate")]
|
|
[ValidateAntiForgeryToken]
|
|
public async Task<IActionResult> Authenticate([FromBody] AuthenticateRequest request)
|
|
{
|
|
try
|
|
{
|
|
if (!Request.Headers["X-Requested-With"].Equals("XMLHttpRequest"))
|
|
{
|
|
return BadRequest("Requisição inválida");
|
|
}
|
|
|
|
var client = _httpClientFactory.CreateClient();
|
|
var baseUrl = _configuration["ExternalApiBaseUrl"];
|
|
|
|
// Primeira requisição - newclient
|
|
var newClientRequest = new
|
|
{
|
|
localId = request.UserId,
|
|
companyTenant = request.Company,
|
|
name = request.Name
|
|
};
|
|
|
|
var newClientResponse = await client.PostAsync(
|
|
$"{baseUrl}/login/newclient",
|
|
new StringContent(JsonConvert.SerializeObject(newClientRequest),
|
|
Encoding.UTF8, "application/json"));
|
|
|
|
newClientResponse.EnsureSuccessStatusCode();
|
|
var clientContent = await newClientResponse.Content.ReadAsStringAsync();
|
|
var clientResult = JsonConvert.DeserializeObject<NewClientResponse>(clientContent);
|
|
|
|
// Segunda requisição - token
|
|
var tokenRequest = new
|
|
{
|
|
clientId = request.UserId,
|
|
clientName = request.Name,
|
|
clientSecret = clientResult.Secret
|
|
};
|
|
|
|
var tokenResponse = await client.PostAsync(
|
|
$"{baseUrl}/login/token",
|
|
new StringContent(JsonConvert.SerializeObject(tokenRequest),
|
|
Encoding.UTF8, "application/json"));
|
|
|
|
tokenResponse.EnsureSuccessStatusCode();
|
|
var tokenContent = await tokenResponse.Content.ReadAsStringAsync();
|
|
var tokenResult = JsonConvert.DeserializeObject<TokenResponse>(tokenContent);
|
|
|
|
return Ok(new { token = tokenResult.Token });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return BadRequest($"Erro na autenticação: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private string FormatDifferencesForChat(dynamic jsonDifferences)
|
|
{
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("Análise das diferenças entre os documentos:");
|
|
sb.AppendLine();
|
|
|
|
try
|
|
{
|
|
// Focar apenas nas diferenças reais (onlyDifferences)
|
|
var onlyDiffs = jsonDifferences.onlyDifferences;
|
|
|
|
if (onlyDiffs != null && onlyDiffs.Count > 0)
|
|
{
|
|
foreach (var diff in onlyDiffs)
|
|
{
|
|
string content = diff.content?.ToString() ?? "";
|
|
string type = diff.typeName?.ToString() ?? "";
|
|
int lineNumber = diff.lineNumber;
|
|
|
|
switch (type)
|
|
{
|
|
case "Deleted":
|
|
sb.AppendLine($"Removido (linha {lineNumber}):");
|
|
sb.AppendLine($"- {content}");
|
|
break;
|
|
case "Inserted":
|
|
sb.AppendLine($"Adicionado (linha {lineNumber}):");
|
|
sb.AppendLine($"+ {content}");
|
|
break;
|
|
}
|
|
sb.AppendLine();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.AppendLine("Nenhuma diferença significativa encontrada entre os documentos.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
sb.AppendLine("Erro ao processar diferenças. Resumo simplificado:");
|
|
sb.AppendLine("As diferenças entre os documentos não puderam ser formatadas adequadamente.");
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
|
|
public class AuthenticateRequest
|
|
{
|
|
public string UserId { get; set; }
|
|
public string Company { get; set; }
|
|
public string Name { get; set; }
|
|
}
|
|
|
|
public class NewClientResponse
|
|
{
|
|
public string Secret { get; set; }
|
|
}
|
|
|
|
public class TokenResponse
|
|
{
|
|
public string Token { get; set; }
|
|
}
|
|
}
|