2026-06-24 15:06:40 +08:00
|
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.IService;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Dto;
|
|
|
|
|
|
using QYZH.InteractiveMagazine.Models.Enum;
|
2026-06-24 18:25:25 +08:00
|
|
|
|
using System.Text.Json;
|
2026-06-24 15:06:40 +08:00
|
|
|
|
|
|
|
|
|
|
namespace QYZH.InteractiveMagazine.WebApi.Controllers;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// AI聊天控制器
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Route("api/[controller]")]
|
|
|
|
|
|
[ApiController]
|
|
|
|
|
|
[ApiExplorerSettings(GroupName = nameof(ApiVersionEnum.Platform))]
|
|
|
|
|
|
public class AiChatController : BaseController
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly IAiChatService _aiChatService;
|
|
|
|
|
|
private readonly ILogger<AiChatController> _logger;
|
|
|
|
|
|
|
|
|
|
|
|
public AiChatController(IAiChatService aiChatService, ILogger<AiChatController> logger)
|
|
|
|
|
|
{
|
|
|
|
|
|
_aiChatService = aiChatService;
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2026-06-24 18:25:25 +08:00
|
|
|
|
/// AI聊天(流式返回),根据需求生成提示词
|
2026-06-24 15:06:40 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="input">用户需求消息</param>
|
2026-06-24 18:25:25 +08:00
|
|
|
|
/// <returns>SSE流,逐块返回AI生成的提示词内容</returns>
|
2026-06-24 15:06:40 +08:00
|
|
|
|
[HttpPost]
|
2026-06-24 18:25:25 +08:00
|
|
|
|
public async Task ChatAsync([FromBody] AiChatInput input)
|
2026-06-24 15:06:40 +08:00
|
|
|
|
{
|
2026-06-24 18:25:25 +08:00
|
|
|
|
Response.ContentType = "text/event-stream";
|
|
|
|
|
|
Response.Headers.Append("Cache-Control", "no-cache");
|
|
|
|
|
|
Response.Headers.Append("Connection", "keep-alive");
|
|
|
|
|
|
|
2026-06-24 15:06:40 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2026-06-24 18:25:25 +08:00
|
|
|
|
await foreach (var chunk in _aiChatService.ChatAsync(input, HttpContext.RequestAborted))
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = JsonSerializer.Serialize(new { content = chunk });
|
|
|
|
|
|
await Response.WriteAsync($"data: {data}\n\n");
|
|
|
|
|
|
await Response.Body.FlushAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await Response.WriteAsync("data: [DONE]\n\n");
|
|
|
|
|
|
await Response.Body.FlushAsync();
|
2026-06-24 15:06:40 +08:00
|
|
|
|
}
|
2026-06-24 18:25:25 +08:00
|
|
|
|
catch (OperationCanceledException)
|
2026-06-24 15:06:40 +08:00
|
|
|
|
{
|
2026-06-24 18:25:25 +08:00
|
|
|
|
_logger.LogInformation("客户端断开连接,AI聊天流式返回终止");
|
2026-06-24 15:06:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
2026-06-24 18:25:25 +08:00
|
|
|
|
_logger.LogError(ex, "AI聊天流式返回异常,参数:{Input}", input);
|
|
|
|
|
|
var errorData = JsonSerializer.Serialize(new { error = "AI聊天失败,请稍后重试" });
|
|
|
|
|
|
await Response.WriteAsync($"data: {errorData}\n\n");
|
|
|
|
|
|
await Response.Body.FlushAsync();
|
2026-06-24 15:06:40 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|