using Fuel.Core.Transactions.Dto;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using FuelServer.Core.Entity;
using System.Linq.Expressions;
using Fuel.Core.Models;
using System.Net;
using Fuel.Payment.Service.Pay;
using DFS.Core.Abstractions.View;
namespace Fuel.Application.Service
{
public class TransactionsService : ITransactionsService
{
private readonly EntityHelper _entityHelper;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IPayService _payService;
public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor, IPayService payService)
{
_entityHelper = entityHelper;
_httpContextAccessor = httpContextAccessor;
_payService = payService;
}
///
/// 创建订单
///
///
///
public async Task CreateTransactions(UploadTransactions uploadTransactions)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
Guid guid = Guid.Parse(Buid);
string key = string.Empty;
if (uploadTransactions.Type == 1)//预支付
{
key = uploadTransactions.NozzleId + ":" +
uploadTransactions.OriginalAmount + ":" +
uploadTransactions.Qty + ":" +
uploadTransactions.MiniProgramID + ":" +
Buid;
}
else//后支付
{
key = uploadTransactions.NozzleId + ":" +
uploadTransactions.OriginalAmount + ":" +
uploadTransactions.Qty + ":" +
uploadTransactions.MiniProgramID + ":" +
uploadTransactions.FuelItemTransactionEndTime + ":" +
uploadTransactions.TransactionNumber + ":" +
Buid;
}
transactions output = await GetRedisTransactions(uploadTransactions, key);
if (output != null)
{
return ServiceResponse.Ok(output);
}
var _product = await _entityHelper.GetEntitiesAsync(_ => _.Buid == guid && _.ProductName == uploadTransactions.Product);
var _nozzle = await _entityHelper.GetEntitiesAsync(_ => _.Buid == guid && _.ExternalGunNumber == uploadTransactions.NozzleId);
var transactions = uploadTransactions.ToTransactions(uploadTransactions, guid, _product.FirstOrDefault(), _nozzle.FirstOrDefault());
var respond = await _entityHelper.InsertEntityAsync(transactions);
string jsonString = JsonConvert.SerializeObject(respond);
RedisHelper.SetAsync(key, jsonString, 3600);
return ServiceResponse.Ok(respond);
}
public async Task GetTransactionsAsync(TransactionsInput input)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
Guid guid = Guid.Parse(Buid);
Expression> where = p => p.Buid == guid;
if (input.TransactionID != null)
{
where = CombineExpressions(where, p => p.Id == input.TransactionID);
}
if (input.type != null)
{
var status = (transactionsORDERSTATUS)input.type.Value;
where = CombineExpressions(where, p => p.OrderStatus == status);
}
if (input.MiniProgramID != null)
{
where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID);
}
if (input.TransactionSTime != null)
{
where = CombineExpressions(where, p => p.TransactionTime >= input.TransactionSTime);
}
if (input.TransactionETime != null)
{
where = CombineExpressions(where, p => p.TransactionTime == input.TransactionETime);
}
if (!string.IsNullOrEmpty(input.Product))
{
where = CombineExpressions(where, p => p.ProductName == input.Product);
}
var result = await _entityHelper.GetEntitiesAsync(where);
return ServiceResponse.Ok(result);
}
///
/// 小程序查询未支付订单
///
///
public async Task GetMiniProgramTransactionsUnpaidAsync(TransactionsInput input)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
Guid guid = Guid.Parse(Buid);
Expression> where = p => p.Buid == guid;
if (input.MiniProgramID == null)
{
return ServiceResponse.Error("用户id为空");
}
where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID && p.OrderStatus == transactionsORDERSTATUS.Unpaid);
var result = await _entityHelper.GetEntitiesAsync(where);
return ServiceResponse.Ok(result);
}
///
/// 小程序查询已支付订单
///
///
public async Task GetMiniProgramTransactionsPaidAsync(TransactionsInput input)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
Guid guid = Guid.Parse(Buid);
Expression> where = p => p.Buid == guid;
if (input.MiniProgramID == null)
{
return ServiceResponse.Error("用户id为空");
}
where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID && p.OrderStatus == transactionsORDERSTATUS.Paid);
var result = await _entityHelper.GetEntitiesAsync(where);
return ServiceResponse.Ok(result);
}
///
/// 提交支付
///
///
///
public async Task CommitPayment(int trxId, string AuthCode)
{
bool paymentOK = false;
var trx = _entityHelper.GetEntitiesAsync(_ => _.Id == trxId).Result.FirstOrDefault();
if (trx == null)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
}
var paytype = _entityHelper.GetEntitiesAsync(_ => _.Id == trx.PaymentMethod).Result.FirstOrDefault();
string billNumber = SequenceNumber.Next();//订单编号
trx.TransactionNumber = billNumber;
decimal payDueAmount = (decimal)trx.OriginalAmount;
string Channel = paytype.Channel;
var serviceResult = await _payService.PerformElectronicProcess(AuthCode, payDueAmount, billNumber);
Payment.Core.Models.ElectronicOrderProcessResultModel payResult = (Payment.Core.Models.ElectronicOrderProcessResultModel)serviceResult.Data;
if (!serviceResult.IsSuccessful() || payResult.ResultCode == "PAY_ERROR")
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "支付失败");
}
trx.ActualPaymentAmount = payDueAmount;//实际支付金额
trx.ResultCode = payResult?.ResultCode;//支付成功应该为0
trx.ErrorDetail = payResult?.ErrorDetail;
_entityHelper.UpdateAsync(trx);
return ServiceResponse.Ok(trx);
}
///
/// 查询redis订单缓存
///
///
public async Task GetRedisTransactions(UploadTransactions uploadTransactions, string key)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
var respond = RedisHelper.GetAsync(key).Result;
if (respond == null)
{
return null;
}
transactions transactions = JsonConvert.DeserializeObject(respond);
return transactions;
}
// 辅助方法:组合两个表达式
private static Expression> CombineExpressions(Expression> expr1, Expression> expr2)
{
ParameterExpression param = expr1.Parameters[0];
Expression body = Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param));
return Expression.Lambda>(body, param);
}
}
}