self_mall_api/ARW.Service/Api/BusinessService/PayManage/PayServiceApi.cs
2023-10-14 15:18:59 +08:00

377 lines
15 KiB
C#

using Infrastructure.Attribute;
using System.Threading.Tasks;
using ARW.Repository.Business.ShopManager.Shops;
using ARW.Repository.Business.GoodsManager.GoodsCategorys;
using ARW.Repository.Business.Custom.Customers;
using ARW.Model.Models.Business.Payments;
using Infrastructure;
using static Infrastructure.WeChat.TenPay.Pay;
using Infrastructure.WeChat.TenPay;
using Senparc.CO2NET.HttpUtility;
using ARW.Service.Api.IBusinessService.PayManage;
using ARW.Repository.Business.Payments;
using ARW.Repository.Business.OrderManage.Orders;
using ARW.Repository.Business.Marketing.CouponManage.Coupons;
using ARW.Model.Dto.Api.Pay;
using ARW.Repository.Business.Carts;
using ARW.Repository.Business.GoodsManager.Goodss;
using ARW.Repository.Business.GoodsManager.GoodsSpecs.GoodsSkus;
using ARW.Service.Api.IBusinessService.GoodsManager.Goodss;
using ARW.Model.Dto.Api.GoodsManager.Goodss;
using ARW.Model.Models.Business.OrderManage.OrderGoodss;
using ARW.Repository.Business.OrderManage.OrderGoodss;
using ARW.Repository.Business.OrderManage.OrderCustomerAddreses;
using ARW.Repository.Business.Custom.CustomerAddresses;
using ARW.Model.Models.Business.OrderManage.OrderCustomerAddreses;
using ARW.Model.Models.Business.GoodsManager.Goodss;
namespace ARW.Service.Api.BusinessService.PaymentManage
{
/// <summary>
/// 支付业务实现类Api
///
/// @author lwh
/// @date 2023-06-12
/// </summary>
[AppService(ServiceType = typeof(IPayServiceApi), ServiceLifetime = LifeTime.Transient)]
public class PayServiceApi : BaseService<Payment>, IPayServiceApi
{
private readonly SenparcHttpClient _httpClient;
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly IGoodsServiceApi _GoodsServiceApi;
private readonly ShopRepository _ShopRepository;
private readonly GoodsRepository _GoodsRepository;
private readonly GoodsCategoryRepository _GoodsCategoryRepository;
private readonly CustomerRepository _CustomerRepository;
private readonly OrderRepository _OrderRepository;
private readonly PaymentRepository _PaymentRepository;
private readonly CouponRepository _CouponRepository;
private readonly CartRepository _CartRepository;
private readonly GoodsSkuRepository _GoodsSkuRepository;
private readonly OrderGoodsRepository _OrderGoodsRepository;
private readonly OrderCustomerAddressRepository _OrderCustomerAddressRepository;
private readonly CustomerAddressRepository _CustomerAddressRepository;
public PayServiceApi(ShopRepository ShopRepository, GoodsCategoryRepository goodsCategoryRepository, CustomerRepository customerRepository, OrderRepository orderRepository, PaymentRepository paymentRepository, CouponRepository couponRepository, SenparcHttpClient httpClient, GoodsRepository goodsRepository, GoodsSkuRepository goodsSkuRepository, IGoodsServiceApi goodsServiceApi, CartRepository cartRepository, OrderGoodsRepository orderGoodsRepository, OrderCustomerAddressRepository orderCustomerAddressRepository, CustomerAddressRepository customerAddressRepository)
{
this._ShopRepository = ShopRepository;
_GoodsCategoryRepository = goodsCategoryRepository;
_CustomerRepository = customerRepository;
_OrderRepository = orderRepository;
_PaymentRepository = paymentRepository;
_CouponRepository = couponRepository;
_httpClient = httpClient;
_GoodsRepository = goodsRepository;
_GoodsSkuRepository = goodsSkuRepository;
_GoodsServiceApi = goodsServiceApi;
_CartRepository = cartRepository;
_OrderGoodsRepository = orderGoodsRepository;
_OrderCustomerAddressRepository = orderCustomerAddressRepository;
_CustomerAddressRepository = customerAddressRepository;
}
#region Api接口代码
public async Task<PayParams> HandelPrePay(CommitPayDtoApi parm)
{
// 获取金额
var price = 1;//单位:分
// 生成订单号
var orderNo = Common.Common.CreateNoQuery();
// 调用统一下单(接口)
Pay pay = new Pay(_httpClient);
var payEntity = await pay.PrePay(parm.OpenId, orderNo, parm.PayType, price);
if (payEntity == null)
{
throw new CustomException("下单失败!");
}
else
{
#region
/* 计算核销前价格(商品总额) */
var goodsPrice = await CalculateBeforePrice(parm);
/* 计算运费 */
GoodsFreightDto goodsFreightDto = new()
{
GoodsRequestList = parm.GoodsRequestList,
CustomerAddressGuid = parm.CustomerAddressGuid,
};
var freight = await _GoodsServiceApi.GetGoodsFreight(goodsFreightDto);
var totalPrice = goodsPrice + freight;
if (parm.TotalAmount != totalPrice) throw new CustomException("前端传递金额不合法!下单失败!");
parm.TotalAmount = totalPrice;
/* 计算核销前后价格(优惠后价格) */
var afterPriceRes = await CalculateAfterPrice(parm);
/* 添加订单流水 */
var paymentGuid = await AddPayment(parm, orderNo, totalPrice, afterPriceRes.DiscountPrice);
/* 添加业务订单 */
var orderGuid = await AddOrder(parm, orderNo, paymentGuid, goodsPrice, afterPriceRes, freight);
/* 添加订单商品 */
await AddOrderGoods(parm, orderGuid);
/* 添加订单用户地址 */
await AddOrderCustomerAddress(parm, orderGuid);
#endregion
// 返回拼接好的支付调起信息
var res = await _PaymentRepository.GetFirstAsync(s => s.PaymentGuid == paymentGuid);
PayParams payRes = new()
{
jsApiUiPackage = payEntity,
outTradeNo = orderNo,
CreateTime = res.Create_time,
OverTime = res.Create_time.AddMinutes(1)
};
return payRes;
}
}
#region
/// <summary>
/// 计算核销前的价格
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public async Task<decimal> CalculateBeforePrice(CommitPayDtoApi parm)
{
decimal price = 0;
foreach (var item in parm.GoodsRequestList)
{
var cart = await _CartRepository.GetFirstAsync(s => s.CartId == item.CartId);
var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == cart.GoodsGuid);
var quantity = cart.CartGoodsNum;
/* 计算商品总价 */
// 是否有规格
if (cart.GoodsSkuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == cart.GoodsSkuId);
if (sku != null)
{
price += sku.GoodsSkuPrice * quantity;
}
}
else
{
price += goods.GoodsPriceHighest * quantity;
}
}
return price;
}
/// <summary>
/// 计算核后的价格
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public async Task<DiscountRes> CalculateAfterPrice(CommitPayDtoApi parm)
{
var res = new DiscountRes();
res.DiscountPrice = parm.TotalAmount;
// 优惠券减免价格
if (parm.CouponId != 0)
{
var coupon = await _CouponRepository.GetFirstAsync(s => s.CouponId == parm.CouponId);
if (coupon != null)
{
res.CouponGuid = coupon.CouponGuid;
res.CouponMoney = coupon.CouponDeductionMoney;
res.DiscountPrice -= coupon.CouponDeductionMoney;
}
else
{
throw new CustomException($"优惠券Id为 {parm.CouponId} 找不到");
}
}
return res;
}
/// <summary>
/// 添加订单流水
/// </summary>
/// <param name="parm">下单信息Dto对象</param>
/// <param name="orderNo">订单号</param>
/// <param name="beforeMoney">核销前价格</param>
/// <param name="afterMoney">核销后价格</param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
public async Task<long> AddPayment(CommitPayDtoApi parm, string orderNo, decimal beforeMoney, decimal afterMoney)
{
// 添加订单流水
Payment payment = new()
{
CustomerGuid = parm.UserId,
PaymentNumber = orderNo,
PaymentBuytype = parm.PayType,
PaymentBeforeMoney = beforeMoney,
PaymentMoney = afterMoney,
PaymentStatus = 1
};
var response = await _PaymentRepository.InsertReturnSnowflakeIdAsync(payment);
if (response == 0)
throw new CustomException("订单流水数据加入失败");
return response;
}
/// <summary>
/// 添加业务订单
/// </summary>
/// <param name="parm">下单信息Dto对象</param>
/// <param name="orderNo">订单号</param>
/// <param name="paymentGuid">支付订单流水guid</param>
/// <param name="beforeMoney">商品总额</param>
/// <param name="discountRes">优惠后的结果</param>
/// <param name="freight">运费</param>
/// <returns></returns>
/// <exception cref="CustomException"></exception>
public async Task<long> AddOrder(CommitPayDtoApi parm, string orderNo, long paymentGuid, decimal beforeMoney, DiscountRes discountRes, decimal freight)
{
Model.Models.Business.OrderManage.Orders.Order order = new()
{
PaymentGuid = paymentGuid,
CustomerGuid = parm.UserId,
OrderNumber = orderNo,
CouponGuid = discountRes?.CouponGuid,
CouponMoney = discountRes.CouponMoney,
GoodsTotalAmoun = beforeMoney,
OrderAmount = discountRes.DiscountPrice,
PayPrice = discountRes.DiscountPrice,
OrderRemark = parm?.Remark,
PayType = parm.PayType,
PayStatus = 1,
DeliveryStatus = 1,
ReceiptStatus = 1,
IsComment = 1,
IsSettled = 1,
OrderSource = 1,
OrderStatus = 1,
DeliveryType = 1,
ExpressPrice = freight,
};
// TODO:余额支付
var response = await _OrderRepository.InsertReturnSnowflakeIdAsync(order);
if (response == 0)
throw new CustomException("业务订单数据加入失败");
return response;
}
/// <summary>
/// 添加OrderGoods(订单商品副表)
/// </summary>
/// <param name="parm"></param>
/// <param name="orderGuid"></param>
/// <returns></returns>
public async Task AddOrderGoods(CommitPayDtoApi parm, long orderGuid)
{
foreach (var item in parm.GoodsRequestList)
{
decimal singlePrice = 0;
decimal toatlPrice = 0;
var cart = await _CartRepository.GetFirstAsync(s => s.CartId == item.CartId);
var goods = await _GoodsRepository.GetFirstAsync(s => s.GoodsGuid == cart.GoodsGuid);
var quantity = cart.CartGoodsNum;
/* 计算商品总价 */
// 是否有规格
if (cart.GoodsSkuId != 0)
{
var sku = await _GoodsSkuRepository.GetFirstAsync(s => s.GoodsSkuId == cart.GoodsSkuId);
if (sku != null)
{
singlePrice = sku.GoodsSkuPrice;
toatlPrice = sku.GoodsSkuPrice * quantity;
}
}
else
{
singlePrice = goods.GoodsPriceHighest;
toatlPrice = goods.GoodsPriceHighest * quantity;
}
/* 添加OrderGoods(订单商品副表) */
OrderGoods orderGoods = new()
{
OrderGuid = orderGuid,
GoodsGuid = cart.GoodsGuid,
GoodsSkuId = cart.GoodsSkuId,
GoodsPrice = singlePrice,
GoodsTotalNum = quantity,
GoodsTotalAmoun = toatlPrice,
};
var response = await _OrderGoodsRepository.InsertReturnSnowflakeIdAsync(orderGoods);
if (response == 0)
throw new CustomException("订单商品数据加入失败");
}
}
/// <summary>
/// 添加订单用户地址
/// </summary>
/// <param name="parm"></param>
/// <param name="orderGuid"></param>
/// <returns></returns>
public async Task AddOrderCustomerAddress(CommitPayDtoApi parm, long orderGuid)
{
var customerAddress = await _CustomerAddressRepository.GetFirstAsync(s => s.CustomerAddressGuid == parm.CustomerAddressGuid);
OrderCustomerAddress orderCustomerAddress = new()
{
OrderGuid = orderGuid,
CustomerGuid = parm.UserId,
CustomerAddressGuid = customerAddress.CustomerAddressGuid,
ConsigneeName = customerAddress.CustomerAddressName,
Phont = customerAddress.CustomerAddressPhone,
ProvinceId = customerAddress.CustomerAddressProvinceId,
CityId = customerAddress.CustomerAddressCityId,
RegionId = customerAddress.CustomerAddressAreaId,
Detail = customerAddress.CustomerAddressDetailed
};
var response = await _OrderCustomerAddressRepository.InsertReturnSnowflakeIdAsync(orderCustomerAddress);
if (response == 0)
throw new CustomException("订单用户地址数据加入失败");
}
#endregion
#endregion
}
}