订单充值

This commit is contained in:
zpc 2024-08-28 15:53:49 +08:00
parent 71037c6c67
commit 49754cc173
8 changed files with 110 additions and 78 deletions

View File

@ -1,6 +1,8 @@
using HuanMeng.MiaoYu.Code.Cache.Special; using HuanMeng.MiaoYu.Code.Cache.Special;
using HuanMeng.MiaoYu.Code.DataAccess; using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Code.Payment; using HuanMeng.MiaoYu.Code.Payment;
using HuanMeng.MiaoYu.Code.Users;
using HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
using HuanMeng.MiaoYu.Model.Dto.Order; using HuanMeng.MiaoYu.Model.Dto.Order;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -22,6 +24,15 @@ namespace HuanMeng.MiaoYu.Code.Order
{ {
} }
/// <summary>
/// 创建订单
/// </summary>
/// <param name="paymentMethod"></param>
/// <param name="productId"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="NullReferenceException"></exception>
/// <exception cref="Exception"></exception>
public async Task<BaseResponse<IntentOrderDto>> CreateOrder(string paymentMethod, string productId) public async Task<BaseResponse<IntentOrderDto>> CreateOrder(string paymentMethod, string productId)
{ {
if (_UserId == 0) if (_UserId == 0)
@ -78,6 +89,21 @@ namespace HuanMeng.MiaoYu.Code.Order
return new BaseResponse<IntentOrderDto>(ResonseCode.Success, "", intentOrderDto); return new BaseResponse<IntentOrderDto>(ResonseCode.Success, "", intentOrderDto);
} }
/// <summary>
/// 获取订单状态
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
public async Task<BaseResponse<bool>> GetOrderRewardsInfo(string orderId)
{
var tips = await Dao.daoDbMiaoYu.context.T_OrderItems.Where(it => it.OrderId == orderId).Select(it => it.RewardTips).FirstOrDefaultAsync();
if (string.IsNullOrEmpty(tips))
{
return new BaseResponse<bool>(ResonseCode.Success, "", false);
}
return new BaseResponse<bool>(ResonseCode.Success, tips, true);
}
} }
/// <summary> /// <summary>
@ -98,62 +124,17 @@ namespace HuanMeng.MiaoYu.Code.Order
/// <returns></returns> /// <returns></returns>
public static async Task<bool> OrderRewardsAsync(this T_Products product, T_User user, string pay, string orderId, decimal price, DateTime intentDate, DAO dao) public static async Task<bool> OrderRewardsAsync(this T_Products product, T_User user, string pay, string orderId, decimal price, DateTime intentDate, DAO dao)
{ {
var userId = user.Id; using (IDbContextTransaction transaction = dao.daoDbMiaoYu.context.Database.BeginTransaction())
var chargeMoneyCount = dao.daoDbMiaoYu.context.T_Order.Count(it => it.UserId == userId && it.ProductId == product.ProductId);
var productReward = await dao.daoDbMiaoYu.context.T_Products_Reward.Where(it => it.ProductId == product.ProductId).ToListAsync();
if (productReward != null && productReward.Count > 0)
{ {
using (IDbContextTransaction transaction = dao.daoDbMiaoYu.context.Database.BeginTransaction()) try
{ {
try await OrderRewardsNoWorkAsync(product, user, pay, orderId, price, intentDate, dao);
{ await transaction.CommitAsync();
//List<T_User_Currency> user_Currencies = new List<T_User_Currency>(); }
foreach (var reward in productReward) catch (Exception ex)
{ {
var money = reward.Money; await transaction.RollbackAsync();
if (product.IsFirstCharge && chargeMoneyCount == 0) return false;
{
money = reward.FirstChargeMoney ?? reward.Money;
}
var currency = (UserCurrencyType)reward.CurrencyType;
var userCurrency = new T_User_Currency();
user.ConsumeMoneyNoWork(currency, money, dao, userCurrency, orderId);
}
T_Order order = new T_Order()
{
OrderId = orderId,
CreatedAt = DateTime.Now,
OrderDate = intentDate,
PaymentDate = DateTime.Now,
PaymentDay = DateOnly.FromDateTime(DateTime.Now),
PaymentMethod = pay,
ProductId = product.ProductId,
Status = (int)OrderState.,
TenantId = product.TenantId,
TotalPrice = price,
UpdatedAt = DateTime.Now,
UserId = userId,
};
T_OrderItems t_OrderItems = new T_OrderItems()
{
OrderId = orderId,
PaymentInfo = "",
Product = product.Id,
ProductId = product.ProductId,
RewardInfo = JsonConvert.SerializeObject(productReward),
TenantId = product.TenantId,
};
dao.daoDbMiaoYu.context.T_OrderItems.Add(t_OrderItems);
dao.daoDbMiaoYu.context.T_Order.Add(order);
await dao.daoDbMiaoYu.context.SaveChangesAsync();
await transaction.CommitAsync();
}
catch (Exception ex)
{
await transaction.RollbackAsync();
return false;
}
} }
} }
return true; return true;
@ -169,7 +150,7 @@ namespace HuanMeng.MiaoYu.Code.Order
/// <param name="intentDate"></param> /// <param name="intentDate"></param>
/// <param name="dao"></param> /// <param name="dao"></param>
/// <returns></returns> /// <returns></returns>
public static async Task OrderRewardsNoWorkAsync(this T_Products product, T_User user, string pay, string orderId, decimal price, DateTime intentDate, DAO dao) public static async Task OrderRewardsNoWorkAsync(this T_Products product, T_User user, string pay, string orderId, decimal price, DateTime intentDate, DAO dao, T_OrderItems orderItems = null)
{ {
var userId = user.Id; var userId = user.Id;
var chargeMoneyCount = dao.daoDbMiaoYu.context.T_Order.Count(it => it.UserId == userId && it.ProductId == product.ProductId); var chargeMoneyCount = dao.daoDbMiaoYu.context.T_Order.Count(it => it.UserId == userId && it.ProductId == product.ProductId);
@ -177,17 +158,22 @@ namespace HuanMeng.MiaoYu.Code.Order
if (productReward != null && productReward.Count > 0) if (productReward != null && productReward.Count > 0)
{ {
List<string> tips = new List<string>();
//List<T_User_Currency> user_Currencies = new List<T_User_Currency>();
foreach (var reward in productReward) foreach (var reward in productReward)
{ {
var money = reward.Money; var money = reward.Money;
if (product.IsFirstCharge && chargeMoneyCount == 0)
{
money = reward.FirstChargeMoney ?? reward.Money;
}
var currency = (UserCurrencyType)reward.CurrencyType; var currency = (UserCurrencyType)reward.CurrencyType;
var userCurrency = new T_User_Currency(); var userCurrency = new T_User_Currency();
user.ConsumeMoneyNoWork(currency, money, dao, userCurrency, orderId); user.ConsumeMoneyNoWork(currency, money, dao, userCurrency, orderId);
tips.Add($"获得{currency}*{money}");
if (product.IsFirstCharge && chargeMoneyCount == 0 && reward.FirstChargeMoney > 0)
{
user.ConsumeMoneyNoWork(currency, reward.FirstChargeMoney ?? 0, dao, userCurrency, orderId, $"首充赠送{currency}{reward.FirstChargeMoney}");
tips.Add($"首充赠送{currency}*{money}");
}
} }
var rewardTips = string.Join(',', tips.ToArray());
T_Order order = new T_Order() T_Order order = new T_Order()
{ {
OrderId = orderId, OrderId = orderId,
@ -203,16 +189,18 @@ namespace HuanMeng.MiaoYu.Code.Order
UpdatedAt = DateTime.Now, UpdatedAt = DateTime.Now,
UserId = userId, UserId = userId,
}; };
T_OrderItems t_OrderItems = new T_OrderItems() if (orderItems == null)
{ {
OrderId = orderId, orderItems = new T_OrderItems();
PaymentInfo = "", }
Product = product.Id, orderItems.OrderId = orderId;
ProductId = product.ProductId, orderItems.RewardTips = rewardTips;
RewardInfo = JsonConvert.SerializeObject(productReward), orderItems.Product = product.Id;
TenantId = product.TenantId, orderItems.TenantId = product.TenantId;
}; orderItems.ProductId = product.ProductId;
dao.daoDbMiaoYu.context.T_OrderItems.Add(t_OrderItems); orderItems.RewardInfo = JsonConvert.SerializeObject(productReward);
orderItems.RewardTips = rewardTips;
dao.daoDbMiaoYu.context.T_OrderItems.Add(orderItems);
dao.daoDbMiaoYu.context.T_Order.Add(order); dao.daoDbMiaoYu.context.T_Order.Add(order);
await dao.daoDbMiaoYu.context.SaveChangesAsync(); await dao.daoDbMiaoYu.context.SaveChangesAsync();
} }

View File

@ -105,17 +105,18 @@ namespace HuanMeng.MiaoYu.Code.Users
/// <param name="money">扣除金额(负数扣除,正数添加)</param> /// <param name="money">扣除金额(负数扣除,正数添加)</param>
/// <param name="dao">数据库</param> /// <param name="dao">数据库</param>
/// <param name="_currency"></param> /// <param name="_currency"></param>
/// <param name="orderId">订单号</param>
/// <param name="title"></param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="ArgumentNullException"></exception> /// <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, string orderId = "", string title = "")
public static bool ConsumeMoneyNoWork(this T_User user, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string remarks = "")
{ {
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, remarks); return ConsumeMoneyNoWork(userId, userCurrencyType, money, dao, _currency, orderId: orderId, title: title);
} }
/// <summary> /// <summary>
/// 扣除或者充值货币 /// 扣除或者充值货币
@ -170,7 +171,7 @@ namespace HuanMeng.MiaoYu.Code.Users
/// <param name="dao">数据库</param> /// <param name="dao">数据库</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 = "") public static bool ConsumeMoneyNoWork(int userId, UserCurrencyType userCurrencyType, decimal money, DAO dao, T_User_Currency? _currency = null, string remarks = "", string title = "", string orderId = "")
{ {
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 == userId && it.CurrencyType == (int)userCurrencyType);
if (userCurrency == null) if (userCurrency == null)
@ -207,6 +208,10 @@ namespace HuanMeng.MiaoYu.Code.Users
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(); 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); var tempMoney = Math.Abs(money);
if (string.IsNullOrEmpty(title))
{
title = $"{userCurrencyConsumeType}{money}{userCurrencyType}";
}
//消费 //消费
if (log == null) if (log == null)
{ {
@ -219,7 +224,9 @@ namespace HuanMeng.MiaoYu.Code.Users
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId, TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UpdateTime = DateTime.Now, UpdateTime = DateTime.Now,
UserId = userId, UserId = userId,
Remarks = remarks Remarks = remarks,
Title = title,
OrderId = orderId
}; };
dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(log); dao.daoDbMiaoYu.context.T_User_Currency_Log.Add(log);
} }

View File

@ -888,12 +888,14 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
entity.Property(e => e.OrderId) entity.Property(e => e.OrderId)
.HasMaxLength(64) .HasMaxLength(64)
.HasComment("订单id"); .HasComment("订单id");
entity.Property(e => e.PayUrl).HasComment("支付地址");
entity.Property(e => e.PaymentInfo).HasComment("支付信息"); entity.Property(e => e.PaymentInfo).HasComment("支付信息");
entity.Property(e => e.Product).HasComment("产品id、主键"); entity.Property(e => e.Product).HasComment("产品id、主键");
entity.Property(e => e.ProductId) entity.Property(e => e.ProductId)
.HasMaxLength(100) .HasMaxLength(100)
.HasComment("产品id"); .HasComment("产品id");
entity.Property(e => e.RewardInfo).HasComment("发放奖励信息"); entity.Property(e => e.RewardInfo).HasComment("发放奖励信息");
entity.Property(e => e.RewardTips).HasComment("发放奖励提示");
entity.Property(e => e.TenantId).HasComment("租户"); entity.Property(e => e.TenantId).HasComment("租户");
//添加全局筛选器 //添加全局筛选器
if (this.TenantInfo != null) if (this.TenantInfo != null)
@ -1118,10 +1120,12 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
.HasComment("创建时间") .HasComment("创建时间")
.HasColumnType("datetime"); .HasColumnType("datetime");
entity.Property(e => e.CurrencyType).HasComment("金额类型"); entity.Property(e => e.CurrencyType).HasComment("金额类型");
entity.Property(e => e.OrderId).HasMaxLength(64);
entity.Property(e => e.Remarks) entity.Property(e => e.Remarks)
.HasMaxLength(200) .HasMaxLength(200)
.HasComment("备注"); .HasComment("备注");
entity.Property(e => e.TenantId).HasComment("租户"); entity.Property(e => e.TenantId).HasComment("租户");
entity.Property(e => e.Title).HasMaxLength(200);
entity.Property(e => e.UpdateTime) entity.Property(e => e.UpdateTime)
.HasComment("修改时间") .HasComment("修改时间")
.HasColumnType("datetime"); .HasColumnType("datetime");

View File

@ -34,4 +34,14 @@ public partial class T_OrderItems: MultiTenantEntity
/// 支付信息 /// 支付信息
/// </summary> /// </summary>
public virtual string? PaymentInfo { get; set; } public virtual string? PaymentInfo { get; set; }
/// <summary>
/// 发放奖励提示
/// </summary>
public virtual string? RewardTips { get; set; }
/// <summary>
/// 支付地址
/// </summary>
public virtual string? PayUrl { get; set; }
} }

View File

@ -1,11 +1,11 @@
using System; using System;
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu; namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
/// <summary> /// <summary>
/// 用户货币表 /// 用户货币表
/// </summary> /// </summary>
public partial class T_User_Currency : MultiTenantEntity public partial class T_User_Currency: MultiTenantEntity
{ {
public virtual int Id { get; set; } public virtual int Id { get; set; }
@ -40,4 +40,4 @@ public partial class T_User_Currency : MultiTenantEntity
public virtual int UserId { get; set; } public virtual int UserId { get; set; }
public override Guid TenantId { get; set; } public override Guid TenantId { get; set; }
} }

View File

@ -45,4 +45,8 @@ public partial class T_User_Currency_Log: MultiTenantEntity
/// 修改时间 /// 修改时间
/// </summary> /// </summary>
public virtual DateTime UpdateTime { get; set; } public virtual DateTime UpdateTime { get; set; }
public virtual string? Title { get; set; }
public virtual string? OrderId { get; set; }
} }

View File

@ -5,6 +5,7 @@ using HuanMeng.MiaoYu.WebApi.Base;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace HuanMeng.MiaoYu.WebApi.Controllers namespace HuanMeng.MiaoYu.WebApi.Controllers
{ {
@ -31,5 +32,18 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
OrderBLL orderBLL = new OrderBLL(ServiceProvider); OrderBLL orderBLL = new OrderBLL(ServiceProvider);
return await orderBLL.CreateOrder(intentOrder.PaymentMethod, intentOrder.ProductId); return await orderBLL.CreateOrder(intentOrder.PaymentMethod, intentOrder.ProductId);
} }
/// <summary>
/// 获取订单状态
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
[HttpGet]
public async Task<BaseResponse<bool>> GetOrderRewardsInfo(string orderId)
{
OrderBLL orderBLL = new OrderBLL(ServiceProvider);
return await orderBLL.GetOrderRewardsInfo(orderId);
}
} }
} }

View File

@ -74,7 +74,7 @@ namespace HuanMeng.MiaoYu.WebPayApi.Controllers
//重复请求锁 //重复请求锁
var baseKey = $"pay:lock:{orderId}"; var baseKey = $"pay:lock:{orderId}";
var redis = RedisConnection.GetRedis(appConfig); var redis = RedisConnection.GetRedis(appConfig);
if (!redis.StringSetLock(baseKey, "", 3)) if (!redis.StringSetLock(baseKey, "", 10))
{ {
return "error;重复请求"; return "error;重复请求";
} }
@ -113,7 +113,10 @@ namespace HuanMeng.MiaoYu.WebPayApi.Controllers
{ {
try try
{ {
await product.OrderRewardsNoWorkAsync(user, pay, orderId, intentOrder.Price, intentOrder.IntentDate, dao); T_OrderItems orderItems = new T_OrderItems();
orderItems.PayUrl = context.Request.Path;
//orderItems.
await product.OrderRewardsNoWorkAsync(user, pay, orderId, intentOrder.Price, intentOrder.IntentDate, dao, orderItems);
intentOrder.Status = (int)OrderState.; intentOrder.Status = (int)OrderState.;
dao.daoDbMiaoYu.context.SaveChanges(); dao.daoDbMiaoYu.context.SaveChanges();
await dao.daoDbMiaoYu.context.SaveChangesAsync(); await dao.daoDbMiaoYu.context.SaveChangesAsync();
@ -122,7 +125,9 @@ namespace HuanMeng.MiaoYu.WebPayApi.Controllers
{ {
intentOrder.Status = (int)OrderState.; intentOrder.Status = (int)OrderState.;
dao.daoDbMiaoYu.context.SaveChanges(); dao.daoDbMiaoYu.context.SaveChanges();
logger.LogError($"请求支付回调接口,发货失败,请求路径: {context.Request.Path}", ex);
await dao.daoDbMiaoYu.context.SaveChangesAsync(); await dao.daoDbMiaoYu.context.SaveChangesAsync();
return $"error;出现异常{ex.Message}";
} }
} }
redis.KeyDelete(baseKey); redis.KeyDelete(baseKey);