2 次代碼提交 6951a20522 ... d9cd9d5291

作者 SHA1 備註 提交日期
  Your Name d9cd9d5291 支付与退款调整 2 月之前
  Your Name 9c3d2a5800 mqtt推送指令、验签请求参数修改、云端交易报表 3 月之前
共有 45 個文件被更改,包括 1368 次插入324 次删除
  1. 二進制
      FuelCloud.rar
  2. 9 1
      FuelCloud/ElectronicPayment/WeChatSdk/Business/Refund.cs
  3. 1 0
      FuelCloud/Fuel.Application/Fuel.Application.csproj
  4. 60 10
      FuelCloud/Fuel.Application/MqttService/MqttClientService .cs
  5. 3 3
      FuelCloud/Fuel.Application/MqttService/MqttOptions.cs
  6. 1 0
      FuelCloud/Fuel.Application/Service/INozzleService.cs
  7. 4 5
      FuelCloud/Fuel.Application/Service/ISiteService.cs
  8. 3 1
      FuelCloud/Fuel.Application/Service/ITransactionsService.cs
  9. 58 23
      FuelCloud/Fuel.Application/Service/NozzleService.cs
  10. 104 29
      FuelCloud/Fuel.Application/Service/SiteService.cs
  11. 370 114
      FuelCloud/Fuel.Application/Service/TransactionsService.cs
  12. 29 8
      FuelCloud/Fuel.Application/Service/UserService.cs
  13. 12 0
      FuelCloud/src/Fuel.Payment.Server/.config/dotnet-tools.json
  14. 12 5
      FuelCloud/src/Fuel.Payment.Server/Controllers/AuthController.cs
  15. 22 4
      FuelCloud/src/Fuel.Payment.Server/Controllers/NozzleController.cs
  16. 36 9
      FuelCloud/src/Fuel.Payment.Server/Controllers/SiteController.cs
  17. 54 14
      FuelCloud/src/Fuel.Payment.Server/Controllers/TransactionsController.cs
  18. 1 0
      FuelCloud/src/Fuel.Payment.Server/Fuel.PaymentServer.csproj
  19. 5 0
      FuelCloud/src/Fuel.Payment.Server/MicServer/Middlewares/SignatureValidator.cs
  20. 38 1
      FuelCloud/src/Fuel.Payment.Server/Program.cs
  21. 1 1
      FuelCloud/src/Fuel.Payment.Server/appsettings.json
  22. 27 0
      FuelCloud/src/Fuel.Payment.Server/nlog.xml
  23. 5 0
      FuelCloud/src/Fuel.Payment.Service/AliPaymentProcessor/Alipay/AlipayPaymentProcessor.cs
  24. 4 0
      FuelCloud/src/Fuel.Payment.Service/AllInPayProcessor/AllInPay/AllInPayProcessor.cs
  25. 9 0
      FuelCloud/src/Fuel.Payment.Service/Factory/AsyncPaymentProcessor.cs
  26. 1 1
      FuelCloud/src/Fuel.Payment.Service/Pay/IPayService.cs
  27. 54 39
      FuelCloud/src/Fuel.Payment.Service/Pay/PayService.cs
  28. 5 0
      FuelCloud/src/Fuel.Payment.Service/UnionPayProcessor/MiniUnionPayProcessor.cs
  29. 5 0
      FuelCloud/src/Fuel.Payment.Service/UnionPayProcessor/UnionPayProcessor.cs
  30. 81 22
      FuelCloud/src/Fuel.Payment.Service/WeChatPaymentProcessor/Wechat/WechatPaymentProcessor.cs
  31. 2 2
      FuelCloud/src/FuelServer.Core/Entity/configuration.cs
  32. 3 3
      FuelCloud/src/FuelServer.Core/Entity/nozzle.cs
  33. 48 11
      FuelCloud/src/FuelServer.Core/Entity/transactions.cs
  34. 7 9
      FuelCloud/src/FuelServer.Core/HttpRequestReader.cs
  35. 3 2
      FuelCloud/src/FuelServer.Core/Models/ServiceResponse.cs
  36. 1 0
      FuelCloud/src/FuelServer.Core/Nozzle/Dto/NozzleInfo.cs
  37. 1 1
      FuelCloud/src/FuelServer.Core/Nozzle/Dto/UploadNozzle.cs
  38. 26 0
      FuelCloud/src/FuelServer.Core/Transactions/Dto/RefundTrxRequest.cs
  39. 26 0
      FuelCloud/src/FuelServer.Core/Transactions/Dto/RequestModel.cs
  40. 11 4
      FuelCloud/src/FuelServer.Core/Transactions/Dto/UploadTransactions.cs
  41. 50 0
      FuelCloud/src/FuelServer.Core/Transactions/TransactionsList.cs
  42. 2 2
      FuelCloud/src/FuelServer.Core/User/LoginModel.cs
  43. 155 0
      FuelCloud/src/FuelServer.Core/WechatServer/WeChatService.cs
  44. 3 0
      FuelCloud/src/FuelServer.Core/WechatServer/WechatConstants.cs
  45. 16 0
      FuelCloud/src/FuelServer.Core/WechatServer/WechatUserSessionResponse.cs

二進制
FuelCloud.rar


+ 9 - 1
FuelCloud/ElectronicPayment/WeChatSdk/Business/Refund.cs

@@ -20,6 +20,9 @@ namespace Wechat.PayAPI
         */
         public static async Task<WxPayData> Run(string transaction_id, ElectronicOrderModel order)
         {
+            try 
+            {
+         
             // string out_trade_no, string total_fee, string refund_fee
             //set the default trade_status to PAYERROR
             order.TradeStatus = TradeStatus.PAYERROR;
@@ -91,7 +94,12 @@ namespace Wechat.PayAPI
                     return result;
                 }
             }
-
+            }
+            catch (Exception e) 
+            { 
+            
+            }
+            return new WxPayData();
         }
 
         private static async Task<WxPayData> RequestRefund(

+ 1 - 0
FuelCloud/Fuel.Application/Fuel.Application.csproj

@@ -10,6 +10,7 @@
     <PackageReference Include="Microsoft.AspNetCore.Authorization" Version="8.0.6" />
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
     <PackageReference Include="MQTTnet" Version="4.3.5.1141" />
+    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.0.2" />
   </ItemGroup>
 
   <ItemGroup>

+ 60 - 10
FuelCloud/Fuel.Application/MqttService/MqttClientService .cs

@@ -10,9 +10,10 @@ namespace Fuel.Application.MqttService
 {
     public class MqttClientService : IMqttClientService, IDisposable
     {
-        private readonly IMqttClient _mqttClient;
-        private readonly MqttOptions _options;
-        private readonly ILogger<MqttClientService> _logger;
+        private  IMqttClient _mqttClient;
+        private  MqttOptions _options;
+        private  ILogger<MqttClientService> _logger;
+        private bool _disposed = false;
 
         public MqttClientService(
             IOptions<MqttOptions> options,
@@ -40,7 +41,10 @@ namespace Fuel.Application.MqttService
         {
             _logger.LogWarning("MQTT disconnected. Attempting to reconnect...");
             await Task.Delay(TimeSpan.FromSeconds(5));
-            await ConnectAsync(); // 自动重连
+            if (!_disposed)
+            {
+                await ConnectAsync(); // 自动重连
+            }
         }
 
         private async Task HandleMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e)
@@ -52,14 +56,27 @@ namespace Fuel.Application.MqttService
 
         public async Task ConnectAsync()
         {
+            if (_mqttClient.IsConnected)
+            {
+                return;
+            }
+
             var options = new MqttClientOptionsBuilder()
                 .WithTcpServer(_options.Server, _options.Port)
                 .WithClientId(_options.ClientId)
-                .WithCredentials(_options.Username, _options.Password)
+                .WithCredentials("HSClient", "HS202503")
                 .WithCleanSession()
                 .Build();
 
-            await _mqttClient.ConnectAsync(options);
+            try
+            {
+                await _mqttClient.ConnectAsync(options);
+            }
+            catch (ObjectDisposedException ex)
+            {
+                _logger.LogError($"Error connecting to MQTT broker: {ex.Message}");
+                // 处理异常或重新创建客户端实例
+            }
         }
 
         public async Task PublishAsync(string topic, string payload)
@@ -75,7 +92,15 @@ namespace Fuel.Application.MqttService
                 .WithQualityOfServiceLevel(MQTTnet.Protocol.MqttQualityOfServiceLevel.AtLeastOnce)
                 .Build();
 
-            await _mqttClient.PublishAsync(message);
+            try
+            {
+                await _mqttClient.PublishAsync(message);
+            }
+            catch (ObjectDisposedException ex)
+            {
+                _logger.LogError($"Error publishing message: {ex.Message}");
+                // 处理异常或重新创建客户端实例
+            }
         }
 
         public async Task SubscribeAsync(string topic)
@@ -89,17 +114,42 @@ namespace Fuel.Application.MqttService
                 .WithTopic(topic)
                 .Build();
 
-            await _mqttClient.SubscribeAsync(topicFilter);
+            try
+            {
+                await _mqttClient.SubscribeAsync(topicFilter);
+            }
+            catch (Exception ex)
+            {
+                _logger.LogError($"Error subscribing to topic {topic}: {ex.Message}");
+                // 处理异常
+            }
         }
 
         public async Task DisconnectAsync()
         {
-            await _mqttClient.DisconnectAsync();
+            if (_mqttClient.IsConnected)
+            {
+                await _mqttClient.DisconnectAsync();
+            }
+        }
+
+        protected virtual void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                {
+                    _mqttClient?.Dispose();
+                }
+
+                _disposed = true;
+            }
         }
 
         public void Dispose()
         {
-            _mqttClient?.Dispose();
+            Dispose(true);
+            GC.SuppressFinalize(this);
         }
     }
 }

+ 3 - 3
FuelCloud/Fuel.Application/MqttService/MqttOptions.cs

@@ -8,10 +8,10 @@ namespace Fuel.Application.MqttService
 {
     public class MqttOptions
     {
-        public string Server { get; set; } = "broker.emqx.io";
+        public string Server { get; set; } = "192.168.5.5";
         public int Port { get; set; } = 1883;
         public string ClientId { get; set; } = $"client_{Guid.NewGuid()}";
-        public string Username { get; set; }
-        public string Password { get; set; }
+        public string Username { get; set; } = "HSClient";
+        public string Password { get; set; } = "HS202503";
     }
 }

+ 1 - 0
FuelCloud/Fuel.Application/Service/INozzleService.cs

@@ -27,5 +27,6 @@ namespace Fuel.Application.Service
         Task<ServiceResponse> CancelNozzleAuthorizationAsync(int trxId);
 
         Task<ServiceResponse> UpdateCancelNozzleAuthorization(NozzleAuthorization nozzleAuthorization);
+        Task<NozzleInfo> GetNozzleID(int Nozzleid);
     }
 }

+ 4 - 5
FuelCloud/Fuel.Application/Service/ISiteService.cs

@@ -1,4 +1,5 @@
 using Fuel.Core.Models;
+using Fuel.Core.WechatServer;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -11,10 +12,8 @@ namespace Fuel.Application.Service
     {
         Task<ServiceResponse> GetSiteInfo();
         Task<ServiceResponse> GetAppidSecret(string Code);
-        Task<ServiceResponse> AddMiniprogramUser(string type,
-           string UserName,
-           string UserAvatarUrl,
-           string UserPhoneNumber,
-           string Address);
+        Task<ServiceResponse> AddMiniprogramUser(string type, AddWechatUser wechatUser);
+         Task<ServiceResponse> GetSiteInformationAndConfiguration();
+        Task<ServiceResponse> AddSite(AddSite site);
     }
 }

+ 3 - 1
FuelCloud/Fuel.Application/Service/ITransactionsService.cs

@@ -13,7 +13,7 @@ namespace Fuel.Application.Service
     {
          Task<ServiceResponse> CreateTransactions(UploadTransactions uploadTransactions);
 
-        Task<ServiceResponse> GetTransactionsAsync(TransactionsInput input);
+        Task<ServiceResponse> GetTransactionsAsync(RequestModel input);
         Task<ServiceResponse> CommitPayment(int trxId, string AuthCode);
         Task<ServiceResponse> GetMiniProgramTransactionsUnpaidAsync(TransactionsInput input);
         Task<ServiceResponse> GetMiniProgramTransactionsUnpaidNozzleAsync(long NozzleId);
@@ -23,5 +23,7 @@ namespace Fuel.Application.Service
             double latitude);
         Task<ServiceResponse> Redeem(int trxId, decimal OriginalQty);
         Task<ServiceResponse> UnifiedOrder(int trxId);
+        Task<ServiceResponse> WXFindOrders(DateTime? dateTime, int pageNum, int lineCount);
+        Task SendMessage(int trxId, string orderType);
     }
 }

+ 58 - 23
FuelCloud/Fuel.Application/Service/NozzleService.cs

@@ -1,10 +1,13 @@
-using DFS.Infrastructure;
+using DFS.Core.Abstractions.Models;
+using DFS.Infrastructure;
 using Fuel.Application.MqttService;
 using Fuel.Core;
 using Fuel.Core.Models;
 using Fuel.Core.Nozzle.Dto;
+using Fuel.Core.Transactions.Dto;
 using FuelServer.Core.Entity;
 using Newtonsoft.Json;
+using Org.BouncyCastle.Asn1.Ocsp;
 using Org.BouncyCastle.Ocsp;
 using System;
 using System.Collections.Generic;
@@ -13,6 +16,7 @@ using System.Net;
 using System.Text;
 using System.Threading.Tasks;
 using System.Transactions;
+using System.Xml;
 using static FreeSql.Internal.GlobalFilter;
 
 namespace Fuel.Application.Service
@@ -198,9 +202,6 @@ namespace Fuel.Application.Service
         /// <returns></returns>
         public async Task<ServiceResponse> UploadNozzle(UploadNozzle uploadNozzle)
         {
-            await _mqttService.SubscribeAsync("fromClound/12345678-9abc-def0-1234-56789abcdef0");
-            await Task.Delay(2000);
-            await _mqttService.PublishAsync("fromClound/12345678-9abc-def0-1234-56789abcdef0", "测试");
             //RedisHelper.HSetAsync("Transaction", "11:22:33:44", "3232");
             //RedisHelper.SetAsync("33:22:33:44", "qweqweqwe", 3600);
             // var fsdds = RedisHelper.GetAsync("33:22:33:44");
@@ -225,11 +226,12 @@ namespace Fuel.Application.Service
             _nozzle.ExternalGunNumber = uploadNozzle.ExternalGunNumber;
             _nozzle.ProductID = _product.Id;
             _nozzle.NozzleId = uploadNozzle.NozzleId;
-            int affectedRows = _fsql.Insert<nozzle>().AppendData(_nozzle).ExecuteAffrows();
-            if (affectedRows <= 0)
+            long id = _fsql.Insert<nozzle>().AppendData(_nozzle).ExecuteIdentity();
+            if (id <= 0)
             {
                 return ServiceResponse.Error("油枪信息插入失败");
             }
+            _nozzle.Id = id;
             return ServiceResponse.Ok(_nozzle);
         }
         /// <summary>
@@ -271,7 +273,7 @@ namespace Fuel.Application.Service
                 return ServiceResponse.Error("未找到油枪");
             }
             int affectedRows = _fsql.Delete<nozzle>()
-    .Where(p => p.NozzleId == uploadNozzle.NozzleId) 
+    .Where(p => p.NozzleId == uploadNozzle.NozzleId)
     .ExecuteAffrows();
             if (affectedRows <= 0)
             {
@@ -284,13 +286,15 @@ namespace Fuel.Application.Service
         {
             Guid guid = HttpRequestReader.GetCurrentBuId(); //站点id
             List<nozzle> nozzleStatuses = new List<nozzle>();
+            var nozzleList = _fsql.Select<nozzle>().Where(_ => _.Buid == guid).ToList();
             foreach (var n in uploadNozzleStatuses)
             {
-                nozzleStatuses.Add(new nozzle() { 
-                    NozzleId = n.NozzleId,
-                    Buid = guid,
-                    Status = n.Status
-                });
+                var _nozzle = nozzleList.Where(_ => _.Id == n.NozzleId).First();
+                if (_nozzle != null)
+                {
+                    _nozzle.Status = n.Status;
+                    nozzleStatuses.Add(_nozzle);
+                }
             }
             int affectedRows = _fsql.InsertOrUpdate<nozzle>().SetSource(nozzleStatuses).ExecuteAffrows();
             return ServiceResponse.Ok();
@@ -302,16 +306,32 @@ namespace Fuel.Application.Service
             return _entityHelper._fsql.Select<nozzle, tanks, product>()
                     .LeftJoin((a, b, c) => a.TankId == b.Id)
                     .LeftJoin((a, b, c) => a.ProductID == c.Id)
-                    .Where((a, b, c) => a.Buid == guid && a.ExternalGunNumber == Nozzleid)
+                    .Where((a, b, c) => a.Buid == guid && a.Id == Nozzleid)
                     .ToList((a, b, c) => new NozzleInfo()
                     {
-                        Nozzleid = a.ExternalGunNumber,
+                        Nozzleid = a.Id,
                         ProductName = c.ProductName,
                         ProductPrice = c.ProductPrice,
                         Status = a.Status,
-                        TankNumber = b.TankNumber
+                        TankNumber = b.TankNumber,
+                        ExternalGunNumber = a.ExternalGunNumber
                     });
         }
+        /// <summary>
+        /// 根据外部枪号获取油枪id
+        /// </summary>
+        /// <param name="Nozzleid"></param>
+        /// <returns></returns>
+        public async Task<NozzleInfo> GetNozzleID(int Nozzleid)
+        {
+            Guid guid = HttpRequestReader.GetCurrentBuId(); //站点id
+            return _entityHelper._fsql.Select<nozzle>()
+                 .Where((a) => a.ExternalGunNumber == Nozzleid)
+                 .ToList((a) => new NozzleInfo()
+                 {
+                     Nozzleid = a.Id
+                 }).FirstOrDefault();
+        }
         #endregion
 
         /// <summary>
@@ -339,12 +359,13 @@ namespace Fuel.Application.Service
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
             }
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.Id == trx.MiniProgramID).First();
             string key = guid + "_" + trx.NozzleId;//授权结果的key
             string jsonString = JsonConvert.SerializeObject(trx);
-            await _mqttService.SubscribeAsync("fromClound/" + guid);
+            await _mqttService.SubscribeAsync("authorization/" + guid);
             await Task.Delay(2000);
-            var sendjson = new { type= 1,data = jsonString };
-            await _mqttService.PublishAsync("fromClound/" + guid, JsonConvert.SerializeObject(sendjson));
+            var sendjson = new { data = jsonString, UserName = user.UserName, UserPhoneNumber = user.UserPhoneNumber };
+            await _mqttService.PublishAsync("authorization/" + guid, JsonConvert.SerializeObject(sendjson));
             KeyValueCache.AddOrUpdate("authGun", key, AuthorizationStatus.WaitAuthorization);//添加字典,用于监听授权结果
             bool changed = await KeyValueCache.MonitorDictionaryChanges("authGun", key, AuthorizationStatus.WaitAuthorization);
             if (!changed)
@@ -359,7 +380,7 @@ namespace Fuel.Application.Service
             }
             trx.TransactionNumber = auth.TransactionNumber;
             trx.authorizationStatus = AuthorizationStatus.Authorized;//将订单授权状态更改成已授权
-            _entityHelper.UpdateAsync(trx);
+            int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
             return ServiceResponse.Ok("授权成功");
         }
         /// <summary>
@@ -377,10 +398,10 @@ namespace Fuel.Application.Service
             }
             string key = guid + "_" + trx.NozzleId;//授权结果的key
             string jsonString = JsonConvert.SerializeObject(trx);
-            await _mqttService.SubscribeAsync("fromClound/" + guid);
+            await _mqttService.SubscribeAsync("unAuthorization/" + guid);
             await Task.Delay(2000);
-            var sendjson = new { type = 2, data = jsonString };
-            await _mqttService.PublishAsync("fromClound/" + guid, JsonConvert.SerializeObject(sendjson));
+            var sendjson = new { data = jsonString };
+            await _mqttService.PublishAsync("unAuthorization/" + guid, JsonConvert.SerializeObject(sendjson));
             KeyValueCache.AddOrUpdate("cancelAuth", key, AuthorizationStatus.WaitAuthorization);//添加字典,用于监听授权结果
             bool changed = await KeyValueCache.MonitorDictionaryChanges("cancelAuth", key, AuthorizationStatus.WaitAuthorization);
             if (!changed)
@@ -395,7 +416,7 @@ namespace Fuel.Application.Service
             }
             trx.TransactionNumber = auth.TransactionNumber;
             trx.authorizationStatus = AuthorizationStatus.Unauthorized;//将订单授权状态更改成已授权
-            _entityHelper.UpdateAsync(trx);
+            int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
             return ServiceResponse.Ok("取消授权成功");
         }
         /// <summary>
@@ -408,6 +429,20 @@ namespace Fuel.Application.Service
             Guid guid = HttpRequestReader.GetCurrentBuId(); //站点id
             string key = guid + "_" + nozzleAuthorization.NozzleId;//授权结果的key
             KeyValueCache.AddOrUpdate("cancelAuth", key, nozzleAuthorization);//更新授权结果
+            if (nozzleAuthorization.OilMachineStatus == OilMachineStatus.Success)
+            {
+                var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.Buid == guid && _.ExternalGunNumber == nozzleAuthorization.NozzleId);
+                if (_nozzle.Count() <= 0)
+                {
+                    return ServiceResponse.Error("油枪查询失败,油枪名称:" + nozzleAuthorization.NozzleId);
+                }
+                var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Buid == guid && _.NozzleId == _nozzle.First().Id).Result.FirstOrDefault();
+                if (trx != null)
+                {
+                    trx.authorizationStatus = AuthorizationStatus.Unauthorized;
+                    int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
+                }
+            }
             return ServiceResponse.Ok();
         }
     }

+ 104 - 29
FuelCloud/Fuel.Application/Service/SiteService.cs

@@ -5,6 +5,7 @@ using Fuel.Core.Transactions.Dto;
 using Fuel.Core.WechatServer;
 using FuelServer.Core.Entity;
 using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -12,32 +13,72 @@ using System.Net;
 using System.Net.Http.Headers;
 using System.Text;
 using System.Threading.Tasks;
+using System.Xml.Linq;
+using static FreeSql.Internal.GlobalFilter;
 
 namespace Fuel.Application.Service
 {
-    public class SiteService: ISiteService
+    public class SiteService : ISiteService
     {
         public readonly IFreeSql _fsql;
         public SiteService(IFreeSql freeSql)
-        { 
-             _fsql = freeSql;
+        {
+            _fsql = freeSql;
+        }
+        public async Task<ServiceResponse> AddSite(AddSite site)
+        {
+            Guid Buid = Guid.NewGuid();
+           businessunitinfo bu = new businessunitinfo();
+
+            bu.Buid = Buid;
+            bu.Address = site.Address;
+            bu.Name = site.Name;
+            bu.Appid = site.AppId;
+            bu.Secret = site.Secret;
+            bu.GpsCoordinates = site.GpsCoordinates;
+            bu.PaymentMode = site.PaymentMode == "预支付" ? 1 : 2;
+            bu.Phone = site.Phone;
+            int affectedRows = _fsql.Insert<businessunitinfo>().AppendData(bu).ExecuteAffrows();
+
+            if (!string.IsNullOrEmpty(site.PayType))
+            { 
+                configuration configuration = new configuration();
+                configuration.Type = 1;
+                configuration.Value = site.PayTypeConfiguration;
+                configuration.Name = site.PayType;
+                configuration.Buid = Buid;
+                _fsql.Insert<configuration>().AppendData(configuration).ExecuteAffrows();
+            }
+
+            if (!string.IsNullOrEmpty(site.MessageTemplate))
+            {
+                configuration Message = new configuration();
+                Message.Type = 2;
+                Message.Value = site.MessageTemplateConfiguration;
+                Message.Name = site.MessageTemplate;
+                Message.Buid = Buid;
+                _fsql.Insert<configuration>().AppendData(Message).ExecuteAffrows();
+            }
+            return ServiceResponse.Ok(bu);
         }
         public async Task<ServiceResponse> GetSiteInfo()
         {
             Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
-            Guid WachatID = HttpRequestReader.GetWachatID(); //用户
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
             var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
             if (userSession == null)
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未找到用户!");
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
             }
-            var user = _fsql.Select<miniprogramusers>().Where(_ => _.UnionId == userSession.unionid).First();
-            var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid ).First();
-            var SiteInfo = new {
-                site = new { 
-                  Name = site.Name,//站点名称
-                  GpsCoordinates = site.GpsCoordinates,//油站经纬度
-                  PaymentMode = site.PaymentMode,//预支付:1,后支付:2
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+            var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid).First();
+            var SiteInfo = new
+            {
+                site = new
+                {
+                    Name = site.Name,//站点名称
+                    GpsCoordinates = site.GpsCoordinates,//油站经纬度
+                    PaymentMode = site.PaymentMode,//预支付:1,后支付:2
                 },
                 userInfo = new
                 {
@@ -49,6 +90,38 @@ namespace Fuel.Application.Service
             };
             return ServiceResponse.Ok(SiteInfo);
         }
+        public async Task<ServiceResponse> GetSiteInformationAndConfiguration()
+        {
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            var site = _fsql.Select<businessunitinfo>().ToList();
+            var payinfo = _fsql.Select<configuration>().ToList();
+            var SiteInfo = new[] { new { Name = "", Address = "", Phone = "", Appid = "", Secret = "", GpsCoordinates = "", paytype = "", PaymentMode = "" } }.ToList();
+            SiteInfo.Clear();
+            foreach (var itme in site)
+            {
+                var PaymentMode = itme.PaymentMode == 1 ? "预支付" : "后支付";
+                string paytype = string.Empty;
+                if (payinfo.Count > 0)
+                {
+                     paytype = payinfo.FirstOrDefault(a => a.Buid == Buid && a.Type == 1)?.Name;//获取支付类型
+                }
+
+                SiteInfo.Add(
+                     new
+                     {
+                         Name = itme.Name,
+                         Address = itme.Address,
+                         Phone = itme.Phone,
+                         Appid = itme.Appid,
+                         Secret = itme.Secret,
+                         GpsCoordinates = itme.GpsCoordinates,
+                         paytype = paytype,
+                         PaymentMode = PaymentMode
+                     }
+                    );
+            }
+            return ServiceResponse.Ok(SiteInfo);
+        }
         public async Task<ServiceResponse> GetAppidSecret(string Code)
         {
             Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
@@ -58,12 +131,14 @@ namespace Fuel.Application.Service
                 return ServiceResponse.Error("获取站点小程序appid与Secret失败,BUID:" + Buid);
             }
             WechatUserSessionResponse userSession =
-               await WechatLoginCodeToSessionKeyNOpenId(Code, site.Appid,site.Secret);
+               await WechatLoginCodeToSessionKeyNOpenId(Code, site.Appid, site.Secret);
+            if (userSession == null)
+            {
+                return ServiceResponse.Error("登录失败");
+            }
             AccessTokenManager.GetAccessTokenAsync(site.Appid, site.Secret);
-            var thirdSessionKey = GenerateThirdSessionKey();
-            userSession.unionid = userSession.openid;
-            WechatUserSessionRepo.AddUserSession(thirdSessionKey, userSession);
-            return ServiceResponse.Ok(thirdSessionKey);
+            WechatUserSessionRepo.AddUserSession(userSession.openid, userSession);
+            return ServiceResponse.Ok(userSession.openid);
         }
         /// <summary>
         /// 微信小程序登录
@@ -105,30 +180,30 @@ namespace Fuel.Application.Service
         /// <param name="UserPhoneNumber"></param>
         /// <param name="Address"></param>
         /// <returns></returns>
-        public async Task<ServiceResponse> AddMiniprogramUser(string type,
-            string UserName,
-            string UserAvatarUrl,
-            string UserPhoneNumber,
-            string Address)
+        public async Task<ServiceResponse> AddMiniprogramUser(string type, AddWechatUser wechatUser)
         {
             Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
-            Guid WachatID = HttpRequestReader.GetWachatID(); //用户
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
             var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
             if (userSession == null)
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未找到用户!");
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
             }
-            var miniprogramusers = _fsql.Select<miniprogramusers>().Where(_ => _.UnionId == userSession.unionid).First();
+            var miniprogramusers = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
             if (miniprogramusers != null)
             {
                 return ServiceResponse.Ok(miniprogramusers);
             }
+            string decryptedData = WeChatService.Decrypt(wechatUser.encryptedData, wechatUser.iv, userSession.session_key);
+
+            JObject jsonObject = JObject.Parse(decryptedData);
+            string phoneNumber = jsonObject["phoneNumber"].ToString();
             miniprogramusers user = new miniprogramusers();
             user.Buid = Buid;
-            user.UserName = UserName;
-            user.UserAvatarUrl = UserAvatarUrl;
-            user.UserPhoneNumber = UserPhoneNumber;
-            user.Address = Address;
+            user.UserName = wechatUser.UserName;
+            user.UserAvatarUrl = wechatUser.UserAvatarUrl;
+            user.UserPhoneNumber = phoneNumber;
+            user.Address = wechatUser.Address;
             user.OpenId = userSession.openid;
             user.UnionId = userSession.unionid;
             int affectedRows = _fsql.Insert<miniprogramusers>().AppendData(user).ExecuteAffrows();

+ 370 - 114
FuelCloud/Fuel.Application/Service/TransactionsService.cs

@@ -15,6 +15,12 @@ using Fuel.Core.Nozzle.Dto;
 using Fuel.Application.MqttService;
 using Org.BouncyCastle.Asn1.X509;
 using Jayrock.Json;
+using Fuel.Core.Transactions;
+using Microsoft.Extensions.DependencyInjection;
+using static Fuel.Core.WechatServer.WeChatService;
+using System.Linq.Dynamic.Core;
+using System.Text.Json;
+using Org.BouncyCastle.Asn1.Ocsp;
 
 
 namespace Fuel.Application.Service
@@ -26,13 +32,17 @@ namespace Fuel.Application.Service
         private readonly IPayService _payService;
         public readonly IFreeSql _fsql;
         private readonly IMqttClientService _mqttService;
-        public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor, IPayService payService, IFreeSql fsql, IMqttClientService mqttService)
+        private readonly IServiceScopeFactory _serviceScopeFactory;
+        static NLog.Logger logger = NLog.LogManager.LoadConfiguration("nlog.xml").GetLogger("Main");
+
+        public TransactionsService(EntityHelper entityHelper, IHttpContextAccessor httpContextAccessor, IPayService payService, IFreeSql fsql, IMqttClientService mqttService, IServiceScopeFactory serviceScopeFactory)
         {
             _entityHelper = entityHelper;
             _httpContextAccessor = httpContextAccessor;
             _payService = payService;
             _fsql = fsql;
             _mqttService = mqttService;
+            _serviceScopeFactory = serviceScopeFactory;
         }
 
         /// <summary>
@@ -43,15 +53,57 @@ namespace Fuel.Application.Service
         public async Task<ServiceResponse> CreateTransactions(UploadTransactions uploadTransactions)
         {
             Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid).First();
+            if (site == null)
+            {
+                return ServiceResponse.Error("站点信息查询为空 buid: " + Buid);
+            }
             string key = string.Empty;
-            int OrderType = 0;//订单类型
-            if (OrderType == 1)//预支付
+            var _product = await _entityHelper.GetEntitiesAsync<product>(_ => _.Buid == Buid && _.ProductName == uploadTransactions.Product);
+            if (_product.Count() <= 0)
+            {
+                return ServiceResponse.Error("油品查询失败,油品名称:" + uploadTransactions.Product);
+            }
+            var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.Buid == Buid && _.ExternalGunNumber == uploadTransactions.ExternalGunNumber);
+            if (_nozzle.Count() <= 0)
+            {
+                return ServiceResponse.Error("油枪查询失败,油枪名称:" + uploadTransactions.ExternalGunNumber);
+            }
+            if (site.PaymentMode == 1)//预支付
             {
                 key = uploadTransactions.ExternalGunNumber + ":" +
                          uploadTransactions.OriginalAmount + ":" +
                          uploadTransactions.Qty + ":" +
                          uploadTransactions.MiniProgramID + ":" +
                          Buid.ToString();
+                string WachatID = HttpRequestReader.GetWachatID(); //用户
+                var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+                if (userSession == null)
+                {
+                    return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
+                }
+                var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+
+
+                if (uploadTransactions.OriginalAmount != null)
+                {
+                    decimal decimalValue = uploadTransactions.OriginalAmount.HasValue ? uploadTransactions.OriginalAmount.Value : 0m;
+                    decimal ProductPrice = _product.First().ProductPrice.HasValue ? _product.First().ProductPrice.Value : 0m;
+                    decimal qty = decimalValue / ProductPrice;
+                    uploadTransactions.Qty = qty;
+                }
+                else if (uploadTransactions.Qty != null)
+                {
+                    decimal decimalValue = uploadTransactions.Qty.HasValue ? uploadTransactions.Qty.Value : 0m;
+                    decimal ProductPrice = _product.First().ProductPrice.HasValue ? _product.First().ProductPrice.Value : 0m;
+                    decimal OriginalAmount = decimalValue * ProductPrice;
+                    uploadTransactions.OriginalAmount = OriginalAmount;
+                }
+                else if (uploadTransactions.OriginalAmount == null && uploadTransactions.Qty == null)
+                {
+                    return ServiceResponse.Error("金额与升数为空");
+                }
+                uploadTransactions.MiniProgramID = user.Id;
             }
             else//后支付
             {
@@ -68,17 +120,8 @@ namespace Fuel.Application.Service
             {
                 return ServiceResponse.Ok(output);
             }
-            var _product = await _entityHelper.GetEntitiesAsync<product>(_ => _.Buid == Buid && _.ProductName == uploadTransactions.Product);
-            if (_product.Count() <= 0)
-            {
-                return ServiceResponse.Error("油品查询失败,油品名称:" + uploadTransactions.Product);
-            }
-            var _nozzle = await _entityHelper.GetEntitiesAsync<nozzle>(_ => _.Buid == Buid && _.ExternalGunNumber == uploadTransactions.ExternalGunNumber);
-            if (_nozzle.Count() <= 0)
-            {
-                return ServiceResponse.Error("油枪查询失败,油枪名称:" + uploadTransactions.ExternalGunNumber);
-            }
-            var trx = uploadTransactions.ToTransactions(uploadTransactions, Buid, _product.FirstOrDefault(), _nozzle.FirstOrDefault(), OrderType);
+          
+            var trx = uploadTransactions.ToTransactions(uploadTransactions, Buid, _product.FirstOrDefault(), _nozzle.FirstOrDefault(), site.PaymentMode);
             //int affectedRows = _fsql.Insert<transactions>().AppendData(trx).ExecuteAffrows();
             // var affectedRows = _fsql.Insert<transactions>().AppendData(trx).ExecuteInserted();
             var id = _fsql.Insert(trx).ExecuteIdentity();
@@ -97,38 +140,60 @@ namespace Fuel.Application.Service
                 return ServiceResponse.Error("订单信息插入失败");
             }
         }
-        public async Task<ServiceResponse> GetTransactionsAsync(TransactionsInput input)
+        public async Task<ServiceResponse> GetTransactionsAsync(RequestModel 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)
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid).First();
+            var _nozzle = _fsql.Select<nozzle>().ToList();//根据油枪id查询外部枪号
+            var user = _fsql.Select<miniprogramusers>().ToList();
+            var paytype = _fsql.Select<paytype>().ToList();
+            Expression<Func<transactions, bool>> where = p => p.Buid == Buid;
+            if (input.filter.NozzleID != "")
             {
-                where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID);
+                long.TryParse(input.filter.NozzleID, out long NozzleID);
+                var nozzle = _nozzle.Where(_ => _.ExternalGunNumber == NozzleID).First();//根据油枪id查询外部枪号
+                where = CombineExpressions(where, p => p.NozzleId == nozzle.Id);
             }
-            if (input.TransactionSTime != null)
+            if (input.filter.ProductName != "")
             {
-                where = CombineExpressions(where, p => p.TransactionTime >= input.TransactionSTime);
+                where = CombineExpressions(where, p => p.ProductName == input.filter.ProductName);
             }
-            if (input.TransactionETime != null)
+            if (input.filter.siteName != "")
             {
-                where = CombineExpressions(where, p => p.TransactionTime == input.TransactionETime);
+
+                where = CombineExpressions(where, p => p.Buid == site.Buid);
             }
-            if (!string.IsNullOrEmpty(input.Product))
+            if (input.filter.username != "")
             {
-                where = CombineExpressions(where, p => p.ProductName == input.Product);
+                var userid = user.Where(_ => _.UserName == input.filter.username).First();
+                where = CombineExpressions(where, p => p.MiniProgramID == userid.Id);
             }
+            //if (input.TransactionETime != null)
+            //{
+            //    where = CombineExpressions(where, p => p.TransactionTime == input.TransactionETime);
+            //}
             var result = await _entityHelper.GetEntitiesAsync<transactions>(where);
-            return ServiceResponse.Ok(result);
+
+            List<TransactionsList> list = new List<TransactionsList>();
+            foreach (var item in result)
+            {
+                //  var nozzle = _nozzle.Where(_ => _.Id == item.NozzleId)?.First();//根据油枪id查询外部枪号
+                var nozzle = _nozzle.FirstOrDefault(_ => _.Id == item.NozzleId);//根据油枪id查询外部枪号
+                var userid = user.Where(_ => _.Id == item.MiniProgramID).First();
+                var pay = paytype.FirstOrDefault(_ => _.Id == item.PaymentMethod)?.Name;
+                TransactionsList transactions = new TransactionsList();
+                transactions.TransactionNumber = item.TransactionNumber;
+                transactions.SiteName = site.Name;
+                transactions.NozzleProductName = nozzle?.ExternalGunNumber + " | " + item.ProductName;
+                transactions.ActualPaymentAmount = item.ActualPaymentAmount.ToString();
+                transactions.TransactionTime = item.TransactionTime?.ToString("yyyy-MM-dd hh:mm:ss");
+                transactions.OrderStatus = GetChineseStatus(item.OrderStatus);
+                transactions.UserName = userid.UserName;
+                transactions.PriceQty = item.Price + " | " + item.Qty;
+                transactions.PaymentMethod = pay;
+                list.Add(transactions);
+            }
+            return ServiceResponse.Ok(list);
         }
         /// <summary>
         /// 小程序查询未支付订单
@@ -136,14 +201,17 @@ namespace Fuel.Application.Service
         /// <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)
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            Expression<Func<transactions, bool>> where = p => p.Buid == Buid;
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
+            var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+            if (userSession == null)
             {
-                return ServiceResponse.Error("用户id为空");
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
             }
-            where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID && p.OrderStatus == transactionsORDERSTATUS.Unpaid);
+            DateTime dayBeforeTime = DateTime.Now.AddDays(-1);
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+            where = CombineExpressions(where, p => p.MiniProgramID == user.Id && p.OrderStatus == transactionsORDERSTATUS.Unpaid && p.TransactionTime >= dayBeforeTime);
             var result = await _entityHelper.GetEntitiesAsync<transactions>(where);
             return ServiceResponse.Ok(result);
         }
@@ -156,13 +224,15 @@ namespace Fuel.Application.Service
         {
             Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
             Expression<Func<transactions, bool>> where = p => p.Buid == Buid;
-            Guid WachatID = HttpRequestReader.GetWachatID(); //用户
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
             var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
             if (userSession == null)
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未找到用户!");
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
             }
-            where = CombineExpressions(where, p => p.NozzleId == NozzleId && p.OrderStatus == transactionsORDERSTATUS.Unpaid);
+            DateTime dayBeforeTime = DateTime.Now.AddDays(-1);
+            var _nozzle = _fsql.Select<nozzle>().Where(_ => _.Id == NozzleId).First();//根据油枪id查询外部枪号
+            where = CombineExpressions(where, p => p.NozzleId == _nozzle.ExternalGunNumber && p.OrderStatus == transactionsORDERSTATUS.Unpaid && p.TransactionTime >= dayBeforeTime);
             var result = await _entityHelper.GetEntitiesAsync<transactions>(where);
             return ServiceResponse.Ok(result);
         }
@@ -172,18 +242,42 @@ namespace Fuel.Application.Service
         /// <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)
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            Expression<Func<transactions, bool>> where = p => p.Buid == Buid;
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
+            var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+            if (userSession == null)
             {
-                return ServiceResponse.Error("用户id为空");
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
             }
-            where = CombineExpressions(where, p => p.MiniProgramID == input.MiniProgramID && p.OrderStatus == transactionsORDERSTATUS.Paid);
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+            where = CombineExpressions(where, p => p.MiniProgramID == user.Id && p.OrderStatus == transactionsORDERSTATUS.Paid);
             var result = await _entityHelper.GetEntitiesAsync<transactions>(where);
             return ServiceResponse.Ok(result);
         }
         /// <summary>
+        /// 小程序查询已支付订单
+        /// </summary>
+        /// <returns></returns>
+        public async Task<ServiceResponse> WXFindOrders(DateTime? dateTime, int pageNum, int lineCount)
+        {
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            Expression<Func<transactions, bool>> where = p => p.Buid == Buid;
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
+            var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+            if (userSession == null)
+            {
+                return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
+            }
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+            DateTime time = dateTime != null ? (DateTime)dateTime : DateTime.Now;
+            var select = _fsql.Select<transactions>().Where(_ => _.MiniProgramID == user.Id
+            && (_.TransactionTime >= DateTime.Now.AddDays(-30) && _.TransactionTime <= time));
+            var list = await select.Page(pageNum, lineCount).OrderByDescending(_ => _.TransactionTime).ToListAsync();
+
+            return ServiceResponse.Ok(list);
+        }
+        /// <summary>
         /// 提交支付
         /// </summary>
         /// <param name="input"></param>
@@ -219,13 +313,18 @@ namespace Fuel.Application.Service
         /// <returns></returns>
         public async Task<transactions> GetRedisTransactions(UploadTransactions uploadTransactions, string key)
         {
-            string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
             var respond = RedisHelper.GetAsync(key).Result;
             if (respond == null)
             {
                 return null;
             }
             transactions transactions = JsonConvert.DeserializeObject<transactions>(respond);
+            var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == transactions.Id).Result.FirstOrDefault();
+            if (trx == null || trx.OrderStatus != transactionsORDERSTATUS.Unpaid)
+            {
+                return null;
+            }
             return transactions;
         }
         // 辅助方法:组合两个表达式
@@ -241,44 +340,43 @@ namespace Fuel.Application.Service
         /// <param name="input"></param>
         /// <returns></returns>
         public async Task<ServiceResponse> RefundTrx(int trxId,
-            double longitude,
-            double latitude)
+            double longitude = 0.0,
+            double latitude = 0.0)
         {
-            string Buid = _httpContextAccessor.HttpContext.Request.Headers["Buid"].FirstOrDefault();
-            Guid guid = Guid.Parse(Buid);
-            var businessunitinfo = _entityHelper.GetEntitiesAsync<businessunitinfo>(_ => _.Buid == guid).Result.FirstOrDefault();
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            var businessunitinfo = _entityHelper.GetEntitiesAsync<businessunitinfo>(_ => _.Buid == Buid).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))
-            {
+           // 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公里");
-            }
+           // }
+           // 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<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
             if (trx == null)
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
             }
-            else if (trx.OrderStatus == transactionsORDERSTATUS.FullyRefunded)
+            else if (trx.RefundStatus == RefundStatus.FullyRefunded)
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单已退款");
             }
-            else if (trx.OrderStatus == transactionsORDERSTATUS.PartiallyRefunded)
+            else if (trx.RefundStatus == RefundStatus.PartiallyRefunded)
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该订单已部分退款");
             }
@@ -297,75 +395,233 @@ namespace Fuel.Application.Service
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "单价获取失败");
             }
             //计算退款金额
+            //decimal RefundAmount = (decimal)trx.ActualPaymentAmount;
             decimal RefundAmount = (decimal)((trx.Qty - trx.OriginalQty) * ProductPrice.Value);
-            if (RefundAmount <= 0.0M)
-            {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该笔单无需退款");
-            }
+            //if (RefundAmount <= 0.0M)
+            //{
+            //    return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "该笔单无需退款");
+            //}
             //退款
-            var serviceResult = await _payService.ReturnProcess(RefundAmount, "ALL_IN_SCAN", trx.TransactionNumber);
+            var serviceResult = await _payService.ReturnProcess(RefundAmount, (decimal)trx.ActualPaymentAmount, "WX_SCAN", trx.BillNumber);
             Payment.Core.Models.ElectronicOrderProcessResultModel payResult = (Payment.Core.Models.ElectronicOrderProcessResultModel)serviceResult.Data;
             if (!serviceResult.IsSuccessful() || payResult.ResultCode == "PAY_ERROR")
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "退款失败");
             }
-
+            if (RefundAmount == (decimal)trx.ActualPaymentAmount)
+            {
+                trx.RefundStatus = RefundStatus.FullyRefunded;//全额退款
+            }
+            else
+            {
+                trx.RefundStatus = RefundStatus.PartiallyRefunded;//部分退款
+            }
+            trx.OrderStatus = transactionsORDERSTATUS.Cancelled;
             trx.RefundAmount = RefundAmount;
-            _entityHelper.UpdateAsync(trx);
+            int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
             return ServiceResponse.Ok(trx);
         }
         public async Task<ServiceResponse> UnifiedOrder(int trxId)
         {
-            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
-            Guid WachatID = HttpRequestReader.GetWachatID(); //用户
-            var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
-            if (userSession == null)
+            try
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未找到用户!");
+                logger.Debug("UnifiedOrder  start++");
+
+                Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+                string WachatID = HttpRequestReader.GetWachatID(); //用户
+                //var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+                //if (userSession == null)
+                //{
+                //    return ServiceResponse.Error(HttpStatusCode.NonAuthoritativeInformation, "未找到用户!");
+                //}
+                var userSession = new WechatUserSessionResponse() { buId = "12345678-9abc-def0-1234-56789abcdef0", openid = "o8pFb5cWH1KkBDvGls2X7yMiFkGA" };
+                var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid).First();
+                var weChatService = new WeChatService(site.Appid, site.Secret);
+                var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+                var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
+                if (trx == null)
+                {
+                    return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
+                }
+                logger.Debug("统一下单开始");
+                var serviceResult = await _payService.UnifiedOrder(trx.OriginalAmount.Value, "WX_SCAN", userSession.openid);
+                var dataProperties = serviceResult.Data.GetType().GetProperty("UnifiedOrderResult");
+                if (!serviceResult.IsSuccessful() || dataProperties == null)
+                {
+                    logger.Debug("统一下单失败" );
+                    return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "统一下单失败");
+                }
+
+
+                //小程序支付完后,云端需要通过订单编号去支付平台查询支付状态,以便更新订单信息
+                _ = Task.Delay(1500).ContinueWith(async _ =>
+                {
+                    using (var scope = _serviceScopeFactory.CreateScope())
+                    {
+                        var scopedMqttService = scope.ServiceProvider.GetRequiredService<IMqttClientService>();
+                        var dataProperties = serviceResult.Data.GetType().GetProperty("eOrder");
+                        var orderModel = (Fuel.Payment.Core.Models.ElectronicOrderModel)dataProperties.GetValue(serviceResult.Data);
+                        var genericResponse = await _payService.QueryOrder(orderModel);
+                        if (genericResponse.IsSuccessful() && orderModel.TradeStatus == Fuel.Payment.Core.Models.TradeStatus.SUCCESS)
+                        {
+                            trx.OrderStatus = transactionsORDERSTATUS.Paid;//将订单状态更改成已支付
+                            trx.MiniProgramID = user.Id;
+                            trx.BillNumber = orderModel.BillNumber;
+                            trx.ActualPaymentAmount = trx.OriginalAmount;
+                            trx.PaymentMethod = 2;//2 :微信支付
+                            try
+                            {
+                                await scopedMqttService.SubscribeAsync("paid/" + Buid);
+                                string jsonString = JsonConvert.SerializeObject(trx);
+                                await Task.Delay(2000);
+                                var sendjson = new { data = jsonString, UserName = user.UserName, UserPhoneNumber = user.UserPhoneNumber };
+                                //支付完成将订单信息推送到fcc
+                                await scopedMqttService.PublishAsync("paid/" + Buid, JsonConvert.SerializeObject(sendjson));
+                            }
+                            catch (Exception ex)
+                            {
+
+                            }
+
+                            int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
+                            //SendMessage(trx,Buid);
+                        }
+                    }
+                });
+                var unifiedOrderResult = dataProperties.GetValue(serviceResult.Data);
+                var options = new JsonSerializerOptions
+                {
+                    IgnoreReadOnlyProperties = true // 忽略只读属性
+                };
+                string serializedUnifiedOrderResult = System.Text.Json.JsonSerializer.Serialize(unifiedOrderResult, options);
+                logger.Debug("统一下单 支付信息 " + serializedUnifiedOrderResult);
+                return ServiceResponse.Ok(unifiedOrderResult);
+            }
+            catch (Exception ex)
+            {
+                logger.Debug("统一下单: "+ex.Message);
+                return ServiceResponse.Error(ex.Message);
             }
+        }
+        public async Task<ServiceResponse> Redeem(int trxId, decimal OriginalQty)
+        {
             var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
             if (trx == null)
             {
                 return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
             }
-            var serviceResult = await _payService.UnifiedOrder((decimal)trx.OriginalAmount, "WX_SCAN", userSession.unionid);
-            var dataProperties = serviceResult.Data.GetType().GetProperty("UnifiedOrderResult");
-            if (!serviceResult.IsSuccessful() || dataProperties == null)
+            trx.OriginalQty = OriginalQty;
+            var refund = await RefundTrx(trxId);
+            if (refund.IsSuccessful() || refund.StatusCode == HttpStatusCode.NotAcceptable)
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "统一下单失败");
+                trx.OrderStatus = transactionsORDERSTATUS.Completed;
             }
+            int affectedRows = _fsql.Update<transactions>().SetSource(trx).ExecuteAffrows();
+            return ServiceResponse.Ok(trx);
+        }
+        /// <summary>
+        /// 微信发送模板消息
+        /// </summary>
+        /// <returns></returns>
+        public async Task SendMessage(int trxId, string orderType)
+        {
+            var data = new Dictionary<string, object>();//动态字段
+
+            Guid Buid = HttpRequestReader.GetCurrentBuId(); //站点id
+            var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
+            var site = _fsql.Select<businessunitinfo>().Where(_ => _.Buid == Buid).First();
+            var weChatService = new WeChatService(site.Appid, site.Secret);
+            string WachatID = HttpRequestReader.GetWachatID(); //用户
+                                                               //var userSession = WechatUserSessionRepo.GetUserSession(WachatID.ToString());
+                                                               //if (userSession == null)
+                                                               //{
+                                                               //}
+                                                               //var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == userSession.openid).First();
+
+            var user = _fsql.Select<miniprogramusers>().Where(_ => _.OpenId == WachatID).First();
+            var template = _fsql.Select<configuration>().Where(_ => _.Buid == Buid && _.Type == 2 && _.Name == "小程序通知模板").First();
+            if (template == null)
+            {
+                //模板获取失败
+                return;
+            }
+
+            var config = JsonConvert.DeserializeObject<TemplateConfig>(template.Value);
+            var dataDict = new Dictionary<string, object>();
+            var dynamicData = new Dictionary<string, object>
+            {
+                { "orderType", orderType },
+                { "BillNumber", trx.BillNumber},
+                { "ProductName_Qty", trx.ProductName + " | " + trx.Qty + "L"},
+                { "ActualPaymentAmount", trx.ActualPaymentAmount },
+                { "TransactionTime", ToFormattedString(trx.TransactionTime) }
+            };
+
 
-            //小程序支付完后,云端需要通过订单编号去支付平台查询支付状态,以便更新订单信息
-            _ = Task.Delay(5000).ContinueWith(async _ =>
+            foreach (var mapping in config.DataMappings)
             {
-                var dataProperties = serviceResult.Data.GetType().GetProperty("eOrder");
-                var orderModel = (Fuel.Payment.Core.Models.ElectronicOrderModel)dataProperties.GetValue(serviceResult.Data);
-                var genericResponse = await _payService.QueryOrder(orderModel);
-                if (genericResponse.IsSuccessful())
+                string dataFieldName = mapping.Key;
+                string targetFieldName = mapping.Value;
+
+                if (dynamicData.TryGetValue(dataFieldName, out object value))
                 {
-                    trx.OrderStatus = transactionsORDERSTATUS.Paid;//将订单状态更改成已支付
-                    await _mqttService.SubscribeAsync("fromClound/" + Buid);
-                    string jsonString = JsonConvert.SerializeObject(trx);
-                    await Task.Delay(2000);
-                    var sendjson = new { type = 3, data = jsonString };
-                    ///支付完成将订单信息推送到fcc
-                    await _mqttService.PublishAsync("fromClound/" + Buid, JsonConvert.SerializeObject(sendjson));
-                    _entityHelper.UpdateAsync(trx);
+                    dataDict.Add(targetFieldName, new { value = value });
                 }
-            });
-            var unifiedOrderResult = dataProperties.GetValue(serviceResult.Data);
-            return ServiceResponse.Ok(unifiedOrderResult);
+            }
+            // 准备要发送的模板消息内容
+            var templateMessage = new WeChatService.TemplateMessage
+            {
+                ToUser = user.OpenId,
+                TemplateId = config.TemplateId,
+                Page = "pages/historyOrder/historyOrder",
+                Data = dataDict
+            };
+            //var templateMessage = new WeChatService.TemplateMessage
+            //{
+            //    ToUser = user.OpenId,
+            //    TemplateId = "V0tl-4n-5hwNZc4SrEttvrmawAyM-SB0pQWZNwp54Ks",
+            //    Page = "pages/historyOrder/historyOrder",
+            //    Data = new
+            //    {
+            //        short_thing10 = new { value = orderType },
+            //        character_string11 = new { value = trx.BillNumber },
+            //        thing12 = new { value = trx.ProductName + " | " + trx.Qty + "L"},
+            //        amount13 = new { value = trx.ActualPaymentAmount },
+            //        time14 = new { value = ToFormattedString(trx.TransactionTime) },
+            //    }
+            //};
+            weChatService.SendTemplateMessage(templateMessage);
         }
-        public async Task<ServiceResponse> Redeem(int trxId, decimal OriginalQty)
+        public string ToFormattedString(DateTime? dateTime)
         {
-            var trx = _entityHelper.GetEntitiesAsync<transactions>(_ => _.Id == trxId).Result.FirstOrDefault();
-            if (trx == null)
+            if (dateTime.HasValue)
             {
-                return ServiceResponse.Error(HttpStatusCode.NotAcceptable, "未查询到订单!");
+                return dateTime.Value.ToString("yyyy-MM-dd HH:mm:ss");
+            }
+            else
+            {
+                return null;
+            }
+        }
+        public static string GetChineseStatus(transactionsORDERSTATUS status)
+        {
+            switch (status)
+            {
+                case transactionsORDERSTATUS.Unpaid:
+                    return "订单未支付";
+                case transactionsORDERSTATUS.Paid:
+                    return "订单已支付";
+                case transactionsORDERSTATUS.Paying:
+                    return "订单正在支付中";
+                case transactionsORDERSTATUS.CardPayment:
+                    return "订单通过卡支付";
+                case transactionsORDERSTATUS.Completed:
+                    return "订单已完成";
+                case transactionsORDERSTATUS.Cancelled:
+                    return "已取消";
+                default:
+                    throw new ArgumentOutOfRangeException(nameof(status), status, null);
             }
-            trx.OriginalQty = OriginalQty;
-            _entityHelper.UpdateAsync(trx);
-            return ServiceResponse.Ok(trx);
         }
     }
 }

+ 29 - 8
FuelCloud/Fuel.Application/Service/UserService.cs

@@ -35,8 +35,8 @@ namespace Fuel.Application.Service
             var permissionList = new List<string>();
             foreach (var permission in Permission)
             {
-                if(permission.d != null)
-                permissionList.Add(permission.d.Code);
+                if (permission.d != null)
+                    permissionList.Add(permission.d.Code);
             }
             permissionList.Add("Nozzle:uploadNozzle:POST");
             permissionList.Add("Nozzle:UpdateNozzle:PUT");
@@ -46,7 +46,8 @@ namespace Fuel.Application.Service
             permissionList.Add("Nozzle:uploadProduct:POST");
             permissionList.Add("Nozzle:UpdateProduct:Put");
             permissionList.Add("Nozzle:DeleteProduct:Delete");
-            permissionList.Add("Nozzle:GetNozzleInfo:GET");
+            permissionList.Add("Nozzle:GetFuelNozzleInfoByExternalId:GET");
+            permissionList.Add("Nozzle:GetFuelNozzleInfoById:GET");
 
             permissionList.Add("Nozzle:uploadTanks:POST");
             permissionList.Add("Nozzle:UpdateTanks:Put");
@@ -57,18 +58,27 @@ namespace Fuel.Application.Service
             permissionList.Add("Nozzle:CancelNozzleAuthorization:GET");
 
             permissionList.Add("Transactions:CreateTransactions:POST");
-            permissionList.Add("Transactions:UnifiedOrder:GET");
+            permissionList.Add("Transactions:UnifiedOrder:POST");
             permissionList.Add("Transactions:NozzleAuthorization:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsUnpaidQuery:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsUnpaidNozzle:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsPaidQuery:GET");
+            permissionList.Add("Transactions:RefundTrx:POST");
+            permissionList.Add("Transactions:WXFindOrders:GET");
+            permissionList.Add("Transactions:SendMessage:POST");
+            permissionList.Add("Transactions:GetTransactions:POST");
 
             permissionList.Add("Site:AddMiniprogramUser:POST");
             permissionList.Add("Site:GetSiteInfo:GET");
+            permissionList.Add("Site:GetSiteInformationAndConfiguration:GET");
+            permissionList.Add("Site:AddSite:POST");
             return permissionList;
 
         }
         public List<string> GetSitePermissions(string Appid)
         {
-            var Permission = _fsql.Select<AdApply, AdRoleApply, AdRole,AdRolePermission, AdPermission>()
- .LeftJoin((a, b, c, d,e) => a.Id == b.OauthApplyID)
+            var Permission = _fsql.Select<AdApply, AdRoleApply, AdRole, AdRolePermission, AdPermission>()
+ .LeftJoin((a, b, c, d, e) => a.Id == b.OauthApplyID)
  .LeftJoin((a, b, c, d, e) => b.OauthRoleID == c.Id)
  .LeftJoin((a, b, c, d, e) => c.Id == d.RoleId)
   .LeftJoin((a, b, c, d, e) => d.PermissionId == e.Id)
@@ -88,7 +98,8 @@ namespace Fuel.Application.Service
             permissionList.Add("Nozzle:uploadProduct:POST");
             permissionList.Add("Nozzle:UpdateProduct:Put");
             permissionList.Add("Nozzle:DeleteProduct:Delete");
-            permissionList.Add("Nozzle:GetNozzleInfo:GET");
+            permissionList.Add("Nozzle:GetFuelNozzleInfoByExternalId:GET");
+            permissionList.Add("Nozzle:GetFuelNozzleInfoById:GET");
 
             permissionList.Add("Nozzle:uploadTanks:POST");
             permissionList.Add("Nozzle:UpdateTanks:Put");
@@ -99,10 +110,20 @@ namespace Fuel.Application.Service
             permissionList.Add("Nozzle:CancelNozzleAuthorization:GET");
 
             permissionList.Add("Transactions:CreateTransactions:POST");
-            permissionList.Add("Transactions:UnifiedOrder:GET");
+            permissionList.Add("Transactions:UnifiedOrder:POST");
+            permissionList.Add("Transactions:NozzleAuthorization:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsUnpaidQuery:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsUnpaidNozzle:GET");
+            permissionList.Add("Transactions:GetMiniProgramTransactionsPaidQuery:GET");
+            permissionList.Add("Transactions:RefundTrx:POST");
+            permissionList.Add("Transactions:WXFindOrders:GET");
+            permissionList.Add("Transactions:SendMessage:POST");
+            permissionList.Add("Transactions:GetTransactions:POST");
 
             permissionList.Add("Site:AddMiniprogramUser:POST");
             permissionList.Add("Site:GetSiteInfo:GET");
+            permissionList.Add("Site:GetSiteInformationAndConfiguration:GET");
+            permissionList.Add("Site:AddSite:POST");
             return permissionList;
         }
         public Task<users> GetUsers()

+ 12 - 0
FuelCloud/src/Fuel.Payment.Server/.config/dotnet-tools.json

@@ -0,0 +1,12 @@
+{
+  "version": 1,
+  "isRoot": true,
+  "tools": {
+    "dotnet-ef": {
+      "version": "9.0.2",
+      "commands": [
+        "dotnet-ef"
+      ]
+    }
+  }
+}

+ 12 - 5
FuelCloud/src/Fuel.Payment.Server/Controllers/AuthController.cs

@@ -32,17 +32,23 @@ namespace Fuel.PaymentServer.Controllers
         /// <summary>
         /// 登录
         /// </summary>
-        /// <param name="login"></param>
+        /// <param name="login"></param> 
         /// <returns></returns>
-        [HttpGet("login")]
+        [HttpPost("login")]
         public IActionResult Login([FromBody] LoginModel login)
         {
-            var user = _userService.ValidateCredentials(login.Username, login.Password);
+            var user = _userService.ValidateCredentials(login.userName, login.password);
             if (user == null)
                 return Unauthorized();
 
             var tokenString = GenerateJwt(user);
-            return Ok(new { Token = tokenString });
+            var result = new {
+                success = true,
+                code = "",
+                msg = "",
+                data = new { token = tokenString,buid = user.Buid }
+            };
+            return Ok(result);
         }
         /// <summary>
         /// 小程序登录
@@ -64,6 +70,7 @@ namespace Fuel.PaymentServer.Controllers
 
 
 
+
         private string GenerateJwt(users user)
         {
             var jwtSettings = ConstKey.JwtKey;
@@ -81,7 +88,7 @@ namespace Fuel.PaymentServer.Controllers
                 issuer: ConstKey.JwtIssuer,
                 audience: ConstKey.JwtAudience,
                 claims: claims,
-                expires: DateTime.Now.AddMinutes(15),
+                expires: DateTime.Now.AddMinutes(120),
                 signingCredentials: credentials
             );
 

+ 22 - 4
FuelCloud/src/Fuel.Payment.Server/Controllers/NozzleController.cs

@@ -58,6 +58,11 @@ namespace Fuel.PaymentServer.Controllers
             var serviceResult = await InozzleService.DeleteNozzle(uploadNozzle);
             return Ok(serviceResult);
         }
+        /// <summary>
+        /// fcc更新油枪状态
+        /// </summary>
+        /// <param name="uploadNozzleStatuses"></param>
+        /// <returns></returns>
         [Permission("Nozzle:UpdateNozzleStatus:PUT")]
         [Route("UpdateNozzleStatus")]
         [HttpPut]
@@ -67,14 +72,27 @@ namespace Fuel.PaymentServer.Controllers
             return Ok(serviceResult);
         }
         /// <summary>
-        /// 获取油枪信息
+        /// 根据外部枪号获取油枪信息
+        /// </summary>
+        /// <param name="Nozzleid"></param>
+        /// <returns></returns>
+        [Permission("Nozzle:GetFuelNozzleInfoByExternalId:GET")]
+        [Route("GetFuelNozzleInfoByExternalId")]
+        [HttpGet]
+        public async Task<List<NozzleInfo>> GetFuelNozzleInfoByExternalId(int ExternalGunNumber)
+        {
+            var data = await InozzleService.GetNozzleInfo(ExternalGunNumber);
+            return data;
+        }
+        /// <summary>
+        /// 根据油枪ID获取油枪信息
         /// </summary>
         /// <param name="Nozzleid"></param>
         /// <returns></returns>
-        [Permission("Nozzle:GetNozzleInfo:GET")]
-        [Route("GetNozzleInfo")]
+        [Permission("Nozzle:GetFuelNozzleInfoById:GET")]
+        [Route("GetFuelNozzleInfoById")]
         [HttpGet]
-        public async Task<List<NozzleInfo>> GetNozzleInfo(int Nozzleid)
+        public async Task<List<NozzleInfo>> GetFuelNozzleInfoById(int Nozzleid)
         {
             var data = await InozzleService.GetNozzleInfo(Nozzleid);
             return data;

+ 36 - 9
FuelCloud/src/Fuel.Payment.Server/Controllers/SiteController.cs

@@ -12,9 +12,9 @@ namespace Fuel.PaymentServer.Controllers
     public class SiteController : ControllerBase
     {
         private readonly ISiteService _siteService;
-       public SiteController(ISiteService siteService)
-        { 
-             _siteService = siteService;
+        public SiteController(ISiteService siteService)
+        {
+            _siteService = siteService;
         }
         /// <summary>
         /// 获取站点信息与用户信息
@@ -39,14 +39,41 @@ namespace Fuel.PaymentServer.Controllers
         [HttpPost]
         public async Task<IActionResult> AddMiniprogramUser(AddWechatUser user)
         {
-            var serviceResult = await _siteService.AddMiniprogramUser("1", user.UserName, user.UserAvatarUrl, user.UserPhoneNumber, user.Address);
+            var serviceResult = await _siteService.AddMiniprogramUser("1", user);
             return Ok(serviceResult);
 
         }
-   //     public async Task<IActionResult> AddMiniprogramUser(
-   //string UserName,
-   //string UserAvatarUrl,
-   //string UserPhoneNumber,
-   //string Address)
+        /// <summary>
+        /// 获取站点信息与用户信息
+        /// </summary>
+        /// <param name=""></param>
+        /// <returns></returns>
+        [Permission("Site:GetSiteInformationAndConfiguration:GET")]
+        [Route("GetSiteInformationAndConfiguration")]
+        [HttpGet]
+        public async Task<IActionResult> GetSiteInformationAndConfiguration()
+        {
+            var serviceResult = await _siteService.GetSiteInformationAndConfiguration();
+            return Ok(serviceResult);
+        }
+        /// <summary>
+        /// 添加站点信息
+        /// </summary>
+        /// <returns></returns>
+        [Permission("Site:AddSite:POST")]
+        [Route("AddSite")]
+        [HttpPost]
+        public async Task<IActionResult> AddSite(AddSite site)
+        {
+            var serviceResult = await _siteService.AddSite(site);
+            return Ok(serviceResult);
+
+
+            //     public async Task<IActionResult> AddMiniprogramUser(
+            //string UserName,
+            //string UserAvatarUrl,
+            //string UserPhoneNumber,
+            //string Address)
+        }
     }
 }

+ 54 - 14
FuelCloud/src/Fuel.Payment.Server/Controllers/TransactionsController.cs

@@ -15,9 +15,10 @@ namespace Fuel.PaymentServer.Controllers
     public class TransactionsController : ControllerBase
     {
         private readonly ITransactionsService _transactionsService;
+        static NLog.Logger logger = NLog.LogManager.LoadConfiguration("nlog.xml").GetLogger("Main");
         public TransactionsController(ITransactionsService transactionsService)
-        { 
-             _transactionsService = transactionsService;
+        {
+            _transactionsService = transactionsService;
         }
         /// <summary>
         /// 创建订单
@@ -37,12 +38,14 @@ namespace Fuel.PaymentServer.Controllers
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
+        [Permission("Transactions:GetTransactions:POST")]
         [Route("GetTransactions")]
         [HttpPost]
-        public async Task<IActionResult> GetTransactionsAsync(TransactionsInput input)
+        public async Task<IActionResult> GetTransactionsAsync(RequestModel input)
         {
             var serviceResult = await _transactionsService.GetTransactionsAsync(input);
             return Ok(serviceResult);
+
         }
         /// <summary>
         /// 小程序用户查询未支付订单
@@ -77,14 +80,27 @@ namespace Fuel.PaymentServer.Controllers
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
+        [Permission("Transactions:GetMiniProgramTransactionsPaidQuery:GET")]
         [Route("GetMiniProgramTransactionsPaidQuery")]
-        [HttpPost]
+        [HttpGet]
         public async Task<IActionResult> GetMiniProgramTransactionsPaidAsync(TransactionsInput input)
         {
             var serviceResult = await _transactionsService.GetMiniProgramTransactionsPaidAsync(input);
             return Ok(serviceResult);
         }
 
+        /// <summary>
+        /// 小程序查询历史订单
+        /// </summary>
+        /// <returns></returns>
+        [Permission("Transactions:WXFindOrders:GET")]
+        [Route("WXFindOrders")]
+        [HttpGet]
+        public async Task<IActionResult> WXFindOrders(DateTime? dateTime, int pageNum, int lineCount)
+        {
+            var serviceResult = await _transactionsService.WXFindOrders(dateTime, pageNum, lineCount);
+            return Ok(serviceResult);
+        }
 
         /// <summary>
         /// 提交支付
@@ -94,7 +110,7 @@ namespace Fuel.PaymentServer.Controllers
         /// <returns></returns>
         [Route("Payment")]
         [HttpPost]
-        public async Task<IActionResult> CommitPayment(int trxId,string AuthCode)
+        public async Task<IActionResult> CommitPayment(int trxId, string AuthCode)
         {
             var serviceResult = await _transactionsService.CommitPayment(trxId, AuthCode);
             return Ok(serviceResult);
@@ -107,11 +123,12 @@ namespace Fuel.PaymentServer.Controllers
         /// <param name="longitude">经度</param>
         /// <param name="latitude">纬度</param>
         /// <returns></returns>
-        [Route("Refund")]
+        [Permission("Transactions:RefundTrx:POST")]
+        [Route("RefundTrx")]
         [HttpPost]
-        public async Task<IActionResult> RefundTrx(int trxId, double longitude,double latitude)
+        public async Task<IActionResult> RefundTrx(RefundTrxRequest refundTrx)
         {
-            var serviceResult = await _transactionsService.RefundTrx( trxId,  longitude,  latitude);
+            var serviceResult = await _transactionsService.RefundTrx(refundTrx.trxId, refundTrx.longitude, refundTrx.latitude);
             return Ok(serviceResult);
         }
         /// <summary>
@@ -122,9 +139,9 @@ namespace Fuel.PaymentServer.Controllers
         /// <returns></returns>
         [Route("Redeem")]
         [HttpPost]
-        public async Task<IActionResult> Redeem(int trxId,decimal OriginalQty)
+        public async Task<IActionResult> Redeem(RedeemRequest redeemRequest)
         {
-            var serviceResult = await _transactionsService.Redeem(trxId, OriginalQty);
+            var serviceResult = await _transactionsService.Redeem(redeemRequest.trxId, redeemRequest.OriginalQty);
             return Ok(serviceResult);
         }
         /// <summary>
@@ -132,13 +149,36 @@ namespace Fuel.PaymentServer.Controllers
         /// </summary>
         /// <param name="trxid"></param>
         /// <returns></returns>
-        [Permission("Transactions:UnifiedOrder:GET")]
+        [Permission("Transactions:UnifiedOrder:POST")]
         [Route("UnifiedOrder")]
-        [HttpGet]
+        [HttpPost]
         public async Task<IActionResult> UnifiedOrder(int trxid)
         {
-            var serviceResult = await _transactionsService.UnifiedOrder(trxid);
-            return Ok(serviceResult);
+            try
+            {
+                var serviceResult = await _transactionsService.UnifiedOrder(trxid);
+                logger.Debug("TransactionsController  成功" );
+                return Ok(serviceResult);
+            }
+            catch (Exception ex)
+            {
+                logger.Debug("TransactionsController  :" + ex.Message);
+                return Ok(ex);
+            }
         }
+        /// <summary>
+        /// 发送模板消息
+        /// </summary>
+        /// <param name="trxid"></param>
+        /// <returns></returns>
+        [Permission("Transactions:SendMessage:POST")]
+        [Route("SendMessage")]
+        [HttpPost]
+        public async Task<IActionResult> SendMessage(WechatTemplateMessage wechatTemplateMessage)
+        {
+            await _transactionsService.SendMessage(wechatTemplateMessage.trxid, wechatTemplateMessage.orderType);
+            return Ok();
+        }
+
     }
 }

+ 1 - 0
FuelCloud/src/Fuel.Payment.Server/Fuel.PaymentServer.csproj

@@ -13,6 +13,7 @@
     <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="8.0.6" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="8.0.5" />
     <PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.3.7.1207" />
+    <PackageReference Include="NLog" Version="5.4.0" />
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
   </ItemGroup>
 

+ 5 - 0
FuelCloud/src/Fuel.Payment.Server/MicServer/Middlewares/SignatureValidator.cs

@@ -68,6 +68,11 @@ namespace DFS.Core.Mvc.Middlewares
                 {
                     stringToSign += "&" + bodyContent;
                 }
+                if (request.QueryString.Value != "")
+                {
+                    var querystring = request.QueryString.Value.Substring(1);
+                    stringToSign += "&" + querystring;
+                }
               //var sfd =  Sm4Encryptor.Encrypt(stringToSign, Secret);
                 //stringToSign = Sm4Encryptor.Encrypt(stringToSign, Secret);
                 stringToSign = stringToSign.SM4Encrypt_ECB(Secret);

+ 38 - 1
FuelCloud/src/Fuel.Payment.Server/Program.cs

@@ -26,6 +26,8 @@ using System.Text;
 using DFS.Core.Mvc.Middlewares;
 using Fuel.Payment.Service.WeChatPaymentProcessor.Wechat;
 using Fuel.Application.MqttService;
+using System.Text.Json;
+
 
 var builder = WebApplication.CreateBuilder(args);
 builder.Services.AddScoped<IPayService, PayService>();
@@ -110,11 +112,46 @@ builder.Services.AddAuthorization(options =>
 //mqtt注册
 builder.Services.Configure<MqttOptions>(builder.Configuration.GetSection("Mqtt"));
 builder.Services.AddScoped<IMqttClientService, MqttClientService>();
+builder.Logging.ClearProviders();
+
+// 添加CORS服务,并允许所有来源
+builder.Services.AddCors(options =>
+{
+    options.AddPolicy("AllowAll", policy =>
+    {
+        policy.AllowAnyOrigin()    // 允许所有来源(生产环境应指定具体域名)
+              .AllowAnyMethod()    // 允许所有 HTTP 方法
+              .AllowAnyHeader()    // 允许所有请求头
+              .SetPreflightMaxAge(TimeSpan.FromSeconds(86400)); // 预检请求缓存时间
+    });
+});
 
+builder.WebHost.ConfigureKestrel(options =>
+{
+    options.Listen(System.Net.IPAddress.Parse("192.168.0.202"), 5006); // 监听特定IPv4地址的5002端口
+    //options.Listen(System.Net.IPAddress.Parse("172.31.2.202"), 5006); // 监听特定IPv4地址的5002端口
+    options.Listen(System.Net.IPAddress.Parse("::1"), 5006); // 监听特定IPv6地址(这里是localhost)的5003端口
+});
+builder.Services.AddControllers()
+    .AddJsonOptions(options =>
+    {
+        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; // 支持 camelCase
+        options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
+    });
 
 var app = builder.Build();
 
 app.UseRouting();
+app.UseCors("AllowAll");
+app.Use(async (context, next) =>
+{
+    context.Response.Headers["Referrer-Policy"] = "strict-origin-when-cross-origin";
+    context.Request.EnableBuffering(); // 允许多次读取
+    var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
+    Console.WriteLine($"Request Body: {requestBody}");
+    context.Request.Body.Position = 0; // 重置流的位置
+    await next();
+});
 
 var loggerFactory = LoggerFactory.Create(builder =>
 {
@@ -144,5 +181,5 @@ app.UseAuthentication();
 app.UseAuthorization();
 
 app.MapControllers();
-app.Urls.Add("http://192.168.88.140:5006");
+//app.Urls.Add("http://localhost:5006");
 app.Run();

+ 1 - 1
FuelCloud/src/Fuel.Payment.Server/appsettings.json

@@ -15,7 +15,7 @@
     "KeyName": "Trans"
   },
   "Mqtt": {
-    "Server": "10.153.148.121",
+    "Server": "produce.hsfuel.com",
     "Port": 1883,
     "Username": "",
     "Password": ""

+ 27 - 0
FuelCloud/src/Fuel.Payment.Server/nlog.xml

@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- XSD manual extracted from package NLog.Schema: https://www.nuget.org/packages/NLog.Schema-->
+<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xsi:schemaLocation="NLog NLog.xsd"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      autoReload="true"
+      internalLogFile="log//log-internal.log"
+      internalLogLevel="Info" >
+
+
+  <!-- the targets to write to -->
+  <targets>
+    <!-- write logs to file -->
+    <!--${date}|${level:uppercase=true}|${message} ${exception}|${logger}|${all-event-properties}-->
+    <!--keep this 2 forward slash, it both worked for windows and linux-->
+    <target xsi:type="File" name="main_target" enableArchiveFileCompression="true" archiveEvery="Day" archiveNumbering="DateAndSequence"
+            fileName="log//Main_${date:format=yyyyMMdd}.log"
+            layout="${date:format=HH\:mm\:ss.fff} [${threadid}:${level:uppercase=true}]${logger} - ${message} ${exception}" />
+
+  </targets>
+
+  <!-- rules to map from logger name to target -->
+  <rules>
+    <logger name="Main" minlevel="Debug" writeTo="main_target" />
+    <logger name="default" minlevel="Info" writeTo="main_target" />
+
+  </rules>
+</nlog>

+ 5 - 0
FuelCloud/src/Fuel.Payment.Service/AliPaymentProcessor/Alipay/AlipayPaymentProcessor.cs

@@ -335,5 +335,10 @@ namespace Fuel.Payment.Service.AliPaymentProcessor.Alipay
         {
             throw new NotImplementedException();
         }
+
+        protected override Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 4 - 0
FuelCloud/src/Fuel.Payment.Service/AllInPayProcessor/AllInPay/AllInPayProcessor.cs

@@ -473,6 +473,10 @@ namespace Fuel.Payment.Service.AllInPayProcessor.AllInPay
             throw new NotImplementedException();
         }
 
+        protected override Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }
 public class PeriodicTask

+ 9 - 0
FuelCloud/src/Fuel.Payment.Service/Factory/AsyncPaymentProcessor.cs

@@ -42,5 +42,14 @@ namespace Fuel.Payment.Service.Factory
         /// <param name="electronicOrderModel"></param>
         /// <returns></returns>
         protected abstract Task<object> UnifiedOrderResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel);
+
+        /// <summary>
+        /// 退款结果
+        /// </summary>
+        /// <param name="order"></param>
+        /// <param name="electronicOrderModel"></param>
+        /// <returns></returns>
+        protected abstract Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel);
+
     }
 }

+ 1 - 1
FuelCloud/src/Fuel.Payment.Service/Pay/IPayService.cs

@@ -11,7 +11,7 @@ namespace Fuel.Payment.Service.Pay
     public interface IPayService
     {
         Task<ServiceResponse> PerformElectronicProcess(string AuthCode, decimal payDueAmount, string Channel = "ALL_IN_SCAN", string preCreatedBillNumber = "");
-        Task<ServiceResponse> ReturnProcess(decimal payDueAmount, string Channel = "ALL_IN_SCAN", string preCreatedBillNumber = "");
+        Task<ServiceResponse> ReturnProcess(decimal payDueAmount, decimal totalAmount, string Channel = "ALL_IN_SCAN", string preCreatedBillNumber = "");
         Task<ServiceResponse> UnifiedOrder(decimal payDueAmount, string Channel = "ALL_IN_SCAN", string userId = "001");
         Task<ServiceResponse> QueryOrder(ElectronicOrderModel eOrder);
     }

+ 54 - 39
FuelCloud/src/Fuel.Payment.Service/Pay/PayService.cs

@@ -18,6 +18,7 @@ namespace Fuel.Payment.Service.Pay
 {
     public class PayService : IPayService
     {
+        static NLog.Logger logger = NLog.LogManager.LoadConfiguration("nlog.xml").GetLogger("Main");
         /// <summary>
         /// 支付处理
         /// </summary>
@@ -59,13 +60,10 @@ namespace Fuel.Payment.Service.Pay
         /// <returns></returns>
         public async Task<ServiceResponse> ReturnProcess(
             decimal payDueAmount,
+            decimal totalAmount,
             string Channel = "ALL_IN_SCAN",
             string preCreatedBillNumber = "")
         {
-            if (string.IsNullOrEmpty(preCreatedBillNumber))
-            {
-                preCreatedBillNumber = SequenceNumber.Next();
-            }
             ElectronicOrderModel eOrder = new ElectronicOrderModel
             {
                 Channel = Channel,
@@ -77,7 +75,8 @@ namespace Fuel.Payment.Service.Pay
                 FuelOrderDetails = new List<FuelOrderDetailModel>(),
                 OperatorId = "001",
                 SiteId = "66668888",
-                Config = ""
+                Config = "",
+                TotalAmount = totalAmount,
             };
             var eProcessor = AsyncPaymentProcessorFactory.Default.Get(eOrder);
             //var payConfig = await eProcessor.Initialize(eOrder).ConfigureAwait(false);
@@ -98,39 +97,48 @@ namespace Fuel.Payment.Service.Pay
             string userId = "001"
             )
         {
-            var optionalParam = new Dictionary<string, object>();
-            if (!string.IsNullOrEmpty(userId))
+            try
             {
-                optionalParam.Add("mobilePayId", userId);
+                var optionalParam = new Dictionary<string, object>();
+                if (!string.IsNullOrEmpty(userId))
+                {
+                    optionalParam.Add("mobilePayId", userId);
+                }
+                ElectronicOrderModel eOrder = new ElectronicOrderModel
+                {
+                    Channel = Channel,
+                    IsRefund = false,
+                    AuthCode = "",
+                    BillNumber = SequenceNumber.Next(),
+                    NetAmount = payDueAmount,
+                    Title = "Wayne Payment",
+                    FuelOrderDetails = new List<FuelOrderDetailModel>(),
+                    OperatorId = "001",
+                    SiteId = "66668888",
+                    Config = "",
+                    Optional = optionalParam,
+                };
+                var eProcessor = AsyncPaymentProcessorFactory.Default.Get(eOrder);
+                //var payConfig = await eProcessor.Initialize(eOrder).ConfigureAwait(false);
+                //eOrder.Config = payConfig.electronicOrderModel?.Config;
+                var genericResponseAlipay = await eProcessor.UnifiedOrder(eOrder).ConfigureAwait(false);
+                //_ = Task.Delay(5000).ContinueWith(async _ =>
+                //{
+                //    var genericResponse = await eProcessor.Query(eOrder, 40, 2000).ConfigureAwait(false);
+                //    if (eOrder.TradeStatus == TradeStatus.SUCCESS)
+                //    { 
+
+                //    }
+                //});
+                return new ServiceResponse { StatusCode = HttpStatusCode.OK, Data = new { UnifiedOrderResult = genericResponseAlipay.UnifiedOrderResult, eOrder = eOrder } };
+
             }
-            ElectronicOrderModel eOrder = new ElectronicOrderModel
+            catch ( Exception ex )
             {
-                Channel = Channel,
-                IsRefund = false,
-                AuthCode = "",
-                BillNumber = SequenceNumber.Next(),
-                NetAmount = payDueAmount,
-                Title = "Wayne Payment",
-                FuelOrderDetails = new List<FuelOrderDetailModel>(),
-                OperatorId = "001",
-                SiteId = "66668888",
-                Config = "",
-                Optional = optionalParam,
-            };
-            var eProcessor = AsyncPaymentProcessorFactory.Default.Get(eOrder);
-            //var payConfig = await eProcessor.Initialize(eOrder).ConfigureAwait(false);
-            //eOrder.Config = payConfig.electronicOrderModel?.Config;
-            var genericResponseAlipay = await eProcessor.UnifiedOrder(eOrder).ConfigureAwait(false);
-            _ = Task.Delay(5000).ContinueWith(async _ =>
-            {
-                var genericResponse = await eProcessor.Query(eOrder, 40, 2000).ConfigureAwait(false);
-                if (eOrder.TradeStatus == TradeStatus.SUCCESS)
-                { 
-
-                }
-            });
-            return new ServiceResponse { StatusCode = HttpStatusCode.OK, Data = new { UnifiedOrderResult = genericResponseAlipay.UnifiedOrderResult, eOrder = eOrder } };
-        }
+                logger.Debug("PayService UnifiedOrder :" + ex.Message );
+                return new ServiceResponse(HttpStatusCode.NotExtended, ex);
+            }
+  }
         /// <summary>
         /// 查询订单
         /// </summary>
@@ -138,11 +146,18 @@ namespace Fuel.Payment.Service.Pay
         /// <returns></returns>
         public async Task<ServiceResponse> QueryOrder(ElectronicOrderModel eOrder)
         {
-            var eProcessor = AsyncPaymentProcessorFactory.Default.Get(eOrder);
-            var genericResponse = await eProcessor.Query(eOrder, 40, 2000).ConfigureAwait(false);
-            if (eOrder.TradeStatus == TradeStatus.SUCCESS)
+            try
             {
-                return ServiceResponse.Ok(true);
+                var eProcessor = AsyncPaymentProcessorFactory.Default.Get(eOrder);
+                var genericResponse = await eProcessor.Query(eOrder, 40, 2000).ConfigureAwait(false);
+                if (eOrder.TradeStatus == TradeStatus.SUCCESS)
+                {
+                    return ServiceResponse.Ok(true);
+                }
+            }
+            catch (Exception ex)
+            {
+
             }
             return ServiceResponse.Error();
         }

+ 5 - 0
FuelCloud/src/Fuel.Payment.Service/UnionPayProcessor/MiniUnionPayProcessor.cs

@@ -372,5 +372,10 @@ namespace Fuel.Payment.Service.UnionPayProcessor
         {
             throw new NotImplementedException();
         }
+
+        protected override Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 5 - 0
FuelCloud/src/Fuel.Payment.Service/UnionPayProcessor/UnionPayProcessor.cs

@@ -273,5 +273,10 @@ namespace Fuel.Payment.Service.UnionPayProcessor
         {
             throw new NotImplementedException();
         }
+
+        protected override Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse order, ElectronicOrderModel electronicOrderModel)
+        {
+            throw new NotImplementedException();
+        }
     }
 }

+ 81 - 22
FuelCloud/src/Fuel.Payment.Service/WeChatPaymentProcessor/Wechat/WechatPaymentProcessor.cs

@@ -1,4 +1,6 @@
-using Fuel.Core.Models;
+using Aop.Api.Domain;
+using DFS.Core.Abstractions.View;
+using Fuel.Core.Models;
 using Fuel.Payment.Core;
 using Fuel.Payment.Core.Enum;
 using Fuel.Payment.Core.Models;
@@ -84,57 +86,84 @@ namespace Fuel.Payment.Service.WeChatPaymentProcessor.Wechat
 
         public override async Task<GenericProcessResponse> Query(ElectronicOrderModel order, int count, int interval)
         {
-            Log.Info("MicroPay", "Wechat OrderQuery is processing order: " + order.BillNumber);
-            var result = await MicroPay.RunQuery(ModelMapper.ConvertToWayneCloudModel(order), count, interval);
-
-            Log.Info("MicroPay", "Wechat OrderQuery process complete, result : \r\n" + result.ToXml());
+            order.TradeStatus = TradeStatus.PAYERROR;
+            try
+            {
+                Log.Info("MicroPay", "Wechat OrderQuery is processing order: " + order.BillNumber);
+                var result = await MicroPay.RunQuery(ModelMapper.ConvertToWayneCloudModel(order), count, interval);
 
-            return new GenericProcessResponse()
+                Log.Info("MicroPay", "Wechat OrderQuery process complete, result : \r\n" + result.ToXml());
+                order.TradeStatus = TradeStatus.SUCCESS;
+                return new GenericProcessResponse()
+                {
+                    WeChatResponse = result
+                };
+            }
+            catch (Exception e)
             {
-                WeChatResponse = result
-            };
+                return new GenericProcessResponse()
+                {
+                };
+            }
+          
         }
 
         public override async Task<GenericProcessResponse> Return(ElectronicOrderModel order)
         {
             Log.Info("MicroPay", "MicroPay is processing refund, BillNumber = " + order.BillNumber);
-
+            order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
+            order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
             TradeStatus tradeStatus;
             //var result = Refund.Run("", order.BillNumber, 
             //    order.TotalAmount.ToString(), order.NetAmount.ToString(), out tradeStatus);
             var result = await Refund.Run("", ModelMapper.ConvertToWayneCloudModel(order));
 
             Log.Info("MicroPay", "The final MicroPay response is: \r\n" + result.ToXml());
-            return new GenericProcessResponse()
+            var Generic = new GenericProcessResponse()
             {
                 WeChatResponse = result
             };
+            var ProcessResults = await ReturnResult(Generic, order);
+            Generic.ProcessResults = ProcessResults.ProcessResults;
+            return Generic;
         }
 
         public override async Task<GenericProcessResponse> UnifiedOrder(ElectronicOrderModel order)
         {
-            order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
-            order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
-            Log.Info("UnifiedOrder", "UnifiedOrder is processing order " + order.BillNumber);
-            var result = await MicroPay.UnifiedOrder(ModelMapper.ConvertToWayneCloudModel(order));
+            try
+            {
+                order.Config = Initialize(order).Result?.electronicOrderModel?.Config;
+                order.Certification = Initialize(order).Result?.electronicOrderModel?.Certification;
+                Log.Info("UnifiedOrder", "UnifiedOrder is processing order " + order.BillNumber);
+                var result = await MicroPay.UnifiedOrder(ModelMapper.ConvertToWayneCloudModel(order));
 
-            Log.Info("UnifiedOrder", "The final MicroPay UnifiedOrder is: \r\n" + result.ToXml());
-            var Generic = new GenericProcessResponse()
+                Log.Info("UnifiedOrder", "The final MicroPay UnifiedOrder is: \r\n" + result.ToXml());
+                var Generic = new GenericProcessResponse()
+                {
+                    WeChatResponse = result
+                };
+                var ProcessResults = await UnifiedOrderResult(Generic, order);
+                Generic.UnifiedOrderResult = ProcessResults;
+                return Generic;
+            }
+            catch (Exception ex)
             {
-                WeChatResponse = result
-            };
-            var ProcessResults = await UnifiedOrderResult(Generic, order);
-            Generic.UnifiedOrderResult = ProcessResults;
-            return Generic;
+                Log.Info("UnifiedOrder", "WechatPaymentProcessor :" + ex.Message);
+                return new GenericProcessResponse()
+                {
+
+                };
+            }
         }
 
         protected override async Task<GenericProcessResponse> Initialize(ElectronicOrderModel order)
         {
             string sourceFilePath = @"C:\cw\Code\smartfuel_lite\FuelCloud\src\Fuel.Payment.Server\File\Certificate\12345678-9abc-def0-1234-56789abcdef0\apiclient_cert.p12";
+            //string sourceFilePath = @"D:/fuelcloud/fabu/File/Certificate/12345678-9abc-def0-1234-56789abcdef0/apiclient_cert.p12";
             string config = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<WxPayConfig>  \r\n  <APPID>wxb198dafff060e651</APPID>  \r\n  <SUBAPPID></SUBAPPID>\r\n  <MINI_PROGRAM_APPID>wxb198dafff060e651</MINI_PROGRAM_APPID>\r\n  <MCHID>1617253894</MCHID>\r\n  <SUBMCHID></SUBMCHID>\r\n  <KEY>Kguangzhouhengshangongsi20250211</KEY>\r\n  <APPSECRET>2e6ee037b95c8fb90eb415bb559f8259</APPSECRET>\r\n  <SSLCERT>apiclient_cert.p12</SSLCERT>\r\n  <SSLCERT_PASSWORD>1617253894</SSLCERT_PASSWORD>\r\n  <NOTIFY_URL>http://paysdk.weixin.qq.com/example/ResultNotifyPage.aspx</NOTIFY_URL>\r\n  <IP>8.8.8.8</IP>\r\n  <PROXY_URL>http://10.152.18.220:8080</PROXY_URL>\r\n  <REPORT_LEVENL>1</REPORT_LEVENL>\r\n</WxPayConfig>";
             FileHandler fileHandler = new FileHandler();
             byte[] fileBytes = fileHandler.ReadFileToByteArray(sourceFilePath);
-            order.Certification = fileHandler.GetWxPayCertificationInfo(fileBytes, "1617253894");
+            order.Certification = fileHandler.GetWxPayCertificationInfo(fileBytes, "1617253894").Result.Certification;
             WayneCloud.Models.Models.WxPayConfig wxPayConfig = WayneCloud.Models.Models.WxPayConfig.DeserializeFromXmlString(config);
             order.Config = wxPayConfig;
             return new GenericProcessResponse()
@@ -180,6 +209,36 @@ namespace Fuel.Payment.Service.WeChatPaymentProcessor.Wechat
             return electronicOrderModel;
         }
 
+        protected override async Task<ElectronicOrderModel> ReturnResult(GenericProcessResponse processResponse, ElectronicOrderModel eOrder)
+        {
+            var returnCode = ReturnCode.PAY_ERROR;
+            var wechatResponse = processResponse.WeChatResponse;
+            if (eOrder.TradeStatus == TradeStatus.SUCCESS)
+            {
+                returnCode = ReturnCode.OK;
+            }
+            else
+            {
+                returnCode = ReturnCode.PAY_ERROR;
+
+                if (!eOrder.IsRefund)
+                {
+                    //cancelOrder = true;
+
+                }
+            }
+            List<ElectronicOrderProcessResultModel> electronicOrderProcessResultModels = new List<ElectronicOrderProcessResultModel>();
+            electronicOrderProcessResultModels.Add(new ElectronicOrderProcessResultModel()
+            {
+                BillNumber = eOrder.BillNumber,
+                ResultCode = ((int)returnCode).ToString(CultureInfo.InvariantCulture),
+                ResultMessage = returnCode.ToString(),
+                ErrorDetail = wechatResponse.IsSet("err_code") ? wechatResponse.GetValue("err_code").ToString() : "",
+                RawResult = wechatResponse.ToXml()
+            });
+            eOrder.ProcessResults = electronicOrderProcessResultModels;
+            return eOrder;
+        }
 
     }
 }

+ 2 - 2
FuelCloud/src/FuelServer.Core/Entity/configuration.cs

@@ -26,7 +26,7 @@ namespace FuelServer.Core.Entity
 		public Guid? Buid { get; set; }
 
 		/// <summary>
-		/// 支付方式类型
+		/// 支付方式类型  1:微信支付   2:银联支付   3:通联支付
 		/// </summary>
 		[JsonProperty]
 		public long payType { get; set; }
@@ -56,7 +56,7 @@ namespace FuelServer.Core.Entity
 		public string remark { get; set; }
 
 		/// <summary>
-		/// 模板类型
+		/// 模板类型 1:支付模板   2:消息通知模板  
 		/// </summary>
 		[JsonProperty]
 		public long Type { get; set; }

+ 3 - 3
FuelCloud/src/FuelServer.Core/Entity/nozzle.cs

@@ -54,9 +54,9 @@ namespace FuelServer.Core.Entity
 		public long PumpId { get; set; }
 
 		/// <summary>
-		/// 1:在线、2:离线、3:正在加油
-		/// </summary>
-		[JsonProperty]
+		/// 01:不可用  02:关闭   03:空闲   04:呼叫   05:授权   06:开始加油   07:挂起开始加油   08:加油中   09:挂起加油
+        /// </summary>
+        [JsonProperty]
 		public long Status { get; set; }
 
         [JsonProperty]

+ 48 - 11
FuelCloud/src/FuelServer.Core/Entity/transactions.cs

@@ -32,7 +32,7 @@ namespace FuelServer.Core.Entity
 		/// 用户ID
 		/// </summary>
 		[JsonProperty]
-		public long MiniProgramID { get; set; }
+		public long? MiniProgramID { get; set; }
 
 		/// <summary>
 		/// 枪号
@@ -110,7 +110,7 @@ namespace FuelServer.Core.Entity
 		/// 原升数
 		/// </summary>
 		[JsonProperty]
-		public decimal Qty { get; set; }
+		public decimal? Qty { get; set; }
         /// <summary>
         /// 实际加油升数
         /// </summary>
@@ -165,6 +165,38 @@ namespace FuelServer.Core.Entity
         /// </summary>
         [JsonProperty]
         public decimal? Price { get; set; }
+        /// <summary>
+        /// 订单编号
+        /// </summary>
+        [JsonProperty, Column(StringLength = 50, IsNullable = false)]
+        public string BillNumber { get; set; }
+        /// <summary>
+        /// 退款状态
+        /// </summary>
+        [JsonProperty]
+        public RefundStatus RefundStatus { get; set; }
+        /// <summary>
+        /// 泵码
+        /// </summary>
+        [JsonProperty]
+        public decimal? FuelItemPumpTotalizerVolume { get; set; }
+
+    }
+    public enum RefundStatus
+    {
+        /// <summary>
+        /// 无退款
+        /// </summary>
+        NotRefunded,
+        /// <summary>
+        /// 订单全额退款。
+        /// </summary>
+        FullyRefunded,
+
+        /// <summary>
+        /// 订单部分退款。
+        /// </summary>
+        PartiallyRefunded
     }
     public enum AuthorizationStatus
     {
@@ -179,9 +211,14 @@ namespace FuelServer.Core.Entity
         Authorized,
 
         /// <summary>
-        /// 等待授权
+        /// 等待授权 发起授权时,等待中的状态
+        /// </summary>
+        WaitAuthorization,
+
+        /// <summary>
+        /// 加油中
         /// </summary>
-        WaitAuthorization
+        FillingUp
     }
     public enum transactionsORDERSTATUS
     {
@@ -198,22 +235,22 @@ namespace FuelServer.Core.Entity
         /// <summary>
         /// 订单正在支付中。
         /// </summary>
-        //Paying,
+        Paying,
 
         /// <summary>
-        /// 订单全额退款
+        /// 订单通过卡支付
         /// </summary>
-        FullyRefunded,
+        CardPayment,
 
         /// <summary>
-        /// 订单部分退款。
+        /// 订单已完成
         /// </summary>
-        PartiallyRefunded,
+        Completed,
 
         /// <summary>
-        /// 订单通过卡支付。
+        /// 已取消
         /// </summary>
-        CardPayment
+        Cancelled
     }
 
     /// <summary>

+ 7 - 9
FuelCloud/src/FuelServer.Core/HttpRequestReader.cs

@@ -25,7 +25,10 @@ namespace Fuel.Core
             }
             var httpContext = _httpContextAccessor.HttpContext;
             var headerValue = httpContext.Request.Headers["CurrentBuId"].ToString();
-
+            if (string.IsNullOrEmpty(headerValue))
+            {
+                headerValue = httpContext.Request.Headers["currentbuid"].ToString();
+            }
             if (Guid.TryParse(headerValue, out Guid buId))
             {
                 return buId;
@@ -36,20 +39,15 @@ namespace Fuel.Core
         /// 小程序用户id
         /// </summary>
         /// <returns></returns>
-        public static Guid GetWachatID()
+        public static string GetWachatID()
         {
             if (_httpContextAccessor == null || _httpContextAccessor.HttpContext == null)
             {
-                return Guid.Empty;
+                return null;
             }
             var httpContext = _httpContextAccessor.HttpContext;
             var headerValue = httpContext.Request.Headers["WachatID"].ToString();
-
-            if (Guid.TryParse(headerValue, out Guid buId))
-            {
-                return buId;
-            }
-            return Guid.Empty;
+            return headerValue;
         }
         /// <summary>
         /// 获取请求头值

+ 3 - 2
FuelCloud/src/FuelServer.Core/Models/ServiceResponse.cs

@@ -19,13 +19,14 @@ namespace Fuel.Core.Models
             return StatusCode == HttpStatusCode.OK;
         }
         public ServiceResponse() { }
-        public ServiceResponse(HttpStatusCode statusCode, object data, string errorMsg = "")
+        public ServiceResponse(HttpStatusCode statusCode, object data, string errorMsg = "", bool success = true)
         {
             StatusCode = statusCode;
             Data = data;
             Message = errorMsg;
+            Success = success;
         }
-        public static ServiceResponse Ok(object data = null)
+        public static ServiceResponse Ok(object data = null,bool success = true)
         {
             return new ServiceResponse(HttpStatusCode.OK, data);
         }

+ 1 - 0
FuelCloud/src/FuelServer.Core/Nozzle/Dto/NozzleInfo.cs

@@ -13,5 +13,6 @@ namespace Fuel.Core.Nozzle.Dto
         public long Status { get; set; }
         public string ProductName { get; set; }
         public decimal? ProductPrice { get; set; }
+        public long ExternalGunNumber { get; set; }
     }
 }

+ 1 - 1
FuelCloud/src/FuelServer.Core/Nozzle/Dto/UploadNozzle.cs

@@ -86,7 +86,7 @@ namespace Fuel.Core.Nozzle.Dto
         /// <summary>
         /// 油枪ID
         /// </summary>
-        public string NozzleId { get; set; }
+        public long NozzleId { get; set; }
         /// <summary>
         /// 交易流水
         /// </summary>

+ 26 - 0
FuelCloud/src/FuelServer.Core/Transactions/Dto/RefundTrxRequest.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.Transactions.Dto
+{
+    public class RefundTrxRequest
+    {
+        public int trxId { get; set; }
+        public double longitude { get; set; }
+        public double latitude { get; set; }
+    }
+
+    public class WechatTemplateMessage
+    {
+        public int trxid { get; set; }
+        public string orderType { get; set; }
+    }
+    public class RedeemRequest
+    {
+        public int trxId { get; set; }
+        public decimal OriginalQty { get; set; }
+    }
+}

+ 26 - 0
FuelCloud/src/FuelServer.Core/Transactions/Dto/RequestModel.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.Transactions.Dto
+{
+    public class Filter
+    {
+        public string NozzleID { get; set; }
+        public string ProductName { get; set; }
+        public string siteName { get; set; }
+        public string PaymentMethod { get; set; }
+        public string username { get; set; }
+        public DateTime[]? TransactionTime { get; set; }
+    }
+
+    public class RequestModel
+    {
+        public int currentPage { get; set; }
+        public int pageSize { get; set; }
+        public Filter filter { get; set; }
+    }
+
+}

+ 11 - 4
FuelCloud/src/FuelServer.Core/Transactions/Dto/UploadTransactions.cs

@@ -15,7 +15,7 @@ namespace Fuel.Core.Transactions.Dto
         /// </summary>
         public int?  ExternalGunNumber { get; set; }
         /// <summary>
-        /// 实际加油金额
+        /// 金额
         /// </summary>
         public decimal? OriginalAmount { get; set; }
         /// <summary>
@@ -25,7 +25,7 @@ namespace Fuel.Core.Transactions.Dto
         /// <summary>
         /// 升数
         /// </summary>
-        public decimal Qty { get; set; }
+        public decimal? Qty { get; set; }
         /// <summary>
         /// 挂枪时间
         /// </summary>
@@ -41,7 +41,7 @@ namespace Fuel.Core.Transactions.Dto
         /// <summary>
         /// 用户id
         /// </summary>
-        public int? MiniProgramID { get; set; }
+        public long? MiniProgramID { get; set; }
         /// <summary>
         /// 订单流水号
         /// </summary>
@@ -54,6 +54,10 @@ namespace Fuel.Core.Transactions.Dto
         /// 单价
         /// </summary>
         public decimal? Price { get; set; }
+        /// <summary>
+        /// 泵码
+        /// </summary>
+        public decimal? FuelItemPumpTotalizerVolume { get; set; }
 
         public transactions ToTransactions(UploadTransactions upload, Guid Buid, product product, nozzle nozzle,int _OrderType)
         {
@@ -62,7 +66,7 @@ namespace Fuel.Core.Transactions.Dto
                 Buid = Buid,
                 NozzleId = nozzle.ExternalGunNumber,
                 ProductId = product.Id,
-                ActualPaymentAmount = upload.ActualPaymentAmount,
+                ActualPaymentAmount = upload.OriginalAmount,
                 FuelItemTransactionEndTime = upload.FuelItemTransactionEndTime,
                 OrderStatus = transactionsORDERSTATUS.Unpaid,
                OrderType = ToTransactionsOrderType(_OrderType),
@@ -74,6 +78,9 @@ namespace Fuel.Core.Transactions.Dto
                 TransactionTime = DateTime.Now,
                 Price = upload.Price,
                 CreateTime = DateTime.Now,
+                OriginalQty = _OrderType == 1 ?0.00M: upload.Qty,
+                FuelItemPumpTotalizerVolume = upload.FuelItemPumpTotalizerVolume,
+                MiniProgramID = upload.MiniProgramID
             };
         }
         public static transactionsORDERTYPE ToTransactionsOrderType(int value)

+ 50 - 0
FuelCloud/src/FuelServer.Core/Transactions/TransactionsList.cs

@@ -0,0 +1,50 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.Transactions
+{
+    public class TransactionsList
+    {
+        /// <summary>
+        /// 订单流水号
+        /// </summary>
+        public string TransactionNumber { get; set; }
+        /// <summary>
+        /// 站点
+        /// </summary>
+        public string SiteName { get; set; }
+        /// <summary>
+        /// 油机号
+        /// </summary>
+        public string FuelId { get; set; }
+        /// <summary>
+        /// 油枪|油品
+        /// </summary>
+        public string NozzleProductName { get; set; }
+        /// <summary>
+        /// 单价升数
+        /// </summary>
+        public string PriceQty { get; set; }
+        /// <summary>
+        /// 金额
+        /// </summary>
+        public string ActualPaymentAmount { get; set; }
+        /// <summary>
+        /// 加油时间
+        /// </summary>
+        public string TransactionTime { get; set; }
+        /// <summary>
+        /// 支付状态
+        /// </summary>
+        public string OrderStatus { get; set; }
+        /// <summary>
+        /// 支付方式
+        /// </summary>
+        public string PaymentMethod { get; set; }
+        public string UserName { get; set; }
+    }
+}

+ 2 - 2
FuelCloud/src/FuelServer.Core/User/LoginModel.cs

@@ -8,7 +8,7 @@ namespace Fuel.Core.User
 {
     public class LoginModel
     {
-        public string Username { get; set; }
-        public string Password { get; set; }
+        public string userName { get; set; }
+        public string password { get; set; }
     }
 }

+ 155 - 0
FuelCloud/src/FuelServer.Core/WechatServer/WeChatService.cs

@@ -0,0 +1,155 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Fuel.Core.WechatServer
+{
+
+    public class WeChatService
+    {
+        private readonly string _appId;
+        private readonly string _appSecret;
+        private string _accessToken;
+        public WeChatService(string appId, string appSecret)
+        {
+            _appId = appId;
+            _appSecret = appSecret;
+        }
+        public WeChatService()
+        {
+        }
+        // 获取AccessToken
+        public string GetAccessTokenAsync()
+        {
+            using (var httpClient = new HttpClient())
+            {
+                var url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={_appId}&secret={_appSecret}";
+                try
+                {
+                    var response = httpClient.GetStringAsync(url).GetAwaiter().GetResult();
+                    var tokenJson = JsonConvert.DeserializeObject<TokenResponse>(response);
+                    _accessToken = tokenJson.AccessToken;
+                    return _accessToken;
+                }
+                catch (Exception ex)
+                {
+                    Console.WriteLine($"Error getting access token: {ex.Message}");
+                    throw;
+                }
+            }
+        }
+
+        // 发送模板消息
+
+        public async void SendTemplateMessage(TemplateMessage message)
+        {
+            //if (string.IsNullOrEmpty(_accessToken))
+            //{
+            //    _accessToken = GetAccessTokenAsync();
+            //}
+            _accessToken = await AccessTokenManager.GetAccessTokenAsync(_appId, _appSecret);
+
+            using (var httpClient = new HttpClient())
+            {
+                var url = $"https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={_accessToken}";
+                var content = new StringContent(JsonConvert.SerializeObject(message), Encoding.UTF8, "application/json");
+
+                var response = httpClient.PostAsync(url, content).GetAwaiter().GetResult();
+                var responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
+            }
+        }
+        /// <summary>
+        /// 解密,用于手机号解密
+        /// </summary>
+        /// <param name="encryptedData"></param>
+        /// <param name="iv"></param>
+        /// <param name="sessionKey"></param>
+        /// <returns></returns>
+        public static string Decrypt(string encryptedData, string iv, string sessionKey)
+        {
+            var encryptedBytes = Convert.FromBase64String(encryptedData);
+            var ivBytes = Convert.FromBase64String(iv);
+            var sessionKeyBytes = Convert.FromBase64String(sessionKey);
+
+            using (var aesAlg = Aes.Create())
+            {
+                aesAlg.Key = sessionKeyBytes;
+                aesAlg.IV = ivBytes;
+
+                var decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
+
+                using (var msDecrypt = new MemoryStream(encryptedBytes))
+                {
+                    using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
+                    {
+                        using (var srDecrypt = new StreamReader(csDecrypt))
+                        {
+                            return srDecrypt.ReadToEnd();
+                        }
+                    }
+                }
+            }
+        }
+
+        public async Task<string> GetPaidUnionid(string openid)
+        {
+            //if (string.IsNullOrEmpty(_accessToken))
+            //{
+            //    _accessToken = GetAccessTokenAsync();
+            //}
+            _accessToken = await AccessTokenManager.GetAccessTokenAsync(_appId, _appSecret);
+
+            using (var httpClient = new HttpClient())
+            {
+                var url = $"https://api.weixin.qq.com/wxa/getpaidunionid?access_token={_accessToken}&openid={openid}";
+                //https://api.weixin.qq.com/wxa/getpaidunionid?access_token=ACCESS_TOKEN&openid=OPENID
+                var response = httpClient.GetStringAsync(url).GetAwaiter().GetResult();
+                return response;
+            }
+        }
+
+        // Token响应类
+        public class TokenResponse
+        {
+            [JsonProperty("access_token")]
+            public string AccessToken { get; set; }
+
+            [JsonProperty("expires_in")]
+            public int ExpiresIn { get; set; }
+        }
+
+        // 模板消息类
+        public class TemplateMessage
+        {
+            [JsonProperty("touser")]
+            public string ToUser { get; set; }
+
+            [JsonProperty("template_id")]
+            public string TemplateId { get; set; }
+
+            [JsonProperty("page")]
+            public string Page { get; set; }
+
+            [JsonProperty("form_id")]
+            public string FormId { get; set; }
+
+            [JsonProperty("data")]
+            public object Data { get; set; }
+
+            [JsonProperty("emphasis_keyword")]
+            public string EmphasisKeyword { get; set; }
+        }
+        public class TemplateConfig
+        {
+            [JsonProperty("TemplateId")]
+            public string TemplateId { get; set; }
+
+            [JsonProperty("data")]
+            public Dictionary<string, string> DataMappings { get; set; } // Key: 配置中的键名,Value: 微信字段名
+        }
+    }
+}

+ 3 - 0
FuelCloud/src/FuelServer.Core/WechatServer/WechatConstants.cs

@@ -14,5 +14,8 @@ namespace Fuel.Core.WechatServer
         public const string token =
          "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}";
 
+        public const string sendmessage =
+       "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token={0} ";
+
     }
 }

+ 16 - 0
FuelCloud/src/FuelServer.Core/WechatServer/WechatUserSessionResponse.cs

@@ -20,5 +20,21 @@ namespace Fuel.Core.WechatServer
         public string UserAvatarUrl { get; set; }
         public string UserName { get; set; }
         public string UserPhoneNumber { get; set; }
+        public string encryptedData { get; set; }
+        public string iv { get; set; }
+    }
+    public class AddSite
+    {
+        public string PayType { get; set; } // 支付类型
+        public string Name { get; set; } //站点名称
+        public string Phone { get; set; } // 手机号
+        public string AppId { get; set; } // 应用ID
+        public string PaymentMode { get; set; } // 支付模式
+        public string MessageTemplate { get; set; } // 小程序通知模板
+        public string MessageTemplateConfiguration { get; set; } // 消息模板配置
+        public string PayTypeConfiguration { get; set; } // 支付类型配置
+        public string Secret { get; set; } // 密钥
+        public string GpsCoordinates { get; set; } // GPS坐标
+        public string Address { get; set; } // 地址
     }
 }