提交代码

This commit is contained in:
zpc 2024-08-12 01:22:43 +08:00
parent 3689a10164
commit 9fc7233324
15 changed files with 408 additions and 59 deletions

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -22,7 +23,10 @@ namespace HuanMeng.DotNetCore.TextCensor.SensitiveWord
/// 存储子节点
/// </summary>
public Dictionary<char, TrieNode> Children { get; set; }
/// <summary>
///
/// </summary>
//public FrozenDictionary<char, TrieNode> fChildren { get; set; }
public TrieNode()
{
IsEnd = false;

View File

@ -113,7 +113,6 @@ namespace HuanMeng.MiaoYu.Code.Cache
#endregion
#region
@ -227,7 +226,7 @@ namespace HuanMeng.MiaoYu.Code.Cache
/// <typeparam name="T"></typeparam>
/// <param name="cacheBase"></param>
/// <returns></returns>
public static CommonDataEntityCache<T> GetMiaoYuDataEntityCache<T>(CacheBase cacheBase) where T : class
public static CommonDataEntityCache<T> GetMiaoYuDataEntityCache<T>(CacheBase cacheBase, Expression<Func<T, bool>> expWhere = null) where T : class
{
object cacheLock;
var typeo = typeof(T);
@ -243,7 +242,7 @@ namespace HuanMeng.MiaoYu.Code.Cache
cacheLock = new object();
CacheLockList[typeo] = cacheLock;
}
return new MiaoYuDataEntityCache<T>(cacheBase, cacheLock);
return new MiaoYuDataEntityCache<T>(cacheBase, cacheLock, expWhere: expWhere);
}
/// <summary>
/// 获取缓存数据
@ -277,7 +276,7 @@ namespace HuanMeng.MiaoYu.Code.Cache
var obj = SpecialCacheLockList[typeof(CharacterCache)];
CharacterEntityCache characterEntityCache = new CharacterEntityCache(miaoYuBase, obj);
characterEntityCache.ClearData();
var dictionaryInfo= miaoYuBase.DictionaryInfo;
var dictionaryInfo = miaoYuBase.DictionaryInfo;
var _dictionaryInfo = dictionaryInfo as ICacheClearData;
if (_dictionaryInfo != null)
{

View File

@ -5,15 +5,22 @@ using HuanMeng.MiaoYu.Code.DataAccess;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;
namespace HuanMeng.MiaoYu.Code.Cache
{
/// <summary>
/// 妙语数据库实体类缓存
/// 妙语数据库实体类缓存
/// </summary>
public class MiaoYuDataEntityCache<T>(CacheBase cacheBase, object lockObj, int cacheTime = 36000)
/// <typeparam name="T"></typeparam>
/// <param name="cacheBase"></param>
/// <param name="lockObj"></param>
/// <param name="cacheTime"></param>
/// <param name="expWhere"></param>
public class MiaoYuDataEntityCache<T>(CacheBase cacheBase, object lockObj, int cacheTime = 36000, Expression<Func<T, bool>> expWhere = null)
: CommonDataEntityCache<T>(lockObj, cacheTime) where T : class
{
public DataAccess.DAO _dao = cacheBase.Dao;
public DataAccess.DAO _dao = cacheBase.Dao;
/// <summary>
/// 缓存的key
/// </summary>
@ -21,7 +28,7 @@ namespace HuanMeng.MiaoYu.Code.Cache
{
get
{
return $"{_dao.daoDbMiaoYu.context.TenantInfo?.TenantId}:MiaoYu:{typeof(T).Name}";
return $"Cache:{_dao.daoDbMiaoYu.context.TenantInfo?.TenantId}:MiaoYu:{typeof(T).Name}";
}
}
/// <summary>
@ -36,6 +43,10 @@ namespace HuanMeng.MiaoYu.Code.Cache
{
return new List<T>();
}
if (expWhere != null)
{
dbSet = dbSet.Where(expWhere);
}
return dbSet.ToList();
}
}

View File

@ -59,9 +59,13 @@ namespace HuanMeng.MiaoYu.Code.Cache.Special
foreach (var characterCache in characterCaches)
{
var modelConfig = modelConfigs.FirstOrDefault(it => it.Id == characterCache.ModelConfigId);
if (modelConfig==null)
if (modelConfig == null)
{
modelConfig= modelConfigs.FirstOrDefault();
modelConfig = modelConfigs.FirstOrDefault(it => it.IsDefabult ?? false);
}
if (modelConfig == null)
{
modelConfig = modelConfigs.FirstOrDefault();
}
if (modelConfig != null)
{

View File

@ -3,8 +3,10 @@ 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.Code.Chat.Minimax;
using HuanMeng.MiaoYu.Code.Users;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.Dto.Character;
using HuanMeng.MiaoYu.Model.Dto.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.User;
@ -16,6 +18,8 @@ using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
@ -175,8 +179,8 @@ namespace HuanMeng.MiaoYu.Code.Chat
chatListDto.ChatList = chatMessageDtos;
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
var charact = MiaoYuCache.CharacterList.FirstOrDefault(it => it.Id == characterId);
if (charact == null)
{
@ -264,37 +268,20 @@ namespace HuanMeng.MiaoYu.Code.Chat
};
#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);
if (response == null)
{
throw new Exception("ai出现错误");
}
var claudeChatResponse = response as ClaudeChatResponse;
if (claudeChatResponse == null)
{
throw new Exception("ai返回出现错误");
}
#endregion
T_Chat t_Chat = new T_Chat
var claudeChatResponse = await Chat(charact, mess);
var t_Chat = new T_Chat
{
CharacterId = charact.Id,
ClaudeModel = claudeChatResponse.Model,
ClaudeId = claudeChatResponse.Id,
ClaudeType = claudeChatResponse.Content[0]?.Type,
Content = claudeChatResponse.Content[0]?.Text,
ClaudeType = "text",
Content = claudeChatResponse.Message,
CreateTime = DateTime.Now,
Input_tokens = claudeChatResponse.Usage.InputTokens,
Output_tokens = claudeChatResponse.Usage.OutputTokens,
Role = claudeChatResponse.Role,
Input_tokens = claudeChatResponse.InputTokens,
Output_tokens = claudeChatResponse.OutputTokens,
Role = ChatRole.assistant.ToString(),
SendDateDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
SendMessageDay = DateTime.Now.ToUnixTimestamp(),
SessionId = userChatSession.SessionId,
@ -303,9 +290,8 @@ namespace HuanMeng.MiaoYu.Code.Chat
Type = 0,
UpdateTime = DateTime.Now,
UserId = _UserId,
Tokens = claudeChatResponse.Usage.OutputTokens
Tokens = claudeChatResponse.OutputTokens
};
#region
using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction())
{
@ -313,17 +299,21 @@ namespace HuanMeng.MiaoYu.Code.Chat
{
if (charact.Token == null || charact.Token == 0)
{
charact.Token = (int)(claudeChatResponse.Usage.InputTokens - (message.Length * 2));
charact.Token = (int)(claudeChatResponse.InputTokens - (message.Length * 2));
if (charact.Token <= 0)
{
charact.Token = claudeChatResponse.Message.Length * 2;
}
var t_Character = await Dao.daoDbMiaoYu.context.T_Character.FirstOrDefaultAsync(it => it.Id == charact.Id);
if (t_Character != null)
{
t_Character.Token = charact.Token;
}
}
t_Chat1.Tokens = claudeChatResponse.Usage.InputTokens - charact.Token;
t_Chat1.Input_tokens = claudeChatResponse.Usage.InputTokens;
t_Chat1.Tokens = claudeChatResponse.InputTokens - charact.Token;
t_Chat1.Input_tokens = claudeChatResponse.InputTokens;
//设置消耗的总token
userChatSession.TotalToken += claudeChatResponse.Usage.InputTokens + claudeChatResponse.Usage.OutputTokens;
userChatSession.TotalToken += claudeChatResponse.InputTokens + claudeChatResponse.OutputTokens;
Dao.daoDbMiaoYu.context.Add(t_Chat1);
Dao.daoDbMiaoYu.context.Add(t_Chat);
//最后一次聊天时间
@ -356,7 +346,7 @@ namespace HuanMeng.MiaoYu.Code.Chat
ChatMessageDto chatMessageDto = new ChatMessageDto()
{
ClaudeType = ChatMessageType.text.ToString(),
Content = claudeChatResponse.Content[0].Text,
Content = claudeChatResponse.Message,
Role = ChatRole.assistant.ToString(),
Timestamp = DateTime.Now,
UserIcon = charact.IconImage,
@ -384,6 +374,58 @@ namespace HuanMeng.MiaoYu.Code.Chat
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
public async Task<BaseChatInfo> Chat(CharacterCache? charact, List<ClaudeChatMessage> mess)
{
if (charact.ModelConfig.ModelName.Contains("minimaxi"))
{
var chat = new MinimaxChat(HttpClientFactory);
MinimaxChatParams minimaxChatParams = new MinimaxChatParams(mess, charact, charact.Name);
return await chat.MessagesAsync(minimaxChatParams);
}
else
{
return await ClaudeChat(charact, mess);
}
}
/// <summary>
///
/// </summary>
/// <param name="charact"></param>
/// <param name="userChatSession"></param>
/// <param name="mess"></param>
/// <param name="t_Chat"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private async Task<BaseChatInfo> ClaudeChat(CharacterCache? charact, List<ClaudeChatMessage> mess)
{
#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);
if (response == null)
{
throw new Exception("ai出现错误");
}
var claudeChatResponse = response as ClaudeChatResponse;
if (claudeChatResponse == null)
{
throw new Exception("ai返回出现错误");
}
#endregion
claudeChatResponse.TotalTokens = claudeChatResponse.Usage.OutputTokens + claudeChatResponse.Usage.InputTokens;
claudeChatResponse.InputTokens = claudeChatResponse.Usage.InputTokens;
claudeChatResponse.OutputTokens = claudeChatResponse.Usage.OutputTokens;
claudeChatResponse.Message = claudeChatResponse.Content[0].Text;
return claudeChatResponse;
}
/// <summary>
/// 通过递归判断聊天是否满足
/// </summary>

View File

@ -1,3 +1,5 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
@ -11,5 +13,38 @@ namespace HuanMeng.MiaoYu.Code.Chat.Contract
/// </summary>
public class BaseChatInfo
{
/// <summary>
/// 消息 ID
/// </summary>
public virtual string Id { get; set; }
/// <summary>
/// 模型
/// </summary>
public virtual string Model { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public virtual string Type { get; set; }
/// <summary>
/// 总token
/// </summary>
public virtual int TotalTokens { get; set; }
/// <summary>
/// 消息内容
/// </summary>
public virtual string Message { get; set; }
/// <summary>
/// 输入token
/// </summary>
public virtual int InputTokens { get; set; }
/// <summary>
/// 输出token
/// </summary>
public virtual int OutputTokens { get; set; }
}
}

View File

@ -0,0 +1,97 @@
using HuanMeng.MiaoYu.Code.Chat.Claude;
using HuanMeng.MiaoYu.Code.Chat.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
namespace HuanMeng.MiaoYu.Code.Chat.Minimax
{
/// <summary>
///
/// </summary>
/// <param name="factory"></param>
public class MinimaxChat(IHttpClientFactory factory) : IChat
{
public async Task<BaseChatInfo> MessagesAsync(BaseChatParams chatParams)
{
var param = chatParams as MinimaxChatParams;
if (param == null)
{
throw new ArgumentNullException("请求错误");
}
using var httpClient = factory.CreateClient();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if (param.Headers != null)
{
foreach (var header in param.Headers)
{
httpClient.DefaultRequestHeaders.Add(header.Key, header.Value);
}
}
BaseChatInfo baseChatInfo = new BaseChatInfo();
var content = new StringContent(param.RequestBody, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync(param.Model_Config.Url, content);
if (response != null && response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
if (responseContent != null)
{
if (param.ResponseConten != null)
{
var responseJobject = JObject.Parse(responseContent);
var message = GetResponseContent("messgae", param, responseJobject);
var model = GetResponseContent("model", param, responseJobject);
var total_tokens = GetResponseContent("total_tokens", param, responseJobject);
var id = GetResponseContent("id", param, responseJobject);
baseChatInfo.Message = message;
baseChatInfo.Model = model;
baseChatInfo.InputTokens = param.Message.Length * 2;
baseChatInfo.OutputTokens = message.Length * 2;
if (!string.IsNullOrEmpty(total_tokens))
{
if (int.TryParse(total_tokens, out var count))
{
baseChatInfo.TotalTokens = count;
}
}
else
{
baseChatInfo.TotalTokens = baseChatInfo.InputTokens + baseChatInfo.OutputTokens;
}
baseChatInfo.Id = id;
}
}
}
return baseChatInfo;
}
private string GetResponseContent(string parmat, MinimaxChatParams? param, JObject responseJobject)
{
if (responseJobject != null)
{
if (param.ResponseConten?.TryGetValue(parmat, out var messgae) ?? false)
{
var mes = responseJobject.SelectToken(messgae).ToString();
return mes;
};
}
return "";
}
public IAsyncEnumerable<string> MessagesStreamAsync(BaseChatParams chatParams)
{
throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,122 @@
using HuanMeng.MiaoYu.Code.Chat.Claude;
using HuanMeng.MiaoYu.Code.Chat.Contract;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.Dto.Character;
using HuanMeng.MiaoYu.Model.EnumModel.Chat;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices.JavaScript;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Chat.Minimax
{
/// <summary>
///
/// </summary>
public class MinimaxChatParams : BaseChatParams
{
public string Message { get; set; }
/// <summary>
///
/// </summary>
/// <param name="messages"></param>
/// <param name="model_Config"></param>
/// <param name="botName"></param>
public MinimaxChatParams(List<ClaudeChatMessage> messages, CharacterCache character, string botName)
{
this.Model_Config = character.ModelConfig;
//
if (!string.IsNullOrEmpty(Model_Config.HeadersTemplate))
{
this.Headers = JsonConvert.DeserializeObject<Dictionary<string, string>>(Model_Config.HeadersTemplate) ?? new Dictionary<string, string>();
}
Message = messages[messages.Count - 1].Content;
if (!string.IsNullOrEmpty(Model_Config.RequestTemplate))
{
var assistant = ChatRole.assistant.ToString();
var user = ChatRole.user.ToString();
List<MinimaxChatMessage> minimaxChatMessages = new List<MinimaxChatMessage>();
messages.ForEach(message =>
{
MinimaxChatMessage minimaxChatMessage = new MinimaxChatMessage();
minimaxChatMessage.Text = message.Content;
if (message.Role == assistant)
{
minimaxChatMessage.SenderType = "BOT";
}
else if (message.Role == user)
{
minimaxChatMessage.SenderType = "USER";
}
minimaxChatMessages.Add(minimaxChatMessage);
});
var mess = JsonConvert.SerializeObject(minimaxChatMessages);
var systemp = Model_Config.RequestTemplate
.Replace("${messages}", mess)
.Replace("${bot_name}", botName)
;
var jobj = JObject.Parse(systemp);
foreach (var item in jobj)
{
if (item.Value?.Type == JTokenType.String)
{
var prompt = item.Value?.ToString() ?? "";
if (prompt.Contains("${prompt}"))
{
jobj[item.Key] = prompt.Replace("${prompt}", character.System);
}
}
}
systemp = JsonConvert.SerializeObject(jobj);
//.Replace("${prompt}", cc["prompt"].ToString())
this.RequestBody = systemp;
}
if (!string.IsNullOrEmpty(character.ModelConfig.ResponseTemplate))
{
this.ResponseConten = JsonConvert.DeserializeObject<Dictionary<string, string>>(Model_Config.ResponseTemplate) ?? new Dictionary<string, string>();
}
}
/// <summary>
///
/// </summary>
public T_Model_Config Model_Config { get; set; }
/// <summary>
/// 请求标头
/// </summary>
public Dictionary<string, string>? Headers { get; set; }
/// <summary>
/// 请求体
/// </summary>
public string RequestBody { get; set; }
/// <summary>
/// 请求返回结果
/// </summary>
public Dictionary<string, string>? ResponseConten { get; set; }
}
/// <summary>
///
/// </summary>
public class MinimaxChatMessage
{
[JsonProperty("sender_type")]
public string SenderType { get; set; }
[JsonProperty("text")]
public string Text;
}
}

View File

@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.6.2" />
<PackageReference Include="TencentCloudSDK.Common" Version="3.0.1042" />
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1042" />

View File

@ -548,6 +548,8 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
entity.Property(e => e.CreateTime)
.HasComment("创建时间")
.HasColumnType("datetime");
entity.Property(e => e.HeadersTemplate).HasComment("headers对象");
entity.Property(e => e.IsDefabult).HasComment("是否默认");
entity.Property(e => e.MaxTokens).HasComment("模型运行最大的max_tokens");
entity.Property(e => e.Model)
.HasMaxLength(50)
@ -555,6 +557,8 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
entity.Property(e => e.ModelName)
.HasMaxLength(50)
.HasComment("模型名称");
entity.Property(e => e.RequestTemplate).HasComment("请求模板");
entity.Property(e => e.ResponseTemplate).HasComment("返回数据模板");
entity.Property(e => e.SystemTemplate).HasComment("system上下文模板");
entity.Property(e => e.TenantId).HasComment("租户");
entity.Property(e => e.UpdateTime)

View File

@ -55,4 +55,24 @@ public partial class T_Model_Config: MultiTenantEntity
/// system上下文模板
/// </summary>
public virtual string? SystemTemplate { get; set; }
/// <summary>
/// 请求模板
/// </summary>
public virtual string? RequestTemplate { get; set; }
/// <summary>
/// headers对象
/// </summary>
public virtual string? HeadersTemplate { get; set; }
/// <summary>
/// 返回数据模板
/// </summary>
public virtual string? ResponseTemplate { get; set; }
/// <summary>
/// 是否默认
/// </summary>
public virtual bool? IsDefabult { get; set; }
}

View File

@ -106,6 +106,21 @@ namespace HuanMeng.MiaoYu.Model.Dto.Character
}
#endregion
private string? _system = null;
public string GenderStr
{
get
{
if(this.Gender == 0)
{
return "男";
}
if (this.Gender == 1)
{
return "女";
}
return "其它";
}
}
/// <summary>
/// 上下文
/// </summary>
@ -121,8 +136,8 @@ namespace HuanMeng.MiaoYu.Model.Dto.Character
_system = ModelConfig.SystemTemplate ?? "";
_system = _system
.Replace("{assistant}", this.Name) //ai角色名称
.Replace("{user}", this.UserName) //用户角色名称
.Replace("{sex}", this.Gender == 0 ? "男" : "女") //角色
.Replace("{user}", "我") //用户角色名称
.Replace("{sex}", GenderStr) //角色
.Replace("{biography}", this.Biography) //提示词 简介
.Replace("{personality}", this.PersonalityStr) //性格
.Replace("{prologue}", this.Prologue) //剧情

View File

@ -37,10 +37,10 @@ namespace HuanMeng.MiaoYu.Model.Dto.Shop
///// </summary>
//public int PropId { get; set; }
///// <summary>
///// 道具名称
///// </summary>
//public string PropName { get; set; }
/// <summary>
/// 道具名称
/// </summary>
public string PropName { get; set; }
/// <summary>
/// 道具剩余数量
@ -63,10 +63,10 @@ namespace HuanMeng.MiaoYu.Model.Dto.Shop
public int PriceType { get; set; }
///// <summary>
///// 图片地址
///// </summary>
//public string ImgUrl { get; set; }
/// <summary>
/// 图片地址
/// </summary>
public string ImgUrl { get; set; }
}
/// <summary>

View File

@ -61,8 +61,6 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
public BaseResponse<List<RecommendDto<DataListBaseDto>>> GetCategoryFindList()
{
CategoryBLL categoryBLL = new CategoryBLL(ServiceProvider);
//var x = categoryBLL.GetRecommendList();
//var json = JsonConvert.SerializeObject(x);
return categoryBLL.GetRecommendList();
}
}

View File

@ -58,9 +58,6 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
CharacterBLL characterBLL = new CharacterBLL(ServiceProvider);
var obj = await characterBLL.GetCharacterInfo(requestCharacterInfo);
return obj;
//var obj = JsonConvert.DeserializeObject<List<CharacterInfoDto>>("[{\"Icon\":\"\",\"Intimacy\":10,\"CharacterIdModel\":2,\"CharacterName\":\"许荷姻\",\"Gender\":1,\"LookCount\":2,\"BgUrl\":\"\",\"Biography\":\"你那商业联姻得来的妻子,原本的天才女孩,聪明伶俐,生的漂亮、端庄,不知贵圈多少人梦寐以求的存在。\",\"Prologue\":\"坐在轮椅上,眼神平静的看着你,语气也同样平静)你回来了。饭菜在桌上,我刚刚热了。(说到这,又垂下眸子道)我还做了碗醒酒汤,记得喝\",\"Label\":[{\"CharacterIdModel\":1,\"Name\":\"美女\"},{\"CharacterIdModel\":2,\"Name\":\"二次元\"}],\"RemainingChatCount\":1}]");
//return new BaseResponse<List<CharacterInfoDto>>(ResonseCode.Success, "", obj);
}
/// <summary>