using Dpz.Core.Service.Network.Models;
using Dpz.Core.Web.Pager;
namespace Dpz.Core.Web.Controllers;
[CheckAuthorize]
public class AiChatController(IAiChatService aiChatService, ILogger<AiChatController> logger)
: Controller
{
public async Task<IActionResult> Index()
{
// 获取用户的会话列表
var sessions = await aiChatService.GetSessionListAsync(User.RequiredUserId);
IPagedList<VmAiChatRecord> records = PagedList<VmAiChatRecord>.Empty();
string? defaultSessionId = null;
AiModel? aiModel = null;
// 第一个会话作为默认会话
if (sessions.Count > 0)
{
defaultSessionId = sessions[0].SessionId;
records = await aiChatService.GetSessionMessagesAsync(defaultSessionId, 1, 500);
if (Enum.TryParse(sessions[0].ModelType, out AiModel modelType))
{
aiModel = modelType;
}
}
var model = new AiChatModel(
sessions,
defaultSessionId,
aiModel ?? AiModel.Gpt5Mini,
records
);
return View(model);
}
/// <summary>
/// 获取会话列表
/// </summary>
[HttpGet]
public async Task<IActionResult> Sessions()
{
var sessions = await aiChatService.GetSessionListAsync(User.RequiredUserId);
return Json(new ResultInfo(true, sessions));
}
/// <summary>
/// 删除会话
/// </summary>
[HttpDelete]
public async Task<IActionResult> DeleteSession(string sessionId)
{
var result = await aiChatService.DeleteSessionAsync(User.RequiredUserId, sessionId);
return Json(new ResultInfo(result));
}
[HttpGet]
public async Task<IActionResult> ChatMessages(
string? sessionId,
int pageIndex = 1,
int pageSize = 500
)
{
if (string.IsNullOrEmpty(sessionId))
{
return PartialView(
"_ChatMessages",
new AiChatMessageModel(null, AiModel.Gpt5Mini, PagedList<VmAiChatRecord>.Empty())
);
}
var session = await aiChatService.GetSessionAsync(User.RequiredUserId, sessionId);
if (session == null)
{
return NotFound();
}
var messages = await aiChatService.GetSessionMessagesAsync(sessionId, pageIndex, pageSize);
AiModel? aiModel = null;
if (Enum.TryParse(session.ModelType, out AiModel modelType))
{
aiModel = modelType;
}
var model = new AiChatMessageModel(sessionId, aiModel ?? AiModel.Gpt5Mini, messages);
return PartialView("_ChatMessages", model);
}
/// <summary>
/// 更新会话名称
/// </summary>
[HttpPut]
public async Task<IActionResult> UpdateSessionName(string sessionId, string newName)
{
var result = await aiChatService.UpdateSessionNameAsync(
User.RequiredUserId,
sessionId,
newName
);
return Json(new ResultInfo(result));
}
/// <summary>
/// 获取会话详情
/// </summary>
[HttpGet]
public async Task<IActionResult> GetSessionModelType(string sessionId)
{
var session = await aiChatService.GetSessionAsync(User.RequiredUserId, sessionId);
if (session == null)
{
return Json(ResultInfo.ToFail("会话不存在"));
}
if (!Enum.TryParse(session.ModelType, out AiModel modelType))
{
modelType = AiModel.Gpt5Mini;
}
return Json(new ResultInfo(true, (int)modelType));
}
/// <summary>
/// 更新会话模型
/// </summary>
[HttpPut]
public async Task<IActionResult> UpdateSessionModelType(string sessionId, AiModel modelType)
{
// 更新会话的模型类型
var updated = await aiChatService.UpdateSessionModelTypeAsync(
User.RequiredUserId,
sessionId,
modelType.ToString()
);
logger.LogInformation(
"Updated model type to {ModelValue} for session {SessionId}",
modelType,
sessionId
);
return Json(new ResultInfo(updated));
}
[HttpPost]
public async Task<IActionResult> CancelMessage(
[FromQuery] string? sessionId = null,
[FromQuery] string? connectionId = null
)
{
if (string.IsNullOrWhiteSpace(sessionId))
{
logger.LogWarning("Session id is null or empty");
return BadRequest("Session id is null or empty");
}
if (string.IsNullOrWhiteSpace(connectionId))
{
logger.LogWarning("connection id null or empty");
return BadRequest("connection id null or empty");
}
// 精确取消指定会话的流
var tokenKey = $"{sessionId}_{connectionId}";
if (WebToolsExtensions.CancellationTokens.TryRemove(tokenKey, out var cts))
{
try
{
await cts.CancelAsync();
logger.LogInformation(
"Stream message cancellation requested and executed, Token Key: {TokenKey}",
tokenKey
);
return Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "Error cancelling stream, Token Key: {TokenKey}", tokenKey);
return BadRequest(ex.Message);
}
finally
{
cts.Dispose();
}
}
logger.LogWarning(
"No active stream found for cancellation, Token Key: {TokenKey}",
tokenKey
);
return BadRequest($"No active stream found for cancellation, Token Key: {tokenKey}");
}
/// <summary>
/// 删除消息
/// </summary>
/// <param name="messageId"></param>
/// <returns></returns>
[HttpDelete]
public async Task<IActionResult> DeleteMessage(string messageId)
{
var result = await aiChatService.DeleteMessageAsync(messageId, User.RequiredUserId);
if (result.Success)
{
return Json(new ResultInfo(true));
}
return Json(new ResultInfo(false, result.Message));
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
AiChatController 功能解析
这个控制器是一个 ASP.NET Core MVC 控制器,用于处理与AI聊天相关的各种操作。以下是其主要功能:
主要功能概述
会话管理:
- 获取会话列表
- 删除会话
- 更新会话名称
- 获取和更新会话使用的AI模型类型
消息管理:
- 获取聊天消息记录
- 删除单条消息
- 取消正在进行的消息流
视图渲染:
- 主页面视图
- 聊天消息部分视图
详细功能说明
1. 主页面 (Index)
- 获取用户的所有聊天会话列表
- 默认显示第一个会话的消息记录
- 设置默认的AI模型类型(默认为Gpt5Mini)
- 返回包含会话列表、默认会话ID、AI模型和消息记录的视图模型
2. 会话相关操作
- Sessions: 获取当前用户的所有会话列表(JSON格式)
- DeleteSession: 删除指定会话
- UpdateSessionName: 更新会话名称
- GetSessionModelType: 获取会话使用的AI模型类型
- UpdateSessionModelType: 更新会话使用的AI模型类型
3. 消息相关操作
- ChatMessages: 获取指定会话的消息记录(分页显示)
- DeleteMessage: 删除单条消息
- CancelMessage: 取消正在进行的消息流(通过取消令牌实现)
4. 其他特性
- 控制器使用
[CheckAuthorize]属性,表示所有操作都需要授权 - 使用依赖注入获取
IAiChatService和ILogger服务 - 包含详细的日志记录,便于调试和问题追踪
- 使用强类型视图模型传递数据到视图
- 部分操作返回JSON格式的结果(如会话列表、操作结果等)
技术特点
- 异步编程:所有方法都是异步的,使用
async/await模式 - 分页处理:使用
IPagedList处理消息记录的分页 - 强类型模型:使用特定的视图模型(如
AiChatModel,AiChatMessageModel) - 错误处理:通过日志记录和返回适当的HTTP状态码处理错误
- RESTful风格:使用适当的HTTP方法(GET, POST, PUT, DELETE)
这个控制器为前端提供了一个完整的API接口,用于管理AI聊天会话和消息。
评论加载中...