提交代码

This commit is contained in:
zpc 2024-09-03 16:41:35 +08:00
parent e52c0742aa
commit fb4d1cc9d2
16 changed files with 326 additions and 119 deletions

View File

@ -17,6 +17,7 @@ using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Protocols; using Microsoft.IdentityModel.Protocols;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models; using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using HuanMeng.MiaoYu.Code.Payment; using HuanMeng.MiaoYu.Code.Payment;
using System.Collections.Frozen;
namespace HuanMeng.MiaoYu.Code.AppExtend namespace HuanMeng.MiaoYu.Code.AppExtend
{ {
@ -240,6 +241,64 @@ namespace HuanMeng.MiaoYu.Code.AppExtend
} }
#endregion #endregion
#region
/// <summary>
/// 测试账号数据
/// </summary>
public static ConcurrentDictionary<Guid, FrozenDictionary<string, int>>? TestAccountList { get; set; }
/// <summary>
/// 获取测试账号
/// </summary>
/// <param name="dao"></param>
/// <returns></returns>
public static FrozenDictionary<string, int> GetTestAccount(DAO dao)
{
if (TestAccountList == null)
{
TestAccountList = new ConcurrentDictionary<Guid, FrozenDictionary<string, int>>();
}
var t = dao.daoDbMiaoYu.context.TenantInfo.TenantId;
if (TestAccountList.ContainsKey(t))
{
return TestAccountList[t];
}
var dir = dao.daoDbMiaoYu.context.T_User.Where(it => it.IsTest == true && it.State == 0).Select(it =>
new
{
PhoneNumAccount = dao.daoDbMiaoYu.context.T_User_Phone_Account.FirstOrDefault(item => item.UserId == it.Id).PhoneNum,
userid = it.Id
}).Where(it => !string.IsNullOrEmpty(it.PhoneNumAccount)).ToDictionary(it => it.PhoneNumAccount, kvp => kvp.userid);
var f = dir.ToFrozenDictionary();
TestAccountList.TryAdd(t, f);
return f;
}
/// <summary>
/// 是否是测试账号
/// </summary>
/// <param name="phoneNum"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static bool IsTestAccount(string phoneNum, DAO dao)
{
var t = GetTestAccount(dao);
return t.ContainsKey(phoneNum);
}
/// <summary>
/// 是否是测试账号
/// </summary>
/// <param name="userId"></param>
/// <param name="dao"></param>
/// <returns></returns>
public static bool IsTestAccount(int userId, DAO dao)
{
var t = GetTestAccount(dao);
return t.Where(it => it.Value == userId).Any();
}
#endregion
} }
} }

View File

@ -216,7 +216,7 @@ namespace HuanMeng.MiaoYu.Code.Base
#endregion #endregion
#region #region
private RequestUserInfo _userInfo; private RequestUserInfo? _userInfo;
/// <summary> /// <summary>
/// 用户信息 /// 用户信息
/// </summary> /// </summary>
@ -227,17 +227,19 @@ namespace HuanMeng.MiaoYu.Code.Base
if (_userInfo == null) if (_userInfo == null)
{ {
var accessToken = HttpContextAccessor.HttpContext.GetTokenAsync("Bearer", "access_token").Result; var accessToken = HttpContextAccessor.HttpContext.GetTokenAsync("Bearer", "access_token").Result;
if (string.IsNullOrEmpty(accessToken)) if (string.IsNullOrEmpty(accessToken))
{ {
_userInfo = new RequestUserInfo() var authorizationHeader = HttpContextAccessor.HttpContext.Request.Headers["Authorization"].ToString();
if (!string.IsNullOrEmpty(authorizationHeader))
{ {
UserId = 0 accessToken = authorizationHeader.Replace("Bearer ", "").Trim();
};
} }
else }
if (!string.IsNullOrEmpty(accessToken))
{ {
var (principal, jwtToken) = JwtAuthManager.DecodeJwtToken(accessToken); var (principal, jwtToken) = JwtAuthManager.DecodeJwtToken(accessToken);
if (jwtToken == null || !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)) if (jwtToken == null)//|| !jwtToken.Header.Alg.Equals(SecurityAlgorithms.HmacSha256Signature)
{ {
throw new SecurityTokenException("无效的token"); throw new SecurityTokenException("无效的token");
} }
@ -248,13 +250,21 @@ namespace HuanMeng.MiaoYu.Code.Base
} }
var nickName = principal.FindFirst("NickName")?.Value; var nickName = principal.FindFirst("NickName")?.Value;
var userId = int.Parse(userIdStr); var userId = int.Parse(userIdStr);
_userInfo = new RequestUserInfo() this._userInfo = new RequestUserInfo()
{ {
UserId = userId, UserId = userId,
NickName = nickName NickName = nickName
}; };
} }
else
{
_userInfo = new RequestUserInfo()
{
UserId = 0
};
} }
}
return _userInfo; return _userInfo;
} }
} }

View File

@ -83,8 +83,9 @@ namespace HuanMeng.MiaoYu.Code.Character
&& it.CharacterId == info.CharacterId).FirstOrDefaultAsync(); && it.CharacterId == info.CharacterId).FirstOrDefaultAsync();
info.Intimacy = intimacys?.IntimacyValue ?? 0; info.Intimacy = intimacys?.IntimacyValue ?? 0;
UserInfoBLL userInfoBLL = new UserInfoBLL(Dao, _UserId); UserInfoBLL userInfoBLL = new UserInfoBLL(Dao, _UserId);
(var maxtoken, var memoryCardState) = userInfoBLL.GetMemoryCardMaxToken(requestCharacterInfo.CharacterId); (var maxtoken, var memoryCardState, var card) = userInfoBLL.GetMemoryCardMaxToken(requestCharacterInfo.CharacterId);
info.MemoryCardState = memoryCardState; info.MemoryCardState = memoryCardState;
info.MemoryCardCount = card?.RemainingCount ?? 0;
} }
return new BaseResponse<CharacterInfoDto>(ResonseCode.Success, "", info); return new BaseResponse<CharacterInfoDto>(ResonseCode.Success, "", info);
} }

View File

@ -1,3 +1,6 @@
using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Model.Dto.Character;
namespace HuanMeng.MiaoYu.Code.Chat; namespace HuanMeng.MiaoYu.Code.Chat;
/// <summary> /// <summary>
@ -231,7 +234,7 @@ public class ChatBLL : MiaoYuBase
List<ClaudeChatMessage> mess = new List<ClaudeChatMessage>(); List<ClaudeChatMessage> mess = new List<ClaudeChatMessage>();
int maxToken = 7000; int maxToken = 7000;
// var _memoryCardType = userInfoBLL[Model.EnumModel.UserMemoryCardType.记忆卡, charact.Id]; // var _memoryCardType = userInfoBLL[Model.EnumModel.UserMemoryCardType.记忆卡, charact.Id];
(maxToken, var isMemoryCard) = userInfoBLL.GetMemoryCardMaxToken(charact.Id); (maxToken, var isMemoryCard, var card) = userInfoBLL.GetMemoryCardMaxToken(charact.Id);
//await AddMessage(userChatSession, mess); //await AddMessage(userChatSession, mess);
//递归获取聊天记录 //递归获取聊天记录
var _token = await AddMessage(userChatSession.SessionId, _UserId, 1, 0, maxToken, mess); var _token = await AddMessage(userChatSession.SessionId, _UserId, 1, 0, maxToken, mess);
@ -269,7 +272,7 @@ public class ChatBLL : MiaoYuBase
#endregion #endregion
var claudeChatResponse = await Chat(charact, mess); var claudeChatResponse = await Chat(charact, mess);
if (claudeChatResponse.Message.Contains("香港") || claudeChatResponse.Message.Contains("台湾")|| claudeChatResponse.Message.Contains("摇头丸")) if (claudeChatResponse.Message.Contains("香港") || claudeChatResponse.Message.Contains("台湾") || claudeChatResponse.Message.Contains("摇头丸"))
{ {
var chatMessage = new ChatMessageDto() var chatMessage = new ChatMessageDto()
{ {
@ -307,7 +310,7 @@ public class ChatBLL : MiaoYuBase
Tokens = claudeChatResponse.OutputTokens Tokens = claudeChatResponse.OutputTokens
}; };
#region #region
using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction()) using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{ {
try try
{ {
@ -529,29 +532,6 @@ public class ChatBLL : MiaoYuBase
return true; 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) { };
//}
/// <summary> /// <summary>
/// 获取消息聊天记录列表 /// 获取消息聊天记录列表
@ -560,10 +540,9 @@ public class ChatBLL : MiaoYuBase
public async Task<BaseResponse<List<ChatHistoryInfo>>> GetChatHistoryList() public async Task<BaseResponse<List<ChatHistoryInfo>>> GetChatHistoryList()
{ {
var userChatSessions = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.UserId == _UserId && !it.IsDelete).ToListAsync(); var userChatSessions = await Dao.daoDbMiaoYu.context.T_User_Chat.Where(it => it.UserId == _UserId && !it.IsDelete).ToListAsync();
List<ChatHistoryInfo> chatHistoryInfos = new List<ChatHistoryInfo>(); List<ChatHistoryInfo> chatHistoryInfos = new List<ChatHistoryInfo>();
var charactersIds = MiaoYuCache.CharacterList.ToList(); var charactersIds = MiaoYuCache.CharacterList.ToList();
var memoryCard = Dao.daoDbMiaoYu.context.T_User_MemoryCard.AsNoTracking().Where(it => it.UserId == _UserId && it.RemainingCount > 0 && it.CharacterId > 0).Select(it => it.CharacterId).ToList();
userChatSessions.ForEach(it => userChatSessions.ForEach(it =>
{ {
var model = charactersIds.FirstOrDefault(item => item.Id == it.CharacterId); var model = charactersIds.FirstOrDefault(item => item.Id == it.CharacterId);
@ -571,8 +550,6 @@ public class ChatBLL : MiaoYuBase
{ {
var info = Mapper.Map<ChatHistoryInfo>(model); var info = Mapper.Map<ChatHistoryInfo>(model);
//获取最新的聊天记录
//var c = Dao.daoDbMiaoYu.context.T_Chat.Where(it => it.SessionId == it.SessionId).OrderByDescending(it => it.SendMessageDay).FirstOrDefault();
info.LastContactTime = it.UpdateAt; info.LastContactTime = it.UpdateAt;
info.LastMessage = it.LastMessage; info.LastMessage = it.LastMessage;
if (string.IsNullOrEmpty(info.LastMessage)) if (string.IsNullOrEmpty(info.LastMessage))
@ -587,11 +564,11 @@ public class ChatBLL : MiaoYuBase
info.LastMessage = Regex.Replace(info.LastMessage, pattern, ""); info.LastMessage = Regex.Replace(info.LastMessage, pattern, "");
} }
} }
if (memoryCard.Contains(it.CharacterId))
{
info.IsMemoryCard = true;
}
//if (c != null)
//{
// info.LastMessage = c.Content;
//}
chatHistoryInfos.Add(info); chatHistoryInfos.Add(info);
} }
}); });

View File

@ -36,7 +36,7 @@ namespace HuanMeng.MiaoYu.Code.MultiTenantUtil
MiaoYuMultiTenantConfig miaoYuMultiTenantConfig = new MiaoYuMultiTenantConfig(MiaoYu_SqlServer_Db); builder.Services.AddSingleton<MiaoYuMultiTenantConfig>(miaoYuMultiTenantConfig); MiaoYuMultiTenantConfig miaoYuMultiTenantConfig = new MiaoYuMultiTenantConfig(MiaoYu_SqlServer_Db); builder.Services.AddSingleton<MiaoYuMultiTenantConfig>(miaoYuMultiTenantConfig);
//添加单个租户的配置项 //添加单个租户的配置项
builder.Services.AddScoped<ITenantInfo,TenantInfo>(); builder.Services.AddScoped<ITenantInfo, TenantInfo>();
//添加系统数据库 //添加系统数据库
builder.Services.AddDbContext<MiaoYuContext>((serviceProvider, options) => builder.Services.AddDbContext<MiaoYuContext>((serviceProvider, options) =>
@ -53,6 +53,7 @@ namespace HuanMeng.MiaoYu.Code.MultiTenantUtil
} }
options options
.UseSqlServer(sunnySportConnectionString); .UseSqlServer(sunnySportConnectionString);
//
//options.UseSqlServer //options.UseSqlServer
}, ServiceLifetime.Scoped); }, ServiceLifetime.Scoped);

View File

@ -142,7 +142,7 @@ namespace HuanMeng.MiaoYu.Code.Order
{ {
throw new Exception("正在购买中"); throw new Exception("正在购买中");
} }
using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction()) using (IDbContextTransaction transaction = Dao.daoDbMiaoYu.context.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{ {
try try
{ {
@ -161,11 +161,24 @@ namespace HuanMeng.MiaoYu.Code.Order
var money = reward.Money; var money = reward.Money;
var currency = (UserCurrencyType)reward.CurrencyType; var currency = (UserCurrencyType)reward.CurrencyType;
var userCurrency = new T_User_Currency(); var userCurrency = new T_User_Currency();
var _log = new T_User_Currency_Log(); CurrencyTransactionParams currencyTransactionParams = new CurrencyTransactionParams()
user.ConsumeMoneyNoWork(currency, money, Dao, userCurrency, productId: productId, imageUrl: image, log: _log); {
_log.IsHide = true; UserCurrencyType = currency,
Money = money,
ImageUrl = image,
Currency = userCurrency,
Products = product
};
user.ConsumeMoneyNoWork(currencyTransactionParams, Dao);
if (currencyTransactionParams.Log != null)
{
currencyTransactionParams.Log.IsHide = true;
} }
} }
Dao.daoDbMiaoYu.context.SaveChanges();
}
} }
await transaction.CommitAsync(); await transaction.CommitAsync();

View File

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Users
{
/// <summary>
/// 货币交易的参数。
/// </summary>
public class CurrencyTransactionParams
{
/// <summary>
/// 用户Id
/// </summary>
public int UserId { get; set; }
/// <summary>
/// 货币类型
/// </summary>
public UserCurrencyType UserCurrencyType { get; set; }
/// <summary>
/// 扣除或添加的金额(负数为扣除,正数为充值)
/// </summary>
public decimal Money { get; set; }
/// <summary>
/// 交易备注
/// </summary>
public string Remarks { get; set; } = string.Empty;
/// <summary>
/// 交易标题
/// </summary>
public string Title { get; set; } = string.Empty;
/// <summary>
/// 关联的订单Id
/// </summary>
public string OrderId { get; set; } = string.Empty;
/// <summary>
/// 关联的产品Id
/// </summary>
public string? ProductId { get; set; } = string.Empty;
/// <summary>
/// 交易相关的图片URL
/// </summary>
public string? ImageUrl { get; set; } = string.Empty;
/// <summary>
/// 可选参数:现有的用户货币数据
/// </summary>
public T_User_Currency? Currency { get; set; }
/// <summary>
/// 可选参数:现有的货币日志
/// </summary>
public T_User_Currency_Log? Log { get; set; }
/// <summary>
/// 购买的产品
/// </summary>
public T_Products? Products { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using HuanMeng.DotNetCore.Base; using HuanMeng.DotNetCore.Base;
using HuanMeng.MiaoYu.Code.AppExtend;
using HuanMeng.MiaoYu.Code.DataAccess; using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Code.TencentUtile; using HuanMeng.MiaoYu.Code.TencentUtile;
using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract; using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract;
@ -103,7 +104,9 @@ namespace HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount
{ {
throw new ArgumentNullException("请输入验证码"); throw new ArgumentNullException("请输入验证码");
} }
if (phoneLoginParams.PhoneNumber == "999999999" && phoneLoginParams.VerificationCode == "123456")
if (phoneLoginParams.PhoneNumber == "999999999" && phoneLoginParams.VerificationCode == "123456" ||
AppConfigurationExtend.IsTestAccount(phoneLoginParams.PhoneNumber, dao))
{ {
//测试账号 //测试账号
} }
@ -132,7 +135,7 @@ namespace HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount
LastLoginAt = DateTime.Now, LastLoginAt = DateTime.Now,
LastLoginTypeAt = 1, LastLoginTypeAt = 1,
Email = "", Email = "",
NickName = "新用户", NickName = "新用户" + new Random().Next(111, 999),
PhoneNum = phoneLoginParams.PhoneNumber, PhoneNum = phoneLoginParams.PhoneNumber,
RegisterType = 1, RegisterType = 1,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId, TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,

View File

@ -173,7 +173,7 @@ namespace HuanMeng.MiaoYu.Code.Users
{ {
return new BaseResponse<List<TransactionDto>>(ResonseCode.Success, "", new List<TransactionDto>()); return new BaseResponse<List<TransactionDto>>(ResonseCode.Success, "", new List<TransactionDto>());
} }
var logs = await Dao.daoDbMiaoYu.context.T_User_Currency_Log.Where(it => it.UserId == _UserId && !(it.CurrencyType == (int)UserCurrencyType. && it.ConsumeType == 0) && !it.IsHide).OrderByDescending(it => it.Id).Take(50).ToListAsync(); var logs = await Dao.daoDbMiaoYu.context.T_User_Currency_Log.Where(it => it.UserId == _UserId && (it.CurrencyType == (int)UserCurrencyType. && it.ConsumeType == 1) && !it.IsHide).OrderByDescending(it => it.Id).Take(50).ToListAsync();
List<TransactionDto> list = new List<TransactionDto>(); List<TransactionDto> list = new List<TransactionDto>();
foreach (var item in logs) foreach (var item in logs)
{ {
@ -182,10 +182,9 @@ namespace HuanMeng.MiaoYu.Code.Users
transactionDto.TransactionTime = item.CreateTime; transactionDto.TransactionTime = item.CreateTime;
transactionDto.CurrencyType = item.CurrencyType; transactionDto.CurrencyType = item.CurrencyType;
transactionDto.TransactionContent = item.Title; transactionDto.TransactionContent = item.Title;
transactionDto.TransactionAmount = $"{item.Consume}{(item.CurrencyType == 1 ? UserCurrencyType.语珠.ToString() : "")}"; transactionDto.TransactionAmount = $"{(item.Consume > 0 ? "+" : "")}{item.Consume:D2}{(item.CurrencyType == 1 ? UserCurrencyType.语珠.ToString() : "")}";
list.Add(transactionDto); list.Add(transactionDto);
} }
//var obj = JsonConvert.DeserializeObject<List<TransactionDto>>("[{\"TransactionContent\":\"购买记忆提升道具卡\",\"TransactionTime\":\"2024-07-18 12:58:52.963\",\"TransactionAmount\":\"-10\",\"TransactionType\":0,\"CurrencyType\":0},{\"TransactionContent\":\"充值语珠\",\"TransactionTime\":\"2024-07-17 12:58:52.963\",\"TransactionAmount\":\"+100\",\"TransactionType\":0,\"CurrencyType\":0},{\"TransactionContent\":\"充值语珠\",\"TransactionTime\":\"2024-07-16 12:58:52.963\",\"TransactionAmount\":\"+200\",\"TransactionType\":0,\"CurrencyType\":0}]");
return new BaseResponse<List<TransactionDto>>(ResonseCode.Success, "", list); return new BaseResponse<List<TransactionDto>>(ResonseCode.Success, "", list);
} }
/// <summary> /// <summary>

View File

@ -110,16 +110,32 @@ namespace HuanMeng.MiaoYu.Code.Users
/// <param name="title"></param> /// <param name="title"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
public static bool ConsumeMoneyNoWork(this T_User user, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string orderId = "", string title = "", string productId = "", string imageUrl = "" public static bool ConsumeMoneyNoWork(this T_User user, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string orderId = "", string title = "")
,
T_User_Currency_Log? log = null)
{ {
if (user == null || user.Id == 0) if (user == null || user.Id == 0)
{ {
throw new ArgumentNullException("用户不能为空"); throw new ArgumentNullException("用户不能为空");
} }
int userId = user.Id; int userId = user.Id;
return ConsumeMoneyNoWork(userId, userCurrencyType, money, dao, _currency, orderId: orderId, title: title, productId: productId, imageUrl: imageUrl, log: log); return ConsumeMoneyNoWork(userId, userCurrencyType, money, dao, _currency, orderId: orderId, title: title);
}
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="param"></param>
/// <param name="dao"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public static bool ConsumeMoneyNoWork(this T_User user, CurrencyTransactionParams param, DAO dao)
{
if (user == null || user.Id == 0)
{
throw new ArgumentNullException("用户不能为空");
}
param.UserId = user.Id;
return ConsumeMoneyNoWork(param, dao);
} }
/// <summary> /// <summary>
/// 扣除或者充值货币 /// 扣除或者充值货币
@ -191,6 +207,7 @@ namespace HuanMeng.MiaoYu.Code.Users
} }
return UserMemoryCardType.; return UserMemoryCardType.;
} }
/// <summary> /// <summary>
/// 扣除或者充值货币,没有事务 /// 扣除或者充值货币,没有事务
/// </summary>> /// </summary>>
@ -206,119 +223,166 @@ namespace HuanMeng.MiaoYu.Code.Users
/// <param name="imageUrl"></param> /// <param name="imageUrl"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="Exception"></exception> /// <exception cref="Exception"></exception>
public static bool ConsumeMoneyNoWork(int userId, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string remarks = "", string title = "", string orderId = "", string productId = "", string imageUrl = "", public static bool ConsumeMoneyNoWork(int userId, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string remarks = "", string title = "", string orderId = "")
T_User_Currency_Log? log = null)
{ {
bool isJiyika = false; CurrencyTransactionParams currencyTransactionParams = new CurrencyTransactionParams()
//记忆卡特殊处理
if (MUserCurrencyType.Contains(userCurrencyType) && money > 0)
{ {
isJiyika = true; UserId = userId,
var memoryCardType = userCurrencyType.GetUserMemoryCardType(); UserCurrencyType = userCurrencyType,
T_User_MemoryCard t_User_MemoryCard = new T_User_MemoryCard()
Money = money,
OrderId = orderId,
Remarks = remarks,
Title = title,
Currency = _currency
};
if (ConsumeMoneyNoWork(currencyTransactionParams, dao))
{ {
RemainingCount = (int)money, _currency = currencyTransactionParams.Currency;
return true;
}
return false;
}
/// <summary>
/// 扣除或充值货币,无事务处理。
/// </summary>
/// <param name="transactionParams">货币交易的参数</param>
/// <param name="dao"></param>
/// <returns>成功时返回 true</returns>
/// <exception cref="Exception">当余额不足时抛出异常</exception>
public static bool ConsumeMoneyNoWork(CurrencyTransactionParams transactionParams, DAO dao)
{
bool isMemoryCardTransaction = false;
// 记忆卡交易的特殊处理
if (MUserCurrencyType.Contains(transactionParams.UserCurrencyType) && transactionParams.Money > 0)
{
isMemoryCardTransaction = true;
var memoryCardType = transactionParams.UserCurrencyType.GetUserMemoryCardType();
T_User_MemoryCard memoryCard = new T_User_MemoryCard()
{
RemainingCount = (int)transactionParams.Money,
CharacterId = 0, CharacterId = 0,
MemoryCardToken = memoryCardType.GetUserMemoryCardTypeToken(), MemoryCardToken = memoryCardType.GetUserMemoryCardTypeToken(),
CreateTime = DateTime.Now, CreateTime = DateTime.Now,
MemoryCardType = (int)memoryCardType, MemoryCardType = (int)memoryCardType,
UseCount = 0, UseCount = 0,
Name = userCurrencyType.ToString(), Name = transactionParams.Products?.ProductName ?? transactionParams.UserCurrencyType.ToString(),
PopId = productId, PopId = transactionParams.Products?.ProductId ?? transactionParams.ProductId,
Remark = remarks, Remark = transactionParams.Remarks,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId, TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateTime = DateTime.Now, UpdateTime = DateTime.Now,
UserId = userId, UserId = transactionParams.UserId,
Image = imageUrl Image = transactionParams.ImageUrl
}; };
dao.daoDbMiaoYu.context.T_User_MemoryCard.Add(t_User_MemoryCard); dao.daoDbMiaoYu.context.T_User_MemoryCard.Add(memoryCard);
money = 1; var mlog = new T_User_Currency_Log()
{
Consume = 1,
ConsumeType = (int)UserCurrencyConsumeType.,
CreateTime = DateTime.Now,
CurrencyType = (int)transactionParams.UserCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateTime = DateTime.Now,
UserId = transactionParams.UserId,
Remarks = transactionParams.Remarks,
Title = $"{transactionParams.UserCurrencyType}",
OrderId = transactionParams.OrderId,
IsHide = false
};
mlog.Remarks += $"于{DateTime.Now:yyyy-MM-dd HH:mm:ss}购买[{transactionParams.UserCurrencyType}][{Math.Abs(transactionParams.Money)}]";
dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(mlog);
transactionParams.Log = mlog;
dao.daoDbMiaoYu.context.SaveChanges();
return true;
//transactionParams.Money = 1;
} }
var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.FirstOrDefault(it => it.UserId == userId && it.CurrencyType == (int)userCurrencyType); var userCurrency = dao.daoDbMiaoYu.context.T_User_Currency.FirstOrDefault(it => it.UserId == transactionParams.UserId && it.CurrencyType == (int)transactionParams.UserCurrencyType);
if (userCurrency == null) if (userCurrency == null)
{ {
userCurrency = new T_User_Currency() userCurrency = new T_User_Currency()
{ {
CreateAt = DateTime.Now, CreateAt = DateTime.Now,
CurrencyMoney = 0, CurrencyMoney = 0,
CurrencyName = userCurrencyType.ToString(), CurrencyName = transactionParams.UserCurrencyType.ToString(),
CurrencyType = (int)userCurrencyType, CurrencyType = (int)transactionParams.UserCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId, TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateAt = DateTime.Now, UpdateAt = DateTime.Now,
UserId = userId UserId = transactionParams.UserId
}; };
dao.daoDbMiaoYu.context.Add(userCurrency); dao.daoDbMiaoYu.context.Add(userCurrency);
dao.daoDbMiaoYu.context.SaveChanges(); dao.daoDbMiaoYu.context.SaveChanges();
} }
userCurrency.CurrencyMoney += money; userCurrency.CurrencyMoney += transactionParams.Money;
if (userCurrency.CurrencyMoney < 0) if (userCurrency.CurrencyMoney < 0)
{ {
//余额不足
throw new Exception("余额不足"); throw new Exception("余额不足");
} }
UserCurrencyConsumeType consumeType = transactionParams.Money >= 0 ? UserCurrencyConsumeType. : UserCurrencyConsumeType.;
UserCurrencyConsumeType userCurrencyConsumeType = UserCurrencyConsumeType.; T_User_Currency_Log? log = null;
if (money >= 0) if (transactionParams.UserCurrencyType == UserCurrencyType. && consumeType == UserCurrencyConsumeType.)
{ {
userCurrencyConsumeType = UserCurrencyConsumeType.; var recentLogs = DateTime.Now.AddMinutes(-5);
log = dao.daoDbMiaoYu.context.T_User_Currency_Log
.Where(it => it.CreateTime > recentLogs && it.ConsumeType == (int)UserCurrencyConsumeType. && it.CurrencyType == (int)transactionParams.UserCurrencyType)
.OrderByDescending(it => it.CreateTime)
.FirstOrDefault();
} }
if (userCurrencyType == UserCurrencyType. && userCurrencyConsumeType == UserCurrencyConsumeType.) if (string.IsNullOrEmpty(transactionParams.Title) && !isMemoryCardTransaction)
{ {
var mintes = DateTime.Now.AddMinutes(-5); transactionParams.Title = $"{consumeType}{transactionParams.Money}{transactionParams.UserCurrencyType}";
log = dao.daoDbMiaoYu.context.T_User_Currency_Log.Where(it => it.CreateTime > mintes && it.ConsumeType == (int)UserCurrencyConsumeType. && it.CurrencyType == (int)userCurrencyType).OrderByDescending(it => it.CreateTime).FirstOrDefault();
} }
var tempMoney = Math.Abs(money);
if (string.IsNullOrEmpty(title) && !isJiyika)
{
title = $"{userCurrencyConsumeType}{money}{userCurrencyType}";
}
//消费
if (log == null) if (log == null)
{ {
log = new T_User_Currency_Log() log = new T_User_Currency_Log()
{ {
Consume = 0, Consume = 0,
ConsumeType = (int)userCurrencyConsumeType, ConsumeType = (int)consumeType,
CreateTime = DateTime.Now, CreateTime = DateTime.Now,
CurrencyType = (int)userCurrencyType, CurrencyType = (int)transactionParams.UserCurrencyType,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId, TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateTime = DateTime.Now, UpdateTime = DateTime.Now,
UserId = userId, UserId = transactionParams.UserId,
Remarks = remarks, Remarks = transactionParams.Remarks,
Title = title, Title = transactionParams.Title,
OrderId = orderId, OrderId = transactionParams.OrderId,
IsHide = false IsHide = false
}; };
dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(log); dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(log);
} }
log.Consume += money;
log.Remarks += $"于{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}{userCurrencyConsumeType.ToString()}[{tempMoney}]{userCurrencyType.ToString()};"; log.Consume += transactionParams.Money;
log.Remarks += $"于{DateTime.Now:yyyy-MM-dd HH:mm:ss}{consumeType}[{Math.Abs(transactionParams.Money)}]{transactionParams.UserCurrencyType};";
if (log.Remarks.Length > 200) if (log.Remarks.Length > 200)
{ {
log.Remarks = log.Remarks.Substring(log.Remarks.Length - 200); log.Remarks = transactionParams.Log.Remarks[^200..];
} }
dao.daoDbMiaoYu.context.SaveChanges(); dao.daoDbMiaoYu.context.SaveChanges();
if (_currency != null)
if (transactionParams.Currency != null)
{ {
_currency.CurrencyMoney = userCurrency.CurrencyMoney; transactionParams.Currency.CurrencyMoney = userCurrency.CurrencyMoney;
_currency.UpdateAt = userCurrency.UpdateAt; transactionParams.Currency.UpdateAt = userCurrency.UpdateAt;
_currency.Id = userCurrency.Id; transactionParams.Currency.Id = userCurrency.Id;
_currency.CurrencyName = userCurrency.CurrencyName; transactionParams.Currency.CurrencyName = userCurrency.CurrencyName;
_currency.CreateAt = userCurrency.CreateAt; transactionParams.Currency.CreateAt = userCurrency.CreateAt;
_currency.CurrencyType = userCurrency.CurrencyType; transactionParams.Currency.CurrencyType = userCurrency.CurrencyType;
} }
else else
{ {
_currency = userCurrency; transactionParams.Currency = userCurrency;
} }
transactionParams.Log = log;
return true; return true;
} }
#endregion #endregion
#region #region
/// <summary> /// <summary>

View File

@ -149,17 +149,18 @@ namespace HuanMeng.MiaoYu.Code.Users
if (_m.TryGetValue(UserMemoryCardType., out _memoryCards)) if (_m.TryGetValue(UserMemoryCardType., out _memoryCards))
{ {
return _memoryCards[0];
return _memoryCards.FirstOrDefault(it => it.RemainingCount > 0);
} }
if (_m.TryGetValue(UserMemoryCardType., out _memoryCards)) if (_m.TryGetValue(UserMemoryCardType., out _memoryCards))
{ {
return _memoryCards[0]; return _memoryCards.FirstOrDefault(it => it.RemainingCount > 0);
} }
if (_m.TryGetValue(UserMemoryCardType., out _memoryCards)) if (_m.TryGetValue(UserMemoryCardType., out _memoryCards))
{ {
return _memoryCards[0]; return _memoryCards.FirstOrDefault(it => it.RemainingCount > 0);
} }
} }
else else
@ -195,14 +196,14 @@ namespace HuanMeng.MiaoYu.Code.Users
/// </summary> /// </summary>
/// <param name="characterId"></param> /// <param name="characterId"></param>
/// <returns></returns> /// <returns></returns>
public (int maxToken, bool isMemoryCard) GetMemoryCardMaxToken(int characterId) public (int maxToken, bool isMemoryCard, T_User_MemoryCard? card) GetMemoryCardMaxToken(int characterId)
{ {
var _m = this[UserMemoryCardType., characterId]; var _m = this[UserMemoryCardType., characterId];
if (_m != null && _m.RemainingCount > 0) if (_m != null && _m.RemainingCount > 0)
{ {
return (_m.MemoryCardToken, true); return (_m.MemoryCardToken, true, _m);
} }
return (UserMemoryCardType..GetUserMemoryCardTypeToken(), false); return (UserMemoryCardType..GetUserMemoryCardTypeToken(), false, null);
} }
} }

View File

@ -83,7 +83,10 @@ namespace HuanMeng.MiaoYu.Model.Dto.Chat
/// 记忆卡状态 /// 记忆卡状态
/// </summary> /// </summary>
public bool MemoryCardState { get; set; } public bool MemoryCardState { get; set; }
/// <summary>
/// 记忆卡剩余次数
/// </summary>
public int MemoryCardCount { get; set; }
/// <summary> /// <summary>
/// 余下聊天次数 /// 余下聊天次数
/// </summary> /// </summary>

View File

@ -57,5 +57,10 @@ namespace HuanMeng.MiaoYu.Model.Dto.Chat
/// </summary> /// </summary>
public string LastMessage { get; set; } public string LastMessage { get; set; }
/// <summary>
/// 是否有记忆卡
/// </summary>
public bool IsMemoryCard { get; set; }
} }
} }

View File

@ -11,6 +11,7 @@ namespace HuanMeng.MiaoYu.Model.Dto
/// </summary> /// </summary>
public class RequestUserInfo public class RequestUserInfo
{ {
public RequestUserInfo() { }
/// <summary> /// <summary>
/// 昵称 /// 昵称
/// </summary> /// </summary>

View File

@ -3,6 +3,7 @@ using HuanMeng.MiaoYu.Code.Order;
using HuanMeng.MiaoYu.Model.Dto.Order; using HuanMeng.MiaoYu.Model.Dto.Order;
using HuanMeng.MiaoYu.WebApi.Base; using HuanMeng.MiaoYu.WebApi.Base;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -14,7 +15,7 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
/// </summary> /// </summary>
[Route("api/[controller]/[action]")] [Route("api/[controller]/[action]")]
[ApiController] [ApiController]
[Authorize]
public class PaymentController : MiaoYuControllerBase public class PaymentController : MiaoYuControllerBase
{ {
public PaymentController(IServiceProvider _serviceProvider) : base(_serviceProvider) public PaymentController(IServiceProvider _serviceProvider) : base(_serviceProvider)

View File

@ -109,7 +109,7 @@ namespace HuanMeng.MiaoYu.WebPayApi.Controllers
await dao.daoDbMiaoYu.context.SaveChangesAsync(); await dao.daoDbMiaoYu.context.SaveChangesAsync();
return $"error;用户不存在"; return $"error;用户不存在";
} }
using (IDbContextTransaction transaction = dao.daoDbMiaoYu.context.Database.BeginTransaction()) using (IDbContextTransaction transaction = dao.daoDbMiaoYu.context.Database.BeginTransaction(System.Data.IsolationLevel.RepeatableRead))
{ {
try try
{ {