修改记忆卡

This commit is contained in:
zpc 2024-07-24 04:58:00 +08:00
parent fc925c8780
commit 786dbe506f
18 changed files with 839 additions and 75 deletions

View File

@ -1,17 +1,10 @@
using AutoMapper;
using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Code.Other;
using HuanMeng.MiaoYu.Model.Dto;
using HuanMeng.MiaoYu.Model.Dto.Character;
using HuanMeng.MiaoYu.Model.Dto.Label;
using HuanMeng.MiaoYu.Model.Dto.Personality;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Cache.Special
{

View File

@ -3,8 +3,10 @@
using AutoMapper;
using HuanMeng.DotNetCore.Base;
using HuanMeng.MiaoYu.Code.Users;
using HuanMeng.MiaoYu.Model.Dto.Character;
using HuanMeng.MiaoYu.Model.Dto.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.User;
using Microsoft.EntityFrameworkCore;
@ -70,6 +72,7 @@ namespace HuanMeng.MiaoYu.Code.Character
return new BaseResponse<CharacterInfoDto>();
}
var info = Mapper.Map<CharacterInfoDto>(charactersinfo);
info.MemoryCardState = false;
//不是游客
if (_UserId != 0)
{
@ -77,6 +80,9 @@ namespace HuanMeng.MiaoYu.Code.Character
var intimacys = await Dao.daoDbMiaoYu.context.T_Character_User_Intimacy.Where(it => it.UserId == _UserId
&& it.CharacterId == info.CharacterId).FirstOrDefaultAsync();
info.Intimacy = intimacys?.IntimacyValue ?? 0;
UserInfoBLL userInfoBLL = new UserInfoBLL(Dao, _UserId);
(var maxtoken, var memoryCardState) = userInfoBLL.GetMemoryCardMaxToken(requestCharacterInfo.CharacterId);
info.MemoryCardState = memoryCardState;
}
return new BaseResponse<CharacterInfoDto>(ResonseCode.Success, "", info);
}

View File

@ -3,13 +3,16 @@ 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.Users;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.Dto.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.Chat;
using HuanMeng.MiaoYu.Model.EnumModel.User;
using HuanMeng.Utility;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.Extensions.DependencyInjection;
using System;
@ -178,6 +181,12 @@ namespace HuanMeng.MiaoYu.Code.Chat
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
//if(timeStamp.)
UserInfoBLL userInfoBLL = new UserInfoBLL(Dao, _UserId);
if (!userInfoBLL.IsCheckingSufficient(UserCurrencyType.))
{
throw new Exception("聊天次数不足");
}
//userInfoBLL.User.GetUserCurrency(Model.EnumModel.User.UserCurrencyType.聊天次数);
var userChatSession = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.CharacterId == characterId && it.UserId == _UserId && !it.IsDelete).FirstOrDefaultAsync();
if (userChatSession == null)
{
@ -187,33 +196,26 @@ namespace HuanMeng.MiaoYu.Code.Chat
CharacterId = characterId,
CreateAt = DateTime.Now,
IsDelete = false,
SessionName = "新会话",
SessionName = $"{charact.Name}-{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}",
UpdateAt = DateTime.Now,
ModelConfigId = charact.ModelConfigId,
TenantId = charact.TenantId,
UserId = _UserId,
TotalToken = 0,
};
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,
});
}
int maxToken = 7000;
// var _memoryCardType = userInfoBLL[Model.EnumModel.UserMemoryCardType.记忆卡, charact.Id];
(maxToken, var isMemoryCard) = userInfoBLL.GetMemoryCardMaxToken(charact.Id);
//await AddMessage(userChatSession, mess);
//递归获取聊天记录
var _token = await AddMessage(userChatSession.SessionId, _UserId, 1, 0, maxToken, mess);
//将聊天数据反转
// mess.Reverse();
mess = mess.OrderBy(it => it.MessageDay).ToList();
mess.Add(new ClaudeChatMessage
{
Role = ChatRole.user.ToString(),
@ -256,7 +258,12 @@ namespace HuanMeng.MiaoYu.Code.Chat
throw new Exception("ai出现错误");
}
var claudeChatResponse = response as ClaudeChatResponse;
if (claudeChatResponse == null)
{
throw new Exception("ai返回出现错误");
}
#endregion
T_Chat t_Chat = new T_Chat
{
CharacterId = charact.Id,
@ -276,11 +283,55 @@ namespace HuanMeng.MiaoYu.Code.Chat
Type = 0,
UpdateTime = DateTime.Now,
UserId = _UserId,
Tokens = claudeChatResponse.Usage.OutputTokens
};
Dao.daoDbMiaoYu.context.Add(t_Chat1);
Dao.daoDbMiaoYu.context.Add(t_Chat);
userChatSession.UpdateAt = DateTime.Now;
await Dao.daoDbMiaoYu.context.SaveChangesAsync();
#region
using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction())
{
try
{
if (charact.Token == null || charact.Token == 0)
{
charact.Token = (int)(claudeChatResponse.Usage.InputTokens - (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;
//设置消耗的总token
userChatSession.TotalToken += claudeChatResponse.Usage.InputTokens + claudeChatResponse.Usage.OutputTokens;
Dao.daoDbMiaoYu.context.Add(t_Chat1);
Dao.daoDbMiaoYu.context.Add(t_Chat);
//最后一次聊天时间
userChatSession.UpdateAt = DateTime.Now;
//最后一次聊天记录
userChatSession.LastMessage = t_Chat.Content;
if (userChatSession.LastMessage.Length > 10)
{
userChatSession.LastMessage = userChatSession.LastMessage.Substring(0, 10) + "...";
}
await Dao.daoDbMiaoYu.context.SaveChangesAsync();
//扣除货币
userInfoBLL[UserCurrencyType.].ConsumeMoneyNoWork(-1, Dao);
if (isMemoryCard)
{
//扣除记忆卡
userInfoBLL[Model.EnumModel.UserMemoryCardType., charact.Id].ConsumeMemoryCard(-1, Dao);
}
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
#endregion
//claudeChatResponse.
ChatMessageDto chatMessageDto = new ChatMessageDto()
{
@ -292,22 +343,77 @@ namespace HuanMeng.MiaoYu.Code.Chat
Id = t_Chat.Id
};
chatMessageDtos.Add(chatMessageDto);
ChatMessageDto chatMessageDto1 = new ChatMessageDto()
#region
var cishu = userInfoBLL[UserCurrencyType.].CurrencyMoney;
if (cishu <= 3)
{
ClaudeType = ChatMessageType.text.ToString(),
Content = "您还剩余1次聊天次数",
Role = ChatRole.tips.ToString(),
Timestamp = DateTime.Now,
UserIcon = "",
Id = t_Chat.Id
};
chatMessageDtos.Add(chatMessageDto1);
ChatMessageDto chatMessageDto1 = new ChatMessageDto()
{
ClaudeType = ChatMessageType.text.ToString(),
Content = $"您还剩余{cishu:F0}次聊天次数",
Role = ChatRole.tips.ToString(),
Timestamp = DateTime.Now,
Id = 0
};
chatMessageDtos.Add(chatMessageDto1);
}
#endregion
chatListDto.ChatList = chatMessageDtos;
chatListDto.LastMessageId = t_Chat1.Id;
chatListDto.RemainingChatCount = 1;
chatListDto.RemainingChatCount = (int)cishu;
return new BaseResponse<ChatMessageDataDto>(ResonseCode.Success, "", chatListDto);
}
/// <summary>
/// 通过递归判断聊天是否满足
/// </summary>
/// <param name="sessionId"></param>
/// <param name="userId"></param>
/// <param name="index"></param>
/// <param name="tokens"></param>
/// <param name="maxTokens"></param>
/// <param name="mess"></param>
/// <returns></returns>
private async Task<int> AddMessage(Guid sessionId, int userId, int index, int tokens, int maxTokens, List<ClaudeChatMessage> mess)
{
int size = 50;
var role = new List<string>();
role.Add(ChatRole.assistant.ToString());
role.Add(ChatRole.user.ToString());
var chatList = await Dao.daoDbMiaoYu.context.T_Chat.AsNoTracking().Where(it => it.SessionId == sessionId && it.UserId == userId && role.Contains(it.Role)).OrderByDescending(it => it.SendMessageDay).Skip((index - 1) * size).Take(size)
.Select(it => new { it.Role, it.Content, it.Tokens, it.SendMessageDay }).ToListAsync();
if (chatList != null || chatList.Count == 0)
{
for (int i = 0; i < chatList.Count; i++)
{
var chat = chatList[i];
if ((tokens + chat.Tokens) > maxTokens)
{
return tokens;
}
mess.Add(new ClaudeChatMessage
{
Role = chat.Role,
Content = chat.Content,
MessageDay = chat.SendMessageDay
});
tokens += chat.Tokens ?? 0;
}
//数据不够
if (chatList.Count < size)
{
return tokens;
}
if (tokens < maxTokens)
{
index++;
await AddMessage(sessionId, userId, index, tokens, maxTokens, mess);
}
}
return tokens;
}
/// <summary>
/// 删除聊天记录
/// </summary>

View File

@ -63,10 +63,13 @@ namespace HuanMeng.MiaoYu.Code.Chat.Claude
var response = await httpClient.PostAsync(claudeChatConfig.RequestUrl, content);
if (response.IsSuccessStatusCode)
{
var chatInfo = await response.Content.ReadFromJsonAsync<ClaudeChatResponse?>();
//var chatInfo1 = await response.Content.ReadFromJsonAsync<ClaudeChatResponse?>();
string responseBody = await response.Content.ReadAsStringAsync();
var chatInfo = JsonConvert.DeserializeObject<ClaudeChatResponse>(responseBody);
return chatInfo;
}
else {
else
{
// 读取并打印返回消息
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine($"返回消息: {responseBody}");

View File

@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Chat.Claude
{
@ -19,5 +15,10 @@ namespace HuanMeng.MiaoYu.Code.Chat.Claude
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
///
/// </summary>
[JsonIgnore]
public long MessageDay { get; set; }
}
}

View File

@ -1,4 +1,8 @@
global using HuanMeng.MiaoYu.Code.Base;
global using HuanMeng.MiaoYu.Code.DataAccess;
global using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
global using HuanMeng.MiaoYu.Code.Other;
global using HuanMeng.MiaoYu.Code.Other;
global using System.Text.Json;
global using System.Text.Json.Serialization;
global using HuanMeng.MiaoYu.Model.EnumModel;
global using HuanMeng.MiaoYu.Model.EnumModel.User;

View File

@ -6,6 +6,7 @@ using HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount;
using HuanMeng.MiaoYu.Model.Dto;
using HuanMeng.MiaoYu.Model.Dto.Account;
using HuanMeng.MiaoYu.Model.Dto.Character;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
@ -16,6 +17,7 @@ using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
namespace HuanMeng.MiaoYu.Code.Users
@ -108,40 +110,44 @@ namespace HuanMeng.MiaoYu.Code.Users
var user = await Dao.daoDbMiaoYu.context.T_User.FirstOrDefaultAsync(it => it.Id == _UserId);
var userData = await Dao.daoDbMiaoYu.context.T_User_Data.FirstOrDefaultAsync(it => it.Id == _UserId);
//获取用户余额
var Currency = user.GetUserCurrency(Model.EnumModel.User.UserCurrencyType., Dao);
var RemainingChatCount = user.GetUserCurrency(Model.EnumModel.User.UserCurrencyType., Dao);
var Currency = user.GetUserCurrencyMoney(Model.EnumModel.User.UserCurrencyType., Dao);
var RemainingChatCount = user.GetUserCurrencyMoney(Model.EnumModel.User.UserCurrencyType., Dao);
var memoryCard = user.GetUserCurrencyMoney(Model.EnumModel.User.UserCurrencyType., Dao);
//获取聊天次数
var hasTalked = Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.UserId == _UserId && !it.IsDelete && it.TotalToken > 0).Count();
List<CreateCharacterInfo> characters = new List<CreateCharacterInfo>();
return new BaseResponse<ResponseUserInfo>(ResonseCode.Success, "请求成功", new ResponseUserInfo
{
NickName = user.NickName,
UserId = user.Id,
Currency = userData.Currency,
Currency = (int)Currency,
UserIconUrl = userData.UserIconUrl,
RemainingChatCount = 1,//这里先写1我不会decimal转int
HasTalked=1,
Photographs=1,
RemainingChatCount = (int)RemainingChatCount,//这里先写1我不会decimal转int
HasTalked = hasTalked,
Photographs = 0,
MemoryCard = (int)memoryCard,
CharacterInfo = new List<CreateCharacterInfo>
{
new CreateCharacterInfo
{
CharacterId = 1,
CharacterName = "林婉儿",
BgImage = "https://cos.shhuanmeng.com/image/icon/%E6%9E%97%E5%A9%89%E5%84%BF.png"
},
new CreateCharacterInfo
{
CharacterId = 2,
CharacterName = "赵灵儿",
BgImage = "https://cos.shhuanmeng.com/image/icon/%E6%9E%97%E5%A9%89%E5%84%BF.png"
}
// 可以继续添加更多的 CreateCharacterInfo 对象
//new CreateCharacterInfo
//{
// CharacterId = 1,
// CharacterName = "林婉儿",
// BgImage = "https://cos.shhuanmeng.com/image/icon/%E6%9E%97%E5%A9%89%E5%84%BF.png"
//},
//new CreateCharacterInfo
//{
// CharacterId = 2,
// CharacterName = "赵灵儿",
// BgImage = "https://cos.shhuanmeng.com/image/icon/%E6%9E%97%E5%A9%89%E5%84%BF.png"
//}
//// 可以继续添加更多的 CreateCharacterInfo 对象
},
InviteNewUser = new InviteNewUserDto
{
ImgUrl = "https://cos.shhuanmeng.com/image/icon/20240720205857.png",
Type = 0
}
});
});
}
}
}

View File

@ -41,6 +41,34 @@ namespace HuanMeng.MiaoYu.Code.Users
/// </summary>
public static class UserCurrencyExtend
{
/// <summary>
/// 获取用户货币余额,没有货币的时候添加
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static decimal GetUserCurrencyMoney(this T_User user, UserCurrencyType userCurrencyType, DAO dao)
{
var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.FirstOrDefault(it => it.UserId == user.Id && it.CurrencyType == (int)userCurrencyType);
if (userCurrency == null)
{
userCurrency = new T_User_Currency()
{
CurrencyMoney = 0,
CreateAt = DateTime.Now,
CurrencyName = userCurrencyType.ToString(),
CurrencyType = (int)userCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateAt = DateTime.Now,
UserId = user.Id,
};
dao.daoDbMiaoYu.context.Add(userCurrency);
dao.daoDbMiaoYu.context.SaveChanges();
}
return userCurrency?.CurrencyMoney ?? 0;
}
/// <summary>
/// 获取用户货币余额
/// </summary>
@ -48,12 +76,178 @@ namespace HuanMeng.MiaoYu.Code.Users
/// <param name="userCurrencyType"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static decimal GetUserCurrency(this T_User user, UserCurrencyType userCurrencyType, DAO dao)
public static T_User_Currency GetUserCurrency(this T_User user, UserCurrencyType userCurrencyType, DAO dao)
{
var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.FirstOrDefault(it => it.UserId == user.Id && it.CurrencyType == (int)userCurrencyType);
return userCurrency?.CurrencyMoney ?? 0;
return userCurrency;
}
/// <summary>
/// 获取用户所有货币信息
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static List<T_User_Currency> GetUserCurrencys(this T_User user, DAO dao)
{
var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.Where(it => it.UserId == user.Id).ToList();
return userCurrency;
}
#region
/// <summary>
/// 扣除或者充值货币
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType">货币类型</param>
/// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param>
/// <param name="_currency"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public static bool ConsumeMoneyNoWork(this T_User user, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null)
{
if (user == null || user.Id == 0)
{
throw new ArgumentNullException("用户不能为空");
}
int userId = user.Id;
return ConsumeMoneyNoWork(userId, userCurrencyType, money, dao, _currency);
}
/// <summary>
/// 扣除或者充值货币
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType">货币类型</param>
/// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param>
/// <param name="_currency"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public static bool ConsumeMoneyNoWork(this T_User_Data user, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null)
{
if (user == null || user.UserId == 0)
{
throw new ArgumentNullException("用户不能为空");
}
int userId = user.UserId;
return ConsumeMoneyNoWork(userId, userCurrencyType, money, dao, _currency);
}
/// <summary>
/// 扣除或者充值货币
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType">货币类型</param>
/// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param>
/// <param name="_currency"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="Exception"></exception>
public static bool ConsumeMoneyNoWork(this T_User_Currency user, decimal money, DAO dao)
{
if (user == null || user.UserId == 0)
{
throw new ArgumentNullException("用户不能为空");
}
int userId = user.UserId;
return ConsumeMoneyNoWork(userId, (UserCurrencyType)user.CurrencyType, money, dao, user);
}
/// <summary>
/// 扣除或者充值货币,没有事务
/// </summary>>
/// <param name="userId">用户Id</param>
/// <param name="userCurrencyType">货币类型</param>
/// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static bool ConsumeMoneyNoWork(int userId, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null)
{
var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.FirstOrDefault(it => it.UserId == userId && it.CurrencyType == (int)userCurrencyType);
if (userCurrency == null)
{
userCurrency = new T_User_Currency()
{
CreateAt = DateTime.Now,
CurrencyMoney = 0,
CurrencyName = userCurrencyType.ToString(),
CurrencyType = (int)userCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateAt = DateTime.Now,
UserId = userId
};
dao.daoDbMiaoYu.context.Add(userCurrency);
dao.daoDbMiaoYu.context.SaveChanges();
}
userCurrency.CurrencyMoney += money;
if (userCurrency.CurrencyMoney < 0)
{
//余额不足
throw new Exception("余额不足");
}
T_User_Currency_Log? log = null;
UserCurrencyConsumeType userCurrencyConsumeType = UserCurrencyConsumeType.;
if (money >= 0)
{
userCurrencyConsumeType = UserCurrencyConsumeType.;
}
if (userCurrencyType == UserCurrencyType.)
{
var mintes = DateTime.Now.AddMinutes(-5);
log = dao.daoDbMiaoYu.context.T_User_Currency_Log.Where(it => it.CreateTime > mintes).OrderByDescending(it => it.CreateTime).FirstOrDefault();
}
var tempMoney = Math.Abs(money);
//消费
if (log == null)
{
log = new T_User_Currency_Log()
{
Consume = tempMoney,
ConsumeType = (int)userCurrencyConsumeType,
CreateTime = DateTime.Now,
CurrencyType = (int)userCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateTime = DateTime.Now,
UserId = userId,
Remarks = ""
};
dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(log);
}
log.Remarks += $"于{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{userCurrencyConsumeType.ToString()}[{tempMoney}]{userCurrencyType.ToString()};";
if (log.Remarks.Length > 200)
{
log.Remarks = log.Remarks.Substring(log.Remarks.Length - 200);
}
dao.daoDbMiaoYu.context.SaveChanges();
if (_currency != null)
{
_currency.CurrencyMoney = userCurrency.CurrencyMoney;
_currency.UpdateAt = userCurrency.UpdateAt;
_currency.Id = userCurrency.Id;
_currency.CurrencyName = userCurrency.CurrencyName;
_currency.CreateAt = userCurrency.CreateAt;
_currency.CurrencyType = userCurrency.CurrencyType;
}
else
{
_currency = userCurrency;
}
return true;
}
#endregion
#region
/// <summary>
/// 扣除或者充值货币
/// </summary>
@ -90,6 +284,25 @@ namespace HuanMeng.MiaoYu.Code.Users
int userId = user.UserId;
return ConsumeMoney(userId, userCurrencyType, money, dao);
}
/// <summary>
/// 扣除或者充值货币
/// </summary>
/// <param name="user"></param>
/// <param name="userCurrencyType">货币类型</param>
/// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool ConsumeMoney(this T_User_Currency user, UserCurrencyType userCurrencyType, decimal money, DAO dao)
{
if (user == null || user.UserId == 0)
{
throw new ArgumentNullException("用户不能为空");
}
int userId = user.UserId;
return ConsumeMoney(userId, userCurrencyType, money, dao);
}
/// <summary>
@ -183,5 +396,8 @@ namespace HuanMeng.MiaoYu.Code.Users
}
return true;
}
#endregion
}
}

View File

@ -1,12 +1,21 @@
using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.EnumModel;
using HuanMeng.MiaoYu.Model.EnumModel.User;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using XLib.DotNetCore.CacheHelper;
namespace HuanMeng.MiaoYu.Code.Users
{
/// <summary>
@ -40,11 +49,270 @@ namespace HuanMeng.MiaoYu.Code.Users
}
}
/// <summary>
/// 货币
/// </summary>
public Dictionary<UserCurrencyType, T_User_Currency> UserCurrencys { get; set; }
/// <summary>
/// 获取用户货币信息
/// </summary>
/// <param name="userCurrencyType"></param>
/// <returns></returns>
[JsonIgnore]
public T_User_Currency this[UserCurrencyType userCurrencyType]
{
get
{
if (UserCurrencys == null)
{
UserCurrencys = new Dictionary<UserCurrencyType, T_User_Currency>();
var _currencuys = User.GetUserCurrencys(dao);
if (_currencuys != null)
{
foreach (var item in _currencuys)
{
UserCurrencys.Add((UserCurrencyType)item.CurrencyType, item);
}
}
}
if (!UserCurrencys.TryGetValue(userCurrencyType, out var t))
{
t = User.GetUserCurrency(userCurrencyType, dao);
if (t == null)
{
t = new T_User_Currency()
{
CurrencyType = (int)userCurrencyType,
CurrencyMoney = 0,
};
}
UserCurrencys.Add(userCurrencyType, t);
}
return t;
}
}
/// <summary>
/// 记忆卡
/// </summary>
public Dictionary<int, Dictionary<UserMemoryCardType, T_User_MemoryCard>>? UserMemoryCard { get; set; }
/// <summary>
/// 获取记忆卡
/// </summary>
/// <param name="userMemoryCardType"></param>
/// <param name="characterId"></param>
/// <returns></returns>
[JsonIgnore]
public T_User_MemoryCard? this[UserMemoryCardType userMemoryCardType, int characterId]
{
get
{
if (UserMemoryCard == null)
{
string key = $"{dao.daoDbMiaoYu.context.TenantInfo.TenantId}:User:{userId}:MemoryCard";
UserMemoryCard = MemoryCacheHelper.GetCache<Dictionary<int, Dictionary<UserMemoryCardType, T_User_MemoryCard>>>(key);
if (UserMemoryCard == null)
{
UserMemoryCard = new Dictionary<int, Dictionary<UserMemoryCardType, T_User_MemoryCard>>();
//获取当前用户所有的记忆卡
var _currencuys = dao.daoDbMiaoYu.context.T_User_MemoryCard.AsNoTracking().Where(it => it.UserId == userId && it.RemainingCount > 0).ToList();
if (_currencuys != null)
{
var characterIds = _currencuys.Select(it => it.CharacterId).Distinct().ToList();
foreach (var _characterId in characterIds)
{
var _temp = new Dictionary<UserMemoryCardType, T_User_MemoryCard>();
foreach (var item in _currencuys)
{
_temp.Add((UserMemoryCardType)item.MemoryCardType, item);
}
UserMemoryCard.Add(_characterId, _temp);
}
}
MemoryCacheHelper.SetCache(key, UserMemoryCard, 60 * 5);
}
}
T_User_MemoryCard? _memoryCard = null;
if (UserMemoryCard.TryGetValue(characterId, out var _m))
{
if (userMemoryCardType == UserMemoryCardType.)
{
if (_m.TryGetValue(UserMemoryCardType., out _memoryCard))
{
return _memoryCard;
}
if (_m.TryGetValue(UserMemoryCardType., out _memoryCard))
{
return _memoryCard;
}
if (_m.TryGetValue(UserMemoryCardType., out _memoryCard))
{
return _memoryCard;
}
}
else
{
if (_m.TryGetValue(userMemoryCardType, out _memoryCard))
{
return _memoryCard;
}
}
}
return _memoryCard;
}
}
/// <summary>
/// 验证余额是否大于0
/// </summary>
/// <param name="userCurrencyType"></param>
/// <param name="money"></param>
/// <returns></returns>
public bool IsCheckingSufficient(UserCurrencyType userCurrencyType, decimal money = 0)
{
if (this[userCurrencyType].CurrencyMoney > money)
{
return true;
}
return false;
}
/// <summary>
/// 获取当前角色记忆卡最大的token
/// </summary>
/// <param name="characterId"></param>
/// <returns></returns>
public (int maxToken, bool isMemoryCard) GetMemoryCardMaxToken(int characterId)
{
var _m = this[UserMemoryCardType., characterId];
if (_m != null && _m.RemainingCount > 0)
{
return (_m.MemoryCardToken, true);
}
return (UserMemoryCardType..GetUserMemoryCardTypeToken(), false);
}
}
public static class UserInfoExtend
{
/// <summary>
/// 记忆卡使用次数
/// </summary>
/// <param name="_memoryCard"></param>
/// <param name="useCount"></param>
/// <param name="dao"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static T_User_MemoryCard ConsumeMemoryCard(this T_User_MemoryCard _memoryCard, int useCount, DAO dao)
{
if (_memoryCard == null)
{
throw new ArgumentNullException("未找到记忆卡");
}
var memoryCard = ConsumeMemoryCard(_memoryCard.UserId, _memoryCard.CharacterId, (UserMemoryCardType)_memoryCard.MemoryCardType, useCount, dao, _memoryCard.Id);
_memoryCard.Id = memoryCard.Id;
_memoryCard.UserId = memoryCard.UserId;
_memoryCard.CharacterId = memoryCard.CharacterId;
_memoryCard.RemainingCount = memoryCard.RemainingCount;
_memoryCard.UseCount = useCount;
_memoryCard.Remark = memoryCard.Remark;
return memoryCard;
}
/// <summary>
/// 记忆卡使用次数
/// </summary>
/// <param name="userId"></param>
/// <param name="characterId"></param>
/// <param name="userMemoryCardType"></param>
/// <param name="useCount"></param>
/// <param name="dao"></param>
/// <param name="id"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static T_User_MemoryCard ConsumeMemoryCard(int userId, int characterId, UserMemoryCardType userMemoryCardType, int useCount, DAO dao, int id = 0)
{
T_User_MemoryCard? memoryCard = null;
if (id > 0)
{
memoryCard = dao.daoDbMiaoYu.context.T_User_MemoryCard.FirstOrDefault(it => it.Id == id);
}
if (memoryCard == null)
{
memoryCard = dao.daoDbMiaoYu.context.T_User_MemoryCard.FirstOrDefault(it => it.UserId == userId && it.CharacterId == characterId && it.MemoryCardType == (int)userMemoryCardType);
}
if (memoryCard == null)
{
memoryCard = new T_User_MemoryCard()
{
CharacterId = characterId,
CreateTime = DateTime.Now,
MemoryCardToken = userMemoryCardType.GetUserMemoryCardTypeToken(),
MemoryCardType = (int)userMemoryCardType,
RemainingCount = 0,
UseCount = 0,
Name = userMemoryCardType.ToString(),
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
Remark = "",
UpdateTime = DateTime.Now,
UserId = userId,
};
dao.daoDbMiaoYu.context.Add(memoryCard);
}
memoryCard.RemainingCount += useCount;
if (memoryCard.RemainingCount < 0)
{
throw new Exception("记忆卡使用次数不足");
}
if (useCount < 0)
{
//添加使用次数
var _useCount = Math.Abs(useCount);
memoryCard.UseCount += _useCount;
memoryCard.Remark += $"记忆卡使用{useCount}次;";
}
else
{
memoryCard.Remark += $"记忆卡添加{useCount};";
}
memoryCard.UpdateTime = DateTime.Now;
if (memoryCard.Remark.Length > 200)
{
memoryCard.Remark = memoryCard.Remark.Substring(memoryCard.Remark.Length - 200);
}
dao.daoDbMiaoYu.context.SaveChanges();
return memoryCard;
}
/// <summary>
/// 获取记忆卡的token数量
/// </summary>
/// <param name="userMemoryCardType"></param>
/// <returns></returns>
public static int GetUserMemoryCardTypeToken(this UserMemoryCardType userMemoryCardType)
{
if (userMemoryCardType == UserMemoryCardType.)
{
return 20000;
}
if (userMemoryCardType == UserMemoryCardType.)
{
return 15000;
}
if (userMemoryCardType == UserMemoryCardType.)
{
return 10000;
}
return 7000;
}
}
}

View File

@ -138,6 +138,11 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
/// </summary>
public virtual DbSet<T_User_Data> T_User_Data { get; set; }
/// <summary>
/// 用户记忆卡
/// </summary>
public virtual DbSet<T_User_MemoryCard> T_User_MemoryCard { get; set; }
/// <summary>
/// 手机号登录表
/// </summary>
@ -185,6 +190,7 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
.HasMaxLength(1000)
.HasComment("人物初始设定");
entity.Property(e => e.TenantId).HasComment("租户Id");
entity.Property(e => e.Token).HasComment("system最大的token数");
entity.Property(e => e.UpdateTime)
.HasComment("更新时间")
.HasColumnType("datetime");
@ -410,6 +416,7 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
entity.Property(e => e.TimeStamp)
.HasComment("发送时间")
.HasColumnType("datetime");
entity.Property(e => e.Tokens).HasComment("消耗的token");
entity.Property(e => e.Type).HasComment("0正常1重新生成2 删除");
entity.Property(e => e.UpdateTime)
.HasComment("更新时间")
@ -691,6 +698,7 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
.HasMaxLength(50)
.HasComment("会话名称");
entity.Property(e => e.TenantId).HasComment("租户");
entity.Property(e => e.TotalToken).HasComment("消耗的总token");
entity.Property(e => e.UpdateAt)
.HasComment("修改时间")
.HasColumnType("datetime");
@ -791,6 +799,37 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
}
});
modelBuilder.Entity<T_User_MemoryCard>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK__T_User_M__3214EC0706BA6604");
entity.ToTable(tb => tb.HasComment("用户记忆卡"));
entity.Property(e => e.CharacterId).HasComment("角色Id");
entity.Property(e => e.CreateTime)
.HasComment("创建时间")
.HasColumnType("datetime");
entity.Property(e => e.MemoryCardType).HasComment("记忆卡类型0初级1中级2高级");
entity.Property(e => e.Name)
.HasMaxLength(1)
.HasComment("记忆卡名称");
entity.Property(e => e.RemainingCount).HasComment("剩余次数");
entity.Property(e => e.Remark)
.HasMaxLength(1)
.HasComment("备注");
entity.Property(e => e.TenantId).HasComment("租户");
entity.Property(e => e.UpdateTime)
.HasComment("修改时间")
.HasColumnType("datetime");
entity.Property(e => e.UseCount).HasComment("已使用次数");
entity.Property(e => e.UserId).HasComment("用户Id");
//添加全局筛选器
if (this.TenantInfo != null)
{
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
}
});
modelBuilder.Entity<T_User_Phone_Account>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK__T_User_P__3214EC07987BDDB2");

View File

@ -77,4 +77,9 @@ public partial class T_Character: MultiTenantEntity
/// 对话性别
/// </summary>
public string? UserSex { get; set; }
/// <summary>
/// system最大的token数
/// </summary>
public int? Token { get; set; }
}

View File

@ -89,4 +89,9 @@ public partial class T_Chat: MultiTenantEntity
/// 人物模型,聊天返回的模型
/// </summary>
public string? ClaudeModel { get; set; }
/// <summary>
/// 消耗的token
/// </summary>
public int? Tokens { get; set; }
}

View File

@ -54,4 +54,9 @@ public partial class T_User_Chat: MultiTenantEntity
/// 最后一条消息
/// </summary>
public string? LastMessage { get; set; }
/// <summary>
/// 消耗的总token
/// </summary>
public int? TotalToken { get; set; }
}

View File

@ -0,0 +1,59 @@
using System;
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
/// <summary>
/// 用户记忆卡
/// </summary>
public partial class T_User_MemoryCard: MultiTenantEntity
{
public int Id { get; set; }
/// <summary>
/// 记忆卡名称
/// </summary>
public string Name { get; set; } = null!;
/// <summary>
/// 用户Id
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 角色Id
/// </summary>
public int CharacterId { get; set; }
/// <summary>
/// 剩余次数
/// </summary>
public int RemainingCount { get; set; }
/// <summary>
/// 已使用次数
/// </summary>
public int UseCount { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public DateTime UpdateTime { get; set; }
/// <summary>
/// 备注
/// </summary>
public string? Remark { get; set; }
/// <summary>
/// 记忆卡类型0初级1中级2高级
/// </summary>
public int MemoryCardType { get; set; }
public int MemoryCardToken { get; set; }
}

View File

@ -79,6 +79,11 @@ namespace HuanMeng.MiaoYu.Model.Dto.Chat
[SourceMember(nameof(CharacterCache.Label))]
public List<LabelDto> Label { get; set; }
/// <summary>
/// 记忆卡状态
/// </summary>
public bool MemoryCardState { get; set; }
/// <summary>
/// 余下聊天次数
/// </summary>

View File

@ -1,4 +1,5 @@
using HuanMeng.MiaoYu.Model.Dto.Character;
using System;
using System.Collections.Generic;
using System.Linq;
@ -61,7 +62,12 @@ namespace HuanMeng.MiaoYu.Model.Dto
/// <summary>
/// 相册
/// </summary>
public int Photographs { get; set; }
public int Photographs { get; set; }
/// <summary>
/// 记忆卡数量
/// </summary>
public int MemoryCard { get; set; }
}
/// <summary>

View File

@ -7,7 +7,7 @@ using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Model.EnumModel.User
{
/// <summary>
/// 用户货币类型
/// 用户货币类型
/// </summary>
public enum UserCurrencyType
{
@ -20,8 +20,13 @@ namespace HuanMeng.MiaoYu.Model.EnumModel.User
/// </summary>
= 1,
/// <summary>
///
/// 聊天次数
/// </summary>
= 2
= 2,
/// <summary>
/// 记忆卡数量
/// </summary>
= 3
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Model.EnumModel
{
/// <summary>
/// 用户会员卡类型
/// </summary>
public enum UserMemoryCardType
{
/// <summary>
/// 记忆卡
/// </summary>
= 0,
/// <summary>
///
/// </summary>
= 1,
/// <summary>
///
/// </summary>
= 2,
/// <summary>
///
/// </summary>
= 3
}
}