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;
using Fuel.Core;
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);
}
///
/// 退款
///
///
///
public async Task RefundTrx(int trxId,
double longitude,
double latitude)
{
string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
Guid guid = Guid.Parse(Buid);
var businessunitinfo = _entityHelper.GetEntitiesAsync(_ => _.Buid == guid).Result.FirstOrDefault();
if (businessunitinfo == null)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "站点为空");
}
string[] parts = businessunitinfo.GpsCoordinates.Split(',');
if (parts.Length == 2 &&
double.TryParse(parts[0], out double latitude2) &&
double.TryParse(parts[1], out double longitude2))
{
}
else
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "站点经纬度获取失败");
}
//计算调用方和油站的距离,超过距离判定为恶意请求
double distance = DistanceCalculator.CalculateDistance(longitude, latitude, longitude2, latitude2);
if (distance > 5)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该请求大于油站地址5公里");
}
var trx = _entityHelper.GetEntitiesAsync(_ => _.Id == trxId).Result.FirstOrDefault();
if (trx == null)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
}
else if (trx.OrderStatus == transactionsORDERSTATUS.FullyRefunded)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单已退款");
}
else if (trx.OrderStatus == transactionsORDERSTATUS.PartiallyRefunded)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单已部分退款");
}
else if (trx.OrderStatus == transactionsORDERSTATUS.Unpaid)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单未支付");
}
else if (trx.OrderStatus == transactionsORDERSTATUS.Unpaid)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单未支付");
}
//获取单价
decimal? ProductPrice = _entityHelper.GetEntitiesAsync(_ => _.Id == trx.ProductId).Result.FirstOrDefault().ProductPrice;
if (ProductPrice == null)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "单价获取失败");
}
//计算退款金额
decimal RefundAmount = (decimal)((trx.Qty - trx.OriginalQty) * ProductPrice.Value);
if (RefundAmount <= 0.0M)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该笔单无需退款");
}
//退款
var serviceResult = await _payService.ReturnProcess(RefundAmount, trx.TransactionNumber);
Payment.Core.Models.ElectronicOrderProcessResultModel payResult = (Payment.Core.Models.ElectronicOrderProcessResultModel)serviceResult.Data;
if (!serviceResult.IsSuccessful() || payResult.ResultCode == "PAY_ERROR")
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "退款失败");
}
trx.RefundAmount = RefundAmount;
_entityHelper.UpdateAsync(trx);
return ServiceResponse.Ok(trx);
}
public async Task Redeem(int trxId, decimal OriginalQty)
{
var trx = _entityHelper.GetEntitiesAsync(_ => _.Id == trxId).Result.FirstOrDefault();
if (trx == null)
{
return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
}
trx.OriginalQty = OriginalQty;
_entityHelper.UpdateAsync(trx);
return ServiceResponse.Ok(trx);
}
}
}