Merge pull request 'dev' (#3) from dev into main

Reviewed-on: #3
This commit is contained in:
西街长安 2025-08-05 16:10:40 +08:00
commit b181972df4
5 changed files with 93 additions and 8 deletions

View File

@ -17,16 +17,17 @@ namespace Apimanager_backend.Controllers
private IOrderService _orderService;
private IPaymentConfigService _paymentService;
private IPayService _payService;
public PayController(ILogger<PayController> logger,IOrderService order,IPaymentConfigService paymentConfigService,IPayService payService)
public PayController(ILogger<PayController> logger, IOrderService order, IPaymentConfigService paymentConfigService, IPayService payService)
{
_logger = logger;
_orderService = order;
_paymentService = paymentConfigService;
_payService = payService;
}
//创建支付订单
[HttpPost]
[Authorize(Roles = "User")]
public async Task<IActionResult> CreatePayment([FromBody]CreatePaymentDto dto)
public async Task<IActionResult> CreatePayment([FromBody] CreatePaymentDto dto)
{
var userId = User.Claims.First(x => x.Type == "userId").Value;
//获取支付接口信息
@ -41,17 +42,18 @@ namespace Apimanager_backend.Controllers
switch (paymentConfig.PayType)
{
case PayType.None:
throw new BaseException(4001,"当前支付方式未配置");
throw new BaseException(4001, "当前支付方式未配置");
case PayType.Epay:
var epayRes = await _payService.CreateEpay(orderRes, paymentConfig,dto.ReturnUrl);
var epayRes = await _payService.CreateEpay(orderRes, paymentConfig, dto.ReturnUrl);
return Ok(epayRes);
default:
throw new BaseException(4001, "不支持的支付方式");
}
}
//支付完成通知
[HttpGet]
public async Task<IActionResult> Notice(
int pid, string trade_no,string out_trade_no
int pid, string trade_no, string out_trade_no
, string type, string name, decimal money
, string trade_status, string sign, string sign_type
)
@ -66,8 +68,9 @@ namespace Apimanager_backend.Controllers
param["trade_status"] = trade_status;
param["sign"] = sign;
param["sign_type"] = sign_type;
//获取支付配置key用于签名校验
PaymentConfig paymentConfig = await _paymentService.GetPaymentConfigInfoByTypeAsync(type);
bool verifyRes = EpayHelper.VerifySign(param,paymentConfig.SecretKey);
bool verifyRes = EpayHelper.VerifySign(param, paymentConfig.SecretKey);
if (!verifyRes)
{
throw new BaseException(4001, "签名校验失败");
@ -79,5 +82,16 @@ namespace Apimanager_backend.Controllers
await _orderService.UpdateOrderAsync(orderDto);
return Ok("Success");
}
[HttpPost]
[Authorize( Roles = "User")]
public async Task<IActionResult> Buy([FromBody]BuyDto dto)
{
var userId = User.Claims.First(x => x.Type == "userId").Value;
dto.UserId = int.Parse(userId);
await _payService.BuyAsync(dto);
var res = new ResponseBase<object?>(1000,"订购成功",null);
return Ok(res);
}
}
}

View File

@ -0,0 +1,11 @@
using System.ComponentModel.DataAnnotations;
namespace Apimanager_backend.Dtos
{
public class BuyDto
{
public int UserId { get; set; }
[Required]
public int ApiPackageId { get; set; }
}
}

View File

@ -6,5 +6,6 @@ namespace Apimanager_backend.Services
public interface IPayService
{
Task<PayReturnData> CreateEpay(Order order,PaymentConfig paymentConfig,string returnUrl);
Task<bool> BuyAsync(BuyDto dto);
}
}

View File

@ -79,6 +79,7 @@ namespace Apimanager_backend.Services
#region
public async Task<bool> UpdateOrderAsync(OrderDto order)
{
var transaction = await _apiContext.Database.BeginTransactionAsync();
try
{
var data = await _apiContext.Orders.SingleOrDefaultAsync(x => x.OrderNumber == order.OrderNumber || x.ThirdPartyOrderId == order.ThirdPartyOrderId);
@ -89,13 +90,22 @@ namespace Apimanager_backend.Services
data.UpdatedAt = DateTime.Now;
data.Status = order.Status;
data.PaiAt = order.Status == OrderStatus.Completed ? DateTime.Now : null;
var user = await _apiContext.Users.FirstOrDefaultAsync(x => x.Id == order.UserId);
if (user == null)
{
throw new BaseException(2004, "用户未找到");
}
user.Balance += order.Amount;
_apiContext.Orders.Update(data);
_apiContext.Users.Update(user);
await _apiContext.SaveChangesAsync();
await transaction.CommitAsync();
return true;
}catch(Exception e)
{
await transaction.RollbackAsync();
logger.LogError(e.Message);
throw new BaseException(4003, "订单未找到");
throw;
}
}
#endregion

View File

@ -13,12 +13,61 @@ namespace Apimanager_backend.Services
private IMapper _mapper;
private ILogger<PayService> _logger;
private ApiContext _context;
public PayService(IMapper mapper,ILogger<PayService> logger,ApiContext apiContext)
public PayService(IMapper mapper,ILogger<PayService> logger,
ApiContext apiContext)
{
_mapper = mapper;
_logger = logger;
_context = apiContext;
}
public async Task<bool> BuyAsync(BuyDto dto)
{
var transaction = await _context.Database.BeginTransactionAsync();
try
{
var package = await _context.Apipackages.FirstOrDefaultAsync(x => x.Id == dto.ApiPackageId);
if (package == null) throw new BaseException(4004,"套餐未找到");
var user = await _context.Users.FirstOrDefaultAsync(x => x.Id == dto.UserId);
if (user == null) throw new BaseException(2004,"用户不存在");
if (user.Balance < package.Price)
{
throw new BaseException(4002, "支付失败,余额不足。");
}
var uPackage = await _context.UserPackages.FirstOrDefaultAsync(x => x.UserId == dto.UserId && x.PackageId == dto.ApiPackageId);
if (uPackage == null)
{
UserPackage userPackage = new UserPackage();
userPackage.UserId = dto.UserId;
userPackage.PackageId = dto.ApiPackageId;
userPackage.RemainingCalls = package.CallLimit;
userPackage.ExpiryDate = DateTime.Now.AddMonths(1);
await _context.UserPackages.AddAsync(userPackage);
}
else
{
var baseDate = uPackage.ExpiryDate > DateTime.Now ? uPackage.ExpiryDate : DateTime.Now;
_context.UserPackages.Update(uPackage);
}
user.Balance -= package.Price;
_context.Users.Update(user);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return true;
}catch(Exception e) when(!(e is BaseException))
{
await transaction.RollbackAsync();
_logger.LogError(e,"购买套餐失败:{Message}",e.Message);
throw new BaseException(1005,"服务器内部错误");
}
catch (BaseException)
{
await transaction.RollbackAsync();
throw;
}
}
public async Task<PayReturnData> CreateEpay(Order order, PaymentConfig paymentConfig,string returnUrl)
{
try