HuanMengProject/src/0-core/HuanMeng.MiaoYu.Code/Chat/ChatBLL.cs
2024-07-17 15:59:59 +08:00

370 lines
15 KiB
C#

using HuanMeng.DotNetCore.Base;
using HuanMeng.MiaoYu.Code.Cache;
using HuanMeng.MiaoYu.Code.Chat.Claude;
using HuanMeng.MiaoYu.Code.Chat.Claude.Model;
using HuanMeng.MiaoYu.Code.Chat.Contract;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.Dto.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.Chat;
using HuanMeng.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Chat
{
/// <summary>
/// 聊天类
/// </summary>
public class ChatBLL : MiaoYuBase
{
public ChatBLL(IServiceProvider serviceProvider) : base(serviceProvider)
{
}
/// <summary>
/// 获取用户和角色的聊天记录
/// </summary>
/// <param name="characterId"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public async Task<BaseResponse<List<ChatMessageDto>>> GetChatMessage(int characterId)
{
var charact = MiaoYuCache.CharacterList.FirstOrDefault(it => it.Id == characterId);
if (charact == null)
{
throw new ArgumentException("角色不存在");
}
var list = new List<ChatMessageDto>();
ChatMessageDto chatMessageDto2 = new ChatMessageDto()
{
ClaudeType = ChatMessageType.text.ToString(),
Content = charact.Biography ?? "",
Role = ChatRole.profile.ToString(),
Timestamp = DateTime.Now,
UserIcon = "",
Id = 0
};
list.Add(chatMessageDto2);
if (_UserId == 0)
{
var chat = new ChatMessageDto()
{
Id = 0,
Role = ChatRole.assistant.ToString(),
ClaudeType = "text",
Content = charact.Prologue,
Timestamp = DateTime.Now,
UserIcon = charact.IconImage
};
list.Add(chat);
return new BaseResponse<List<ChatMessageDto>>(ResonseCode.Success, "", list);
}
//if(timeStamp.)
var userChatSession = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.CharacterId == characterId && it.UserId == _UserId && !it.IsDelete).FirstOrDefaultAsync();
if (userChatSession == null)
{
userChatSession = new T_User_Chat()
{
SessionId = Guid.NewGuid(),
CharacterId = characterId,
CreateAt = DateTime.Now,
IsDelete = false,
SessionName = "新会话",
UpdateAt = DateTime.Now,
ModelConfigId = charact.ModelConfigId,
TenantId = charact.TenantId,
UserId = _UserId,
};
Dao.daoDbMiaoYu.context.T_User_Chat.Add(userChatSession);
Dao.daoDbMiaoYu.context.SaveChanges();
}
var chatList = await Dao.daoDbMiaoYu.context.T_Chat.Where(it => it.SessionId == userChatSession.SessionId && it.UserId == _UserId && it.Type == (int)ChatType.).OrderByDescending(it => it.SendMessageDay).ToListAsync();
if (chatList == null || chatList.Count == 0)
{
//添加第一句
var chat = new T_Chat()
{
Role = ChatRole.initialization.ToString(),
CharacterId = characterId,
ClaudeId = "",
ClaudeType = "text",
CreateTime = DateTime.Now,
Content = charact.Prologue,
Input_tokens = 0,
Output_tokens = 0,
SendDateDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
TimeStamp = DateTime.Now,//DateTimeExtensions.ToUnixTimestamp(),.ToUnixTimestamp()
SendMessageDay = DateTime.Now.ToUnixTimestamp(),
SessionId = userChatSession.SessionId,
TenantId = userChatSession.TenantId,
Type = 0,
UpdateTime = DateTime.Now,
UserId = userChatSession.UserId,
ClaudeModel = ""
};
Dao.daoDbMiaoYu.context.T_Chat.Add(chat);
Dao.daoDbMiaoYu.context.SaveChanges();
chatList = new List<T_Chat>();
chatList.Add(chat);
}
var message = Mapper.Map<List<ChatMessageDto>>(chatList);
//设置头像
message.Where(it =>
it.Role == ChatRole.assistant.ToString() ||
it.Role == ChatRole.initialization.ToString()
).ToList()
.ForEach(it => it.UserIcon = charact.IconImage);
//用户头像
var userData = await Dao.daoDbMiaoYu.context.T_User_Data.FirstOrDefaultAsync(it => it.UserId == _UserId);
var userIconUrl = userData?.UserIconUrl ?? "";
message.Where(it => it.Role == ChatRole.user.ToString()).ToList().ForEach(it => it.UserIcon = userIconUrl);
//将第一句修改角色
var initia = message.FirstOrDefault(it => it.Role == ChatRole.initialization.ToString());
if (initia != null)
{
initia.Role = ChatRole.assistant.ToString();
}
message.Insert(0, chatMessageDto2);
return new BaseResponse<List<ChatMessageDto>>(ResonseCode.Success, "", message);
}
/// <summary>
/// 发送消息接口
/// </summary>
/// <param name="characterId">角色Id</param>
/// <param name="message">消息内容</param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
public async Task<BaseResponse<ChatMessageDataDto>> Message(int characterId, string message)
{
ChatMessageDataDto chatListDto = new ChatMessageDataDto();
List<ChatMessageDto> chatMessageDtos = new List<ChatMessageDto>();
var charact = MiaoYuCache.CharacterList.FirstOrDefault(it => it.Id == characterId);
if (charact == null)
{
throw new ArgumentException("角色不存在");
}
if (_UserId == 0)
{
var chatMessage = new ChatMessageDto()
{
Id = 0,
Role = ChatRole.assistant.ToString(),
ClaudeType = "text",
Content = charact.Prologue,
Timestamp = DateTime.Now,
UserIcon = charact.IconImage
};
chatMessageDtos.Add(chatMessage);
chatListDto.ChatList = chatMessageDtos;
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
//if(timeStamp.)
var userChatSession = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.CharacterId == characterId && it.UserId == _UserId && !it.IsDelete).FirstOrDefaultAsync();
if (userChatSession == null)
{
userChatSession = new T_User_Chat()
{
SessionId = Guid.NewGuid(),
CharacterId = characterId,
CreateAt = DateTime.Now,
IsDelete = false,
SessionName = "新会话",
UpdateAt = DateTime.Now,
ModelConfigId = charact.ModelConfigId,
TenantId = charact.TenantId,
UserId = _UserId,
};
Dao.daoDbMiaoYu.context.T_User_Chat.Add(userChatSession);
Dao.daoDbMiaoYu.context.SaveChanges();
}
var role = new List<string>();
role.Add(ChatRole.assistant.ToString());
role.Add(ChatRole.user.ToString());
var chatList = await Dao.daoDbMiaoYu.context.T_Chat.Where(it => it.SessionId == userChatSession.SessionId && it.UserId == _UserId && role.Contains(it.Role)).OrderBy(it => it.SendMessageDay).ToListAsync();
if (chatList == null)
{
chatList = new List<T_Chat>();
}
List<ClaudeChatMessage> mess = new List<ClaudeChatMessage>();
for (int i = 0; i < chatList.Count; i++)
{
mess.Add(new ClaudeChatMessage
{
Role = chatList[i].Role,
Content = chatList[i].Content,
});
}
mess.Add(new ClaudeChatMessage
{
Role = ChatRole.user.ToString(),
Content = message,
});
#region
T_Chat t_Chat1 = new T_Chat
{
CharacterId = charact.Id,
ClaudeModel = "",
ClaudeId = "",
ClaudeType = "text",
Content = message,
CreateTime = DateTime.Now,
Input_tokens = 0,
Output_tokens = 0,
Role = ChatRole.user.ToString(),
SendDateDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
SendMessageDay = DateTime.Now.ToUnixTimestamp(),
SessionId = userChatSession.SessionId,
TenantId = userChatSession.TenantId,
TimeStamp = DateTime.Now,
Type = 0,
UpdateTime = DateTime.Now,
UserId = _UserId,
};
#endregion
#region api
ClaudeChatChatParams baseChatParams = new ClaudeChatChatParams();
baseChatParams.Messages = mess.ToArray();
baseChatParams.System = charact.System ?? "";
baseChatParams.MaxTokens = charact.ModelConfig.MaxTokens;
var claude = charact.ModelConfig.GetClaudeChatConfig();
IChat chat = new ClaudeChat(claude, HttpClientFactory);
var response = await chat.MessagesAsync(baseChatParams);
var claudeChatResponse = response as ClaudeChatResponse;
#endregion
T_Chat t_Chat = new T_Chat
{
CharacterId = charact.Id,
ClaudeModel = claudeChatResponse.Model,
ClaudeId = claudeChatResponse.Id,
ClaudeType = claudeChatResponse.Content[0]?.Type,
Content = claudeChatResponse.Content[0]?.Text,
CreateTime = DateTime.Now,
Input_tokens = claudeChatResponse.Usage.InputTokens,
Output_tokens = claudeChatResponse.Usage.OutputTokens,
Role = claudeChatResponse.Role,
SendDateDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
SendMessageDay = DateTime.Now.ToUnixTimestamp(),
SessionId = userChatSession.SessionId,
TenantId = userChatSession.TenantId,
TimeStamp = DateTime.Now,
Type = 0,
UpdateTime = DateTime.Now,
UserId = _UserId,
};
Dao.daoDbMiaoYu.context.Add(t_Chat1);
Dao.daoDbMiaoYu.context.Add(t_Chat);
userChatSession.UpdateAt = DateTime.Now;
await Dao.daoDbMiaoYu.context.SaveChangesAsync();
//claudeChatResponse.
ChatMessageDto chatMessageDto = new ChatMessageDto()
{
ClaudeType = ChatMessageType.text.ToString(),
Content = claudeChatResponse.Content[0].Text,
Role = ChatRole.assistant.ToString(),
Timestamp = DateTime.Now,
UserIcon = charact.IconImage,
Id = t_Chat.Id
};
chatMessageDtos.Add(chatMessageDto);
ChatMessageDto chatMessageDto1 = new ChatMessageDto()
{
ClaudeType = ChatMessageType.text.ToString(),
Content = "您还剩余1次聊天次数",
Role = ChatRole.tips.ToString(),
Timestamp = DateTime.Now,
UserIcon = "",
Id = t_Chat.Id
};
chatMessageDtos.Add(chatMessageDto1);
chatListDto.ChatList = chatMessageDtos;
chatListDto.LastMessageId = t_Chat1.Id;
chatListDto.RemainingChatCount = 1;
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
/// <summary>
/// 删除聊天记录
/// </summary>
/// <param name="id">聊天id</param>
/// <param name="characterId"></param>
/// <returns></returns>
public async Task<bool> DelChatByIds(List<int> id, int characterId)
{
var chatsToDelete = await Dao.daoDbMiaoYu.context.T_Chat.Where(t => id.Contains(t.Id)).ToListAsync();
if (chatsToDelete.Count <= 0)
{
throw new Exception("删除失败");
}
var chatList = chatsToDelete.Where(t => t.UserId == _UserId && t.CharacterId == characterId && (t.Type == (int)ChatType. || t.Type == (int)ChatType.)).ToList();
if (chatList.Count > 0)
{
chatList.ForEach(t => t.Type = 2);
}
Dao.daoDbMiaoYu.context.SaveChanges();
return true;
}
/// <summary>
/// 清空聊天记录
/// </summary>
/// <param name="characterId"></param>
/// <returns></returns>
public async Task<bool> DelChat(int characterId)
{
var tempList = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(t => t.UserId == _UserId && t.CharacterId == characterId && t.IsDelete == false).FirstOrDefaultAsync();
if (tempList != null)
{
tempList.IsDelete = true;
}
Dao.daoDbMiaoYu.context.SaveChanges();
return true;
}
/// <summary>
/// 获取消息聊天记录列表
/// </summary>
/// <returns></returns>
public async Task<BaseResponse<List<ChatHistoryInfo>>> GetChatHistoryList()
{
var userChatSessions = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.UserId == _UserId && !it.IsDelete).ToListAsync();
List<ChatHistoryInfo> chatHistoryInfos = new List<ChatHistoryInfo>();
var charactersIds = MiaoYuCache.CharacterList.ToList();
userChatSessions.ForEach(it =>
{
var model = charactersIds.FirstOrDefault(item => item.Id == it.CharacterId);
if (model != null)
{
var info = Mapper.Map<ChatHistoryInfo>(model);
info.LastContactTime = it.UpdateAt;
chatHistoryInfos.Add(info);
}
});
chatHistoryInfos = chatHistoryInfos.OrderByDescending(it => it.LastContactTime).ToList();
return new BaseResponse<List<ChatHistoryInfo>>(ResonseCode.Success, "", chatHistoryInfos) { };
}
}
}