mirror of
https://github.com/AIDotNet/AntSK.git
synced 2026-02-17 22:10:14 +08:00
add 处理在有用户时使用chats表次存储聊天记录,匿名访问时使用localstorage存储聊天记录
This commit is contained in:
@@ -157,11 +157,6 @@
|
||||
模型类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.MessageInfo.IsSend">
|
||||
<summary>
|
||||
发送是true 接收是false
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Domain.Model.PageList`1.PageIndex">
|
||||
<summary>
|
||||
当前页,从1开始
|
||||
@@ -407,6 +402,36 @@
|
||||
回答最大token数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.UserName">
|
||||
<summary>
|
||||
用户名
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.AppId">
|
||||
<summary>
|
||||
应用ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.Context">
|
||||
<summary>
|
||||
消息内容
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.IsSend">
|
||||
<summary>
|
||||
发送是true 接收是false
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.CreateTime">
|
||||
<summary>
|
||||
创建事件
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Chats.FileName">
|
||||
<summary>
|
||||
文件名
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:AntSK.Domain.Repositories.Funs.Path">
|
||||
<summary>
|
||||
接口描述
|
||||
|
||||
@@ -18,6 +18,6 @@ namespace AntSK.Domain.Domain.Interface
|
||||
|
||||
IAsyncEnumerable<StreamingKernelContent> SendKmsByAppAsync(Apps app, string questions, ChatHistory history, string filePath, List<RelevantSource> relevantSources = null);
|
||||
Task<string> SendImgByAppAsync(Apps app, string questions);
|
||||
Task<ChatHistory> GetChatHistory(List<MessageInfo> MessageList);
|
||||
Task<ChatHistory> GetChatHistory(List<Chats> MessageList);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace AntSK.Domain.Domain.Model
|
||||
{
|
||||
public class MessageInfo
|
||||
{
|
||||
public string ID { get; set; } = "";
|
||||
public string Context { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 发送是true 接收是false
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; } = false;
|
||||
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ namespace AntSK.Domain.Domain.Service
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ChatHistory> GetChatHistory(List<MessageInfo> MessageList)
|
||||
public async Task<ChatHistory> GetChatHistory(List<Chats> MessageList)
|
||||
{
|
||||
ChatHistory history = new ChatHistory();
|
||||
if (MessageList.Count > 1)
|
||||
|
||||
40
src/AntSK.Domain/Repositories/AI/Chat/Chats.cs
Normal file
40
src/AntSK.Domain/Repositories/AI/Chat/Chats.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using AntSK.Domain.Domain.Model.Enum;
|
||||
using SqlSugar;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[SugarTable("Chats")]
|
||||
public partial class Chats
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public string Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
/// <summary>
|
||||
/// 应用ID
|
||||
/// </summary>
|
||||
public string AppId { get; set; }
|
||||
/// <summary>
|
||||
/// 消息内容
|
||||
/// </summary>
|
||||
public string Context { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 发送是true 接收是false
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 创建事件
|
||||
/// </summary>
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件名
|
||||
/// </summary>
|
||||
public string? FileName { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/AntSK.Domain/Repositories/AI/Chat/Chats_Repositories.cs
Normal file
11
src/AntSK.Domain/Repositories/AI/Chat/Chats_Repositories.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
using AntSK.Domain.Common.DependencyInjection;
|
||||
using AntSK.Domain.Repositories.Base;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
[ServiceDescription(typeof(IChats_Repositories), ServiceLifetime.Scoped)]
|
||||
public class Chats_Repositories : Repository<Chats>, IChats_Repositories
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using AntSK.Domain.Repositories.Base;
|
||||
|
||||
namespace AntSK.Domain.Repositories
|
||||
{
|
||||
public interface IChats_Repositories : IRepository<Chats>
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -6,14 +6,17 @@ using AntSK.Domain.Domain.Model.Enum;
|
||||
using AntSK.Domain.Repositories;
|
||||
using AntSK.Domain.Utils;
|
||||
using AntSK.LLM.StableDiffusion;
|
||||
using AntSK.Models;
|
||||
using Blazored.LocalStorage;
|
||||
using Markdig;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
|
||||
using Microsoft.JSInterop;
|
||||
using Microsoft.SemanticKernel;
|
||||
using Microsoft.SemanticKernel.ChatCompletion;
|
||||
using Microsoft.SemanticKernel.Connectors.OpenAI;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AntSK.Pages.ChatPage.Components
|
||||
{
|
||||
@@ -36,8 +39,10 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
[Inject] IChatService _chatService { get; set; }
|
||||
[Inject] IJSRuntime _JSRuntime { get; set; }
|
||||
[Inject] ILocalStorageService _localStorage { get; set; }
|
||||
[Inject] IChats_Repositories _chats_Repositories { get; set; }
|
||||
[Inject] ProtectedSessionStorage _protectedSessionStore { get; set; }
|
||||
|
||||
protected List<MessageInfo> MessageList = [];
|
||||
protected List<Chats> MessageList = [];
|
||||
protected string? _messageInput;
|
||||
protected string _json = "";
|
||||
protected bool Sendding = false;
|
||||
@@ -48,25 +53,85 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
|
||||
private List<RelevantSource> _relevantSources = new List<RelevantSource>();
|
||||
|
||||
private string _userName { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
LoadData();
|
||||
var msgs = await _localStorage.GetItemAsync<List<MessageInfo>>("msgs");
|
||||
await LoadData();
|
||||
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await LoadData();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化加载数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task LoadData()
|
||||
{
|
||||
app = _apps_Repositories.GetFirst(p => p.Id == AppId);
|
||||
var userSessionStorageResult = await _protectedSessionStore.GetAsync<UserSession>("UserSession");
|
||||
var userSession = userSessionStorageResult.Success ? userSessionStorageResult.Value : null;
|
||||
_userName = userSession?.UserName;
|
||||
await GetMsgList();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取聊天记录列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task GetMsgList()
|
||||
{
|
||||
MessageList.Clear();
|
||||
List<Chats> msgs = new List<Chats>();
|
||||
if (string.IsNullOrEmpty(_userName))
|
||||
{
|
||||
//匿名访问使用localstore
|
||||
msgs = await _localStorage.GetItemAsync<List<Chats>>($"msgs:{AppId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
msgs = await _chats_Repositories.GetListAsync(p => p.AppId == AppId && p.UserName == _userName);
|
||||
}
|
||||
if (msgs != null && msgs.Count > 0)
|
||||
{
|
||||
MessageList = msgs;
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
/// <summary>
|
||||
/// 清空聊天记录列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task ClearMsgList()
|
||||
{
|
||||
LoadData();
|
||||
MessageList.Clear();
|
||||
if (string.IsNullOrEmpty(_userName))
|
||||
{
|
||||
await _localStorage.SetItemAsync<List<Chats>>($"msgs:{AppId}", MessageList);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _chats_Repositories.DeleteAsync(p => p.AppId == AppId && p.UserName == _userName);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadData()
|
||||
/// <summary>
|
||||
/// 保存聊天记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task SaveMsg()
|
||||
{
|
||||
app = _apps_Repositories.GetFirst(p => p.Id == AppId);
|
||||
if (string.IsNullOrEmpty(_userName))
|
||||
{
|
||||
await _localStorage.SetItemAsync<List<Chats>>($"msgs:{AppId}", MessageList);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _chats_Repositories.InsertAsync(MessageList.LastOrDefault());
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task OnClearAsync()
|
||||
@@ -78,11 +143,11 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
var result = await _confirmService.Show(content, title, ConfirmButtons.YesNo);
|
||||
if (result == ConfirmResult.Yes)
|
||||
{
|
||||
MessageList.Clear();
|
||||
await _localStorage.SetItemAsync<List<MessageInfo>>("msgs", MessageList);
|
||||
|
||||
await ClearMsgList();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
_ = Message.Info("清理成功");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -102,18 +167,25 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
var filePath = fileList.FirstOrDefault()?.Url;
|
||||
var fileName = fileList.FirstOrDefault()?.FileName;
|
||||
|
||||
MessageList.Add(new MessageInfo()
|
||||
var chat = new Chats()
|
||||
{
|
||||
ID = Guid.NewGuid().ToString(),
|
||||
Id = Guid.NewGuid().ToString(),
|
||||
UserName = _userName,
|
||||
AppId = AppId,
|
||||
Context = _messageInput,
|
||||
CreateTime = DateTime.Now,
|
||||
IsSend = true
|
||||
});
|
||||
|
||||
};
|
||||
MessageList.Add(chat);
|
||||
if (string.IsNullOrEmpty(_userName))
|
||||
{
|
||||
_chats_Repositories.InsertAsync(chat);
|
||||
}
|
||||
|
||||
Sendding = true;
|
||||
await SendAsync(_messageInput,filePath);
|
||||
await SendAsync(_messageInput, filePath);
|
||||
_messageInput = "";
|
||||
Sendding = false;
|
||||
Sendding = false;
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
@@ -123,7 +195,9 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
}
|
||||
|
||||
}
|
||||
protected async Task OnCopyAsync(MessageInfo item)
|
||||
|
||||
|
||||
protected async Task OnCopyAsync(Chats item)
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
@@ -135,10 +209,16 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
{
|
||||
await Task.Run(() =>
|
||||
{
|
||||
MessageList = MessageList.Where(w => w.ID != id).ToList();
|
||||
MessageList = MessageList.Where(w => w.Id != id).ToList();
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 开始发送消息
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="filePath"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task<bool> SendAsync(string questions, string? filePath)
|
||||
{
|
||||
ChatHistory history = new ChatHistory();
|
||||
@@ -166,17 +246,25 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
//缓存消息记录
|
||||
if (app.Type != AppType.img.ToString())
|
||||
{
|
||||
await _localStorage.SetItemAsync<List<MessageInfo>>("msgs", MessageList);
|
||||
await SaveMsg();
|
||||
}
|
||||
|
||||
|
||||
return await Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送图片对话
|
||||
/// </summary>
|
||||
/// <param name="questions"></param>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
private async Task SendImg(string questions,Apps app)
|
||||
{
|
||||
MessageInfo info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
Chats info = new Chats();
|
||||
info.Id = Guid.NewGuid().ToString();
|
||||
info.UserName=_userName;
|
||||
info.AppId=AppId;
|
||||
info.CreateTime = DateTime.Now;
|
||||
var base64= await _chatService.SendImgByAppAsync(app, questions);
|
||||
if (string.IsNullOrEmpty(base64))
|
||||
@@ -199,14 +287,16 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
/// <returns></returns>
|
||||
private async Task SendKms(string questions, ChatHistory history, Apps app, string? filePath)
|
||||
{
|
||||
MessageInfo info = null;
|
||||
Chats info = null;
|
||||
var chatResult = _chatService.SendKmsByAppAsync(app, questions, history, filePath, _relevantSources);
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
info = new Chats();
|
||||
info.Id = Guid.NewGuid().ToString();
|
||||
info.UserName = _userName;
|
||||
info.AppId = AppId;
|
||||
info.Context = content.ConvertToString();
|
||||
info.CreateTime = DateTime.Now;
|
||||
|
||||
@@ -233,14 +323,16 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
/// <returns></returns>
|
||||
private async Task SendChat(string questions, ChatHistory history, Apps app)
|
||||
{
|
||||
MessageInfo info = null;
|
||||
Chats info = null;
|
||||
var chatResult = _chatService.SendChatByAppAsync(app, questions, history);
|
||||
await foreach (var content in chatResult)
|
||||
{
|
||||
if (info == null)
|
||||
{
|
||||
info = new MessageInfo();
|
||||
info.ID = Guid.NewGuid().ToString();
|
||||
info = new Chats();
|
||||
info.Id = Guid.NewGuid().ToString();
|
||||
info.UserName = _userName;
|
||||
info.AppId = AppId;
|
||||
info.Context = content.ConvertToString();
|
||||
info.CreateTime = DateTime.Now;
|
||||
|
||||
@@ -257,7 +349,12 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
await MarkDown(info);
|
||||
}
|
||||
|
||||
private async Task MarkDown(MessageInfo info)
|
||||
/// <summary>
|
||||
/// 处理markdown
|
||||
/// </summary>
|
||||
/// <param name="info"></param>
|
||||
/// <returns></returns>
|
||||
private async Task MarkDown(Chats info)
|
||||
{
|
||||
if (info.IsNotNull())
|
||||
{
|
||||
@@ -270,6 +367,10 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
await _JSRuntime.ScrollToBottomAsync("scrollDiv");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传文件事件
|
||||
/// </summary>
|
||||
/// <param name="fileInfo"></param>
|
||||
private void OnSingleCompleted(UploadInfo fileInfo)
|
||||
{
|
||||
fileList.Add(new()
|
||||
@@ -281,6 +382,11 @@ namespace AntSK.Pages.ChatPage.Components
|
||||
});
|
||||
_kMService.OnSingleCompleted(fileInfo);
|
||||
}
|
||||
/// <summary>
|
||||
/// 移除文件事件
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> HandleFileRemove(UploadFileItem file)
|
||||
{
|
||||
fileList.RemoveAll(x => x.FileName == file.FileName);
|
||||
|
||||
Reference in New Issue
Block a user