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; } /// <summary> /// 创建订单 /// </summary> /// <param name="uploadTransactions"></param> /// <returns></returns> public async Task<ServiceResponse> 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<product>(_ => _.Buid == guid && _.ProductName == uploadTransactions.Product); var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.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<ServiceResponse> GetTransactionsAsync(TransactionsInput input) { string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault(); Guid guid = Guid.Parse(Buid); Expression<Func<transactions, bool>> 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<transactions>(where); return ServiceResponse.Ok(result); } /// <summary> /// 小程序查询未支付订单 /// </summary> /// <returns></returns> public async Task<ServiceResponse> GetMiniProgramTransactionsUnpaidAsync(TransactionsInput input) { string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault(); Guid guid = Guid.Parse(Buid); Expression<Func<transactions, bool>> 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<transactions>(where); return ServiceResponse.Ok(result); } /// <summary> /// 小程序查询已支付订单 /// </summary> /// <returns></returns> public async Task<ServiceResponse> GetMiniProgramTransactionsPaidAsync(TransactionsInput input) { string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault(); Guid guid = Guid.Parse(Buid); Expression<Func<transactions, bool>> 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<transactions>(where); return ServiceResponse.Ok(result); } /// <summary> /// 提交支付 /// </summary> /// <param name="input"></param> /// <returns></returns> public async Task<ServiceResponse> CommitPayment(int trxId, string AuthCode) { bool paymentOK = false; var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault(); if (trx == null) { return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!"); } var paytype = _entityHelper.GetEntitiesAsync<paytype>(_ => _.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); } /// <summary> /// 查询redis订单缓存 /// </summary> /// <returns></returns> public async Task<transactions> 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<transactions>(respond); return transactions; } // 辅助方法:组合两个表达式 private static Expression<Func<T, bool>> CombineExpressions<T>(Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2) { ParameterExpression param = expr1.Parameters[0]; Expression body = Expression.AndAlso(expr1.Body, Expression.Invoke(expr2, param)); return Expression.Lambda<Func<T, bool>>(body, param); } } }