Selaa lähdekoodia

feat:请求云端签名验证,发送订单,发送油枪数据

Zhenghanjv 5 kuukautta sitten
vanhempi
commit
c932eeef8c
26 muutettua tiedostoa jossa 656 lisäystä ja 103 poistoa
  1. 12 12
      Edge.Core/Core/database/QueryableExtensions.cs
  2. 2 0
      Edge.Core/Domain/FccNozzleInfo/Output/DetailsNozzleInfoOutput.cs
  3. 2 2
      Edge.Core/Domain/FccOrderInfo/FccOrderInfo.cs
  4. 1 1
      Edge.Core/Domain/FccOrderInfo/Output/OrderInfoOutput.cs
  5. 10 0
      Edge.Core/Domain/FccStationInfo/FccStationInfo.cs
  6. 22 10
      Edge.Core/Domain/FccStationInfo/Input/StationInfoInput.cs
  7. 12 0
      Edge.Core/Domain/FccStationInfo/Output/StationInfoOutput.cs
  8. 31 0
      Edge.Core/Domain/FccTankInfo/Output/DetailsTankInfoOutput.cs
  9. 2 0
      Edge.Core/Edge.Core.csproj
  10. 109 0
      Edge.Core/HttpClient/HttpClientService.cs
  11. 15 0
      Edge.Core/HttpClient/IHttpClient.cs
  12. 62 19
      HengshanPaymentTerminal/HengshanPayTermHandler.cs
  13. 45 0
      HengshanPaymentTerminal/Http/HttpClientUtils.cs
  14. 25 0
      HengshanPaymentTerminal/Http/IHttpClientUtil.cs
  15. 135 0
      HengshanPaymentTerminal/Http/Request/HttpRequest.cs
  16. 26 0
      HengshanPaymentTerminal/Http/Response/Response.cs
  17. 29 3
      HengshanPaymentTerminal/MessageEntity/CommonMessage.cs
  18. 10 40
      HengshanPaymentTerminal/MessageEntity/Incoming/OrderFromMachine.cs
  19. 6 6
      HengshanPaymentTerminal/MessageTemplateLookup.cs
  20. 8 0
      src/FccLife.Web/Program.cs
  21. 1 1
      src/FccLife.Web/Repositories/FccNozzleInfo/INozzleInfoReposity.cs
  22. 4 3
      src/FccLife.Web/Repositories/FccNozzleInfo/NozzleInfoReposity.cs
  23. 2 0
      src/FccLife.Web/Repositories/FccStationInfo/StationRepository.cs
  24. 7 0
      src/FccLife.Web/Repositories/FccTankInfo/ITankReposity.cs
  25. 18 0
      src/FccLife.Web/Repositories/FccTankInfo/TankReposity.cs
  26. 60 6
      src/FccLife.Web/Services/FccNozzleInfo/NozzleInfoServiceImpl.cs

+ 12 - 12
Edge.Core/Core/database/QueryableExtensions.cs

@@ -4,17 +4,17 @@ namespace Edge.Core.Core.database
 {
     public static class QueryableExtensions
     {
-        /// <summary>  
-        /// 根据条件动态地应用 WHERE 子句。  
-        /// </summary>  
-        /// <typeparam name="T">实体类型。</typeparam>  
-        /// <param name="query">原始的 IQueryable 查询。</param>  
-        /// <param name="condition">是否应用 WHERE 子句的条件。</param>  
-        /// <param name="predicate">要应用的 WHERE 子句的条件表达式。</param>  
-        /// <returns>根据条件返回应用了 WHERE 子句或未应用的 IQueryable 查询。</returns>  
-        public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
-        {
-            return condition ? query.Where(predicate) : query;
-        }
+        ///// <summary>  
+        ///// 根据条件动态地应用 WHERE 子句。  
+        ///// </summary>  
+        ///// <typeparam name="T">实体类型。</typeparam>  
+        ///// <param name="query">原始的 IQueryable 查询。</param>  
+        ///// <param name="condition">是否应用 WHERE 子句的条件。</param>  
+        ///// <param name="predicate">要应用的 WHERE 子句的条件表达式。</param>  
+        ///// <returns>根据条件返回应用了 WHERE 子句或未应用的 IQueryable 查询。</returns>  
+        //public static IQueryable<T> WhereIf<T>(this IQueryable<T> query, bool condition, Expression<Func<T, bool>> predicate)
+        //{
+        //    return condition ? query.Where(predicate) : query;
+        //}
     }
 }

+ 2 - 0
Edge.Core/Domain/FccNozzleInfo/Output/DetailsNozzleInfoOutput.cs

@@ -67,4 +67,6 @@
             public int TankNum { get; set; }
         }
     }
+
+    
 }

+ 2 - 2
Edge.Core/Domain/FccOrderInfo/FccOrderInfo.cs

@@ -26,7 +26,7 @@ namespace Edge.Core.Domain.FccOrderInfo
         /// <summary>
         /// 授权时间
         /// </summary>
-        public DateTime? AuthorizationTime { get; set; }
+        public DateTime AuthorizationTime { get; set; }
 
         /// <summary>
         /// 挂枪时间
@@ -76,7 +76,7 @@ namespace Edge.Core.Domain.FccOrderInfo
         /// <summary>
         /// 实际支付金额
         /// </summary>
-        public decimal AmountPayable { get; set; }
+        public decimal? AmountPayable { get; set; }
 
         /// <summary>
         /// 是否已上传云端—— 0:未上传;1:已上传;2:不需要上传

+ 1 - 1
Edge.Core/Domain/FccOrderInfo/Output/OrderInfoOutput.cs

@@ -16,7 +16,7 @@ namespace Edge.Core.Domain.FccOrderInfo.Output
         /// <summary>
         /// 授权时间
         /// </summary>
-        public DateTime? AuthorizationTime { get; set; }
+        public DateTime AuthorizationTime { get; set; }
 
         /// <summary>
         /// 挂枪时间

+ 10 - 0
Edge.Core/Domain/FccStationInfo/FccStationInfo.cs

@@ -19,6 +19,16 @@ namespace Edge.Core.Domain.FccStationInfo
         /// </summary>
         public string BuildId { get; set; }
 
+        /// <summary>
+        /// 客户端id
+        /// </summary>
+        public string SecretId { get; set; }
+
+        /// <summary>
+        /// 与云端加密的 key
+        /// </summary>
+        public string AcessKey { get; set; }
+
         /// <summary>
         /// 站点名称
         /// </summary>

+ 22 - 10
Edge.Core/Domain/FccStationInfo/Input/StationInfoInput.cs

@@ -19,6 +19,16 @@ namespace Edge.Core.Domain.FccStationInfo.Input
         /// </summary>
         public string? Name { get; set; }
 
+        /// <summary>
+        /// 客户端id
+        /// </summary>
+        public string SecretId { get; set; }
+
+        /// <summary>
+        /// 与云端加密的 key
+        /// </summary>
+        public string AcessKey { get; set; }
+
         /// <summary>
         /// 经度
         /// </summary>
@@ -65,16 +75,18 @@ namespace Edge.Core.Domain.FccStationInfo.Input
 
             return new FccStationInfo()
             {
-                BuildId = BuildId,
-                Name = Name != null ? Name : "",
-                Longitude = (decimal)(Longitude != null ? Longitude : new decimal(0)),
-                Latitude = (decimal)(Latitude != null ? Latitude : new decimal(0)),
-                SmallProgram = SmallProgram,
-                CloudService = CloudService,
-                MqttService = MqttService,
-                IcardService = IcardService != null ? IcardService : "",
-                ServicePort = ServicePort,
-                WebSocketPort = WebSocketPort
+                BuildId = this.BuildId,
+                Name = this.Name != null ? this.Name : "",
+                SecretId = this.SecretId,
+                AcessKey = this.AcessKey,
+                Longitude = (decimal)(this.Longitude != null ? this.Longitude : new decimal(0)),
+                Latitude = (decimal)(this.Latitude != null ? this.Latitude : new decimal(0)),
+                SmallProgram = this.SmallProgram,
+                CloudService = this.CloudService,
+                MqttService = this.MqttService,
+                IcardService = this.IcardService != null ? this.IcardService : "",
+                ServicePort = this.ServicePort,
+                WebSocketPort = this.WebSocketPort
             };
         }
 

+ 12 - 0
Edge.Core/Domain/FccStationInfo/Output/StationInfoOutput.cs

@@ -26,6 +26,8 @@ namespace Edge.Core.Domain.FccStationInfo.Output
         {
             this.Id = fccStationInfo.Id;
             this.BuildId = fccStationInfo.BuildId;
+            this.SecretId = fccStationInfo.SecretId;
+            this.AcessKey = fccStationInfo.AcessKey;
             this.Name = fccStationInfo.Name;
             this.Longitude = fccStationInfo.Longitude;
             this.Latitude = fccStationInfo.Latitude;
@@ -46,6 +48,16 @@ namespace Edge.Core.Domain.FccStationInfo.Output
         /// </summary>
         public string BuildId { get; set; }
 
+        /// <summary>
+        /// 客户端id
+        /// </summary>
+        public string SecretId { get; set; }
+
+        /// <summary>
+        /// 与云端加密的 key
+        /// </summary>
+        public string AcessKey { get; set; }
+
         /// <summary>
         /// 站点名称
         /// </summary>

+ 31 - 0
Edge.Core/Domain/FccTankInfo/Output/DetailsTankInfoOutput.cs

@@ -45,4 +45,35 @@
             public string OilName { get; set; }
         }
     }
+
+    /// <summary>
+    /// 发送给云端的油罐信息
+    /// </summary>
+    public class DetailTankInfoForCloud
+    {
+        /// <summary>
+        /// 油罐号
+        /// </summary>
+        public int TankNumber { get; set; }
+
+        /// <summary>
+        /// 油罐容量
+        /// </summary>
+        public decimal TankCapacity { get; set; }
+
+        /// <summary>
+        /// 油品名
+        /// </summary>
+        public string ProductName { get; set; }
+
+        /// <summary>
+        /// 油品吗
+        /// </summary>
+        public int ProductCode { get; set; }
+
+        /// <summary>
+        /// 油品单价
+        /// </summary>
+        public decimal ProductPrice { get; set; }
+    }
 }

+ 2 - 0
Edge.Core/Edge.Core.csproj

@@ -14,6 +14,7 @@
   <ItemGroup>
     <PackageReference Include="AutoMapper" Version="13.0.1" />
     <PackageReference Include="Castle.Core" Version="5.1.1" />
+    <PackageReference Include="DFS.Infrastructure" Version="6.2.1" />
     <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="2.2.0" />
     <PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.7" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
@@ -25,6 +26,7 @@
     <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Xml" Version="8.0.1" />
+    <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.1" />
     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.2" />
     <PackageReference Include="MQTTnet" Version="4.3.7.1207" />
     <PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.3.7.1207" />

+ 109 - 0
Edge.Core/HttpClient/HttpClientService.cs

@@ -0,0 +1,109 @@
+using DFS.Infrastructure.Extension.SM;
+using Edge.Core.Core.database;
+using Microsoft.Extensions.DependencyInjection;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Threading.Tasks;
+
+namespace Edge.Core.HttpClient
+{
+    public class HttpClientService:IHttpClient
+    {
+        private static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
+        private readonly string signMethod = "HMAC_SM4";
+        private string acesskey = "";
+        private string secretId = "";
+        private string baseUrl = "";
+        private readonly MysqlDbContext mysqlDbContext = new MysqlDbContext();
+
+        private IHttpClientFactory _httpContextFactory;
+
+        [ActivatorUtilitiesConstructor]
+        public HttpClientService(IHttpClientFactory httpClientFactory) 
+        {
+            _httpContextFactory = httpClientFactory;
+            getHttpInfo();
+        }
+
+        private void getHttpInfo()
+        {
+            var fccStationInfo = mysqlDbContext.FccStationInfos.FirstOrDefault();
+            if(fccStationInfo ==  null)
+            {
+                Logger.Info($"http client get station info fail");
+                return;
+            }
+            secretId = fccStationInfo?.SecretId;
+            acesskey = fccStationInfo?.AcessKey;
+            baseUrl = fccStationInfo?.CloudService;
+        }
+
+        public async Task<HttpResponseMessage> GetAsync(string api, Dictionary<string,string> parmas)
+        {
+            string nonceStr = GenerateUniqueString();
+            string timeStampStr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
+            var httpClient = _httpContextFactory.CreateClient();
+            httpClient.BaseAddress = new Uri(baseUrl);
+            httpClient.DefaultRequestHeaders.Add("sign_method", signMethod);
+            httpClient.DefaultRequestHeaders.Add("secret_id", secretId);
+            httpClient.DefaultRequestHeaders.Add("nonce", nonceStr);
+            httpClient.DefaultRequestHeaders.Add("timestamp", timeStampStr);
+            httpClient.DefaultRequestHeaders.Add("signature", SignStr(nonceStr,timeStampStr,null,parmas));
+
+            return await httpClient.GetAsync(api);
+        }
+
+        public async Task<HttpResponseMessage> PostAsync(string api, StringContent? parmaJson)
+        {
+            string nonceStr = GenerateUniqueString();
+            string timeStampStr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
+
+            string? json = null;
+            if (parmaJson != null)
+            {
+                json = await parmaJson.ReadAsStringAsync();
+            }
+            var httpClient = _httpContextFactory.CreateClient();
+            httpClient.BaseAddress = new Uri(baseUrl);
+            httpClient.DefaultRequestHeaders.Add("sign_method", signMethod);
+            httpClient.DefaultRequestHeaders.Add("secret_id", secretId);
+            httpClient.DefaultRequestHeaders.Add("nonce", nonceStr);
+            httpClient.DefaultRequestHeaders.Add("timestamp", timeStampStr);
+            httpClient.DefaultRequestHeaders.Add("signature", SignStr(nonceStr, timeStampStr, json,null));
+
+            return await httpClient.PostAsync(api, parmaJson);
+        }
+
+        private string GenerateUniqueString()
+        {
+            // 生成 GUID 并去掉 "-"
+            string guid = Guid.NewGuid().ToString("N");
+            // 截取前 7 位
+            return guid.Substring(0, 7);
+        }
+
+        private string SignStr(string nonce,string timestamp, string? parmaJson,Dictionary<string,string>? parmas)
+        {
+            string sign = $"sign_method={signMethod}&secret_id={secretId}&nonce={nonce}&timestamp={timestamp}";
+            if(parmaJson != null)
+            {
+                sign += $"&{parmaJson}";
+            }
+            if (parmas != null)
+            {
+                foreach (var item in parmas)
+                {
+                    sign += $"&{item.Key}={item.Value}";
+                }
+            }
+            
+            string encrySign = sign.SM4Encrypt_ECB(acesskey);
+            byte[] encrySignBytes = Encoding.UTF8.GetBytes(encrySign);
+            string encryBase64 = Convert.ToBase64String(encrySignBytes);
+            return encryBase64;
+        }
+    }
+}

+ 15 - 0
Edge.Core/HttpClient/IHttpClient.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Edge.Core.HttpClient
+{
+    public interface IHttpClient
+    {
+        Task<HttpResponseMessage> PostAsync(string api, StringContent? parmaJson);
+
+        Task<HttpResponseMessage> GetAsync(string api, Dictionary<string,string> parmas);
+    }
+}

+ 62 - 19
HengshanPaymentTerminal/HengshanPayTermHandler.cs

@@ -23,6 +23,11 @@ using Microsoft.EntityFrameworkCore;
 using Microsoft.VisualStudio.TestPlatform.CommunicationUtilities;
 using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
 using HengshanPaymentTerminal.Mqtt.Request;
+using HengshanPaymentTerminal.Http;
+using HengshanPaymentTerminal.Http.Request;
+using System.Text.Json;
+using Newtonsoft.Json;
+using HengshanPaymentTerminal.Http.Response;
 
 namespace HengshanPaymentTerminal
 {
@@ -78,6 +83,8 @@ namespace HengshanPaymentTerminal
 
         private byte frame = 0x00;
         private object lockFrame = new object();
+
+        private readonly IHttpClientUtil httpClientUtil;
         #endregion
 
         #region Logger
@@ -118,6 +125,7 @@ namespace HengshanPaymentTerminal
                   string.Join(";", config.PumpNozzleLogicIds.Select(m => $"{m.PumpId}={m.LogicIds}")),
                   string.Join(";", config.PumpSiteNozzleNos.Select(m => $"{m.PumpId}={m.SiteNozzleNos}")),
                   string.Join(";", config.NozzleLogicIds.Select(m => $"{m.NozzleNo}={m.LogicId}")))
+                  //clientUtil)
         {
 
         }
@@ -128,6 +136,7 @@ namespace HengshanPaymentTerminal
             string pumpNozzles,
             string pumpSiteNozzleNos,
             string nozzleLogicIds)
+            //IHttpClientUtil clientUtil)
         {
             this.pumpIds = pumpIds;
             this.pumpSubAddresses = pumpSubAddresses;
@@ -135,6 +144,7 @@ namespace HengshanPaymentTerminal
             this.pumpSiteNozzleNos = pumpSiteNozzleNos;
             this.nozzleLogicIds = nozzleLogicIds;
             this.MysqlDbContext = new MysqlDbContext();
+            this.httpClientUtil = new HttpClientUtils();
 
             GetInfo();
             AssociatedPumpIds = GetPumpIdList(pumpIds);
@@ -431,8 +441,9 @@ namespace HengshanPaymentTerminal
                     {
                         //添加或修改数据库订单
                         OrderFromMachine orderFromMachine = (OrderFromMachine)context.Incoming.Message;
-                        int row = UpLoadOrder(orderFromMachine);
-                        logger.Info($"receive order from machine,database had ${row} count change");
+                        FccOrderInfo fccOrderInfo = UpLoadOrder(orderFromMachine);
+                        logger.Info($"receive order from machine,database had change");
+                        CreateTransaction(fccOrderInfo);
                         break;
                     }
                 //普通应答
@@ -720,7 +731,7 @@ namespace HengshanPaymentTerminal
             byte[] commandAndNozzle = { 0x19, (byte)orderInfo.NozzleNum };
             byte[] ttcBytes = NumberToByteArrayWithPadding(orderInfo.Ttc, 4);
 
-            byte[] amountPayableBytes = FormatDecimal(orderInfo.AmountPayable);
+            byte[] amountPayableBytes = FormatDecimal(orderInfo.AmountPayable ?? orderInfo.Amount);
             list.AddRange(commandAndNozzle);    //添加命令字和枪号
             list.AddRange(ttcBytes);            //添加流水号
             list.Add(0x21);                     //由fcc推送实付金额表示该订单是二维码小程序支付的
@@ -824,28 +835,60 @@ namespace HengshanPaymentTerminal
         /// </summary>
         /// <param name="order">接收到油机的订单信息</param>
         /// <returns></returns>
-        public int UpLoadOrder(CommonMessage order)
+        public FccOrderInfo UpLoadOrder(OrderFromMachine order)
         {
             //接收到油机发送过来的订单信息
-            if(order is OrderFromMachine)
+            OrderFromMachine orderFromMachine = (OrderFromMachine)order;
+            FccOrderInfo orderByMessage = orderFromMachine.ToComponent();
+
+            /** 根据枪号+流水号+授权时间来确定订单,因为冷启动后流水号会从头开始计算
+             * 后支付时直接将数据库直接插入
+             * 预支付时由于是云端先创建订单,发起授权响应成功后会插入数据库,响应成功时会回复授权时间,枪号,流水号
+             */
+            FccOrderInfo? fccOrderInfo = MysqlDbContext.fccOrderInfos
+                .Where(order =>
+                    order.NozzleNum == orderFromMachine.nozzleNum && order.Ttc == orderFromMachine.ttc
+                    && order.AuthorizationTime == orderFromMachine.dispenserTime)
+                .FirstOrDefault();
+            if (fccOrderInfo == null)
             {
-                OrderFromMachine orderFromMachine = (OrderFromMachine)order;
-                FccOrderInfo orderByMessage = orderFromMachine.ToComponent();
-                FccOrderInfo? fccOrderInfo = MysqlDbContext.fccOrderInfos.FirstOrDefault(fccOrder =>
-                    fccOrder.NozzleNum == orderFromMachine.nozzleNum && fccOrder.Ttc == orderFromMachine.ttc);
-                if (fccOrderInfo == null)
-                {
-                    logger.Info($"receive order from machine,find order from database is null");
-                    MysqlDbContext.fccOrderInfos.Add(orderByMessage);
-                }
-                else
+                logger.Info($"receive order from machine,find order from database is null");
+                MysqlDbContext.fccOrderInfos.Add(orderByMessage);
+                MysqlDbContext.SaveChanges();
+                return orderByMessage;
+            }
+            else
+            {
+                logger.Info($"receive order from machine,padding data right now");
+                orderFromMachine.PaddingAuthorizationOrderData(fccOrderInfo);
+                MysqlDbContext.SaveChanges();
+                return fccOrderInfo;
+            }
+            
+        }
+
+        private async void CreateTransaction(FccOrderInfo fccOrderInfo)
+        {
+
+            CreateTransaction createTransaction = new CreateTransaction(fccOrderInfo,stationInfo.SecretId);
+            logger.Info($"create transaction,type is {createTransaction.type}");
+            HttpResponseMessage httpResponseMessage = await httpClientUtil.CreateTransaction(JsonConvert.SerializeObject(createTransaction));
+            Response<long>? response = JsonConvert.DeserializeObject<Response<long>>(await httpResponseMessage.Content.ReadAsStringAsync());
+            logger.Info($"reveice create transaction response:{JsonConvert.SerializeObject(response)}");
+            // 后支付填充云端id
+            if(response != null && createTransaction.type == 2)
+            {
+                FccOrderInfo? currentOrder = MysqlDbContext.fccOrderInfos
+                .Where(order =>
+                    order.NozzleNum == fccOrderInfo.NozzleNum && order.Ttc == fccOrderInfo.Ttc
+                    && order.AuthorizationTime == fccOrderInfo.AuthorizationTime)
+                .FirstOrDefault();
+                if(currentOrder != null)
                 {
-                    logger.Info($"receive order from machine,padding data right now");
-                    orderFromMachine.PaddingAuthorizationOrderData(fccOrderInfo);
+                    currentOrder.CloundOrderId = response.data;
+                    MysqlDbContext.SaveChanges();
                 }
             }
-
-            return MysqlDbContext.SaveChanges();
         }
 
         /// <summary>

+ 45 - 0
HengshanPaymentTerminal/Http/HttpClientUtils.cs

@@ -0,0 +1,45 @@
+using Edge.Core.HttpClient;
+using HengshanPaymentTerminal.Http.Request;
+using Microsoft.Extensions.DependencyInjection;
+using Org.BouncyCastle.Asn1.Ocsp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.Http
+{
+    public class HttpClientUtils:IHttpClientUtil
+    {
+        private IHttpClient _httpClientService;
+
+        [ActivatorUtilitiesConstructor]
+        public HttpClientUtils(IHttpClient httpClientService)
+        {
+            _httpClientService = httpClientService;
+        }
+
+        public HttpClientUtils()
+        {
+            ServiceCollection serviceCollection = new ServiceCollection();
+            serviceCollection.AddHttpClient();
+            ServiceProvider serviceProvider = serviceCollection.BuildServiceProvider();
+            IHttpClientFactory httpClientFactory = serviceProvider.GetService<IHttpClientFactory>();
+            _httpClientService = new HttpClientService(httpClientFactory);
+        }
+
+        public async Task<HttpResponseMessage> CreateTransaction(string requestJson)
+        {
+            var requesStr = new StringContent(requestJson, Encoding.UTF8, "application/json");
+            return await _httpClientService.PostAsync("api/transactions/CreateTransaction", requesStr);
+        }
+
+        public async Task<HttpResponseMessage> SendNozzleInfo(string requestJson)
+        {
+            var requesStr = new StringContent(requestJson, Encoding.UTF8, "application/json");
+            return await _httpClientService.PostAsync("api/nozzle/uploadNozzle", requesStr);
+        }
+    }
+}

+ 25 - 0
HengshanPaymentTerminal/Http/IHttpClientUtil.cs

@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.Http
+{
+    public interface IHttpClientUtil
+    {
+        /// <summary>
+        /// 发送油枪信息给云端
+        /// </summary>
+        /// <param name="requestJson"></param>
+        /// <returns></returns>
+        Task<HttpResponseMessage> SendNozzleInfo(string requestJson);// { return null; }
+
+        /// <summary>
+        /// 创建订单
+        /// </summary>
+        /// <param name="requestJson"></param>
+        /// <returns></returns>
+        Task<HttpResponseMessage> CreateTransaction(string requestJson); //{ return null; }
+    }
+}

+ 135 - 0
HengshanPaymentTerminal/Http/Request/HttpRequest.cs

@@ -0,0 +1,135 @@
+using Edge.Core.Domain.FccOrderInfo;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.Http.Request
+{
+    public class HttpRequest
+    {
+    }
+
+    /// <summary>
+    /// 发送油枪信息到云端数据对象
+    /// </summary>
+    public class SendNozzleInfo : HttpRequest
+    {
+        /// <summary>
+        /// 加油点
+        /// </summary>
+        public int PumpId { get; set; }
+
+        /// <summary>
+        /// 内部枪号
+        /// </summary>
+        public int InternalGunNumber { get; set; }
+
+        /// <summary>
+        /// 外部枪号
+        /// </summary>
+        public int ExternalGunNumber { get; set; }
+
+        /// <summary>
+        /// 油罐号
+        /// </summary>
+        public int TankNumber { get; set; }
+
+        /// <summary>
+        /// 油罐容量
+        /// </summary>
+        public decimal TankCapacity { get; set; }
+
+        /// <summary>
+        /// 油品名
+        /// </summary>
+        public string ProductName { get; set; }
+
+        /// <summary>
+        /// 油品吗
+        /// </summary>
+        public int ProductCode { get; set; }
+
+        /// <summary>
+        /// 油品单价
+        /// </summary>
+        public decimal ProductPrice { get; set; }
+
+        /// <summary>
+        /// 1:创建;2:修改;3:删除
+        /// </summary>
+        public int type { get; set; }
+    }
+
+    /// <summary>
+    /// fcc 发送订单给云端数据对象
+    /// </summary>
+    public class CreateTransaction : HttpRequest
+    {
+        public CreateTransaction(FccOrderInfo fccOrderInfo,string auserID) 
+        {
+            this.NozzleId = fccOrderInfo.NozzleNum;
+            this.OriginalAmount = fccOrderInfo.Amount;
+            this.ActualPaymentAmount = fccOrderInfo.AmountPayable;
+            this.Qty = fccOrderInfo.Volume;
+            this.FuelItemTransactionEndTime = fccOrderInfo.EndTime ?? DateTime.Now;
+            this.TransactionTime = fccOrderInfo.PaymentTime;
+            this.Product = fccOrderInfo.OilName;
+            if(fccOrderInfo.CloundOrderId == null)
+            {
+                this.type = 2;
+            } else
+            {
+                this.type = 1;
+            }
+            
+            this.userid = auserID;
+        }
+
+        /// <summary>
+        /// 油枪号
+        /// </summary>
+        public int NozzleId { get; set; }
+
+        /// <summary>
+        /// 实际加油金额
+        /// </summary>
+        public decimal OriginalAmount { get; set; }
+
+        /// <summary>
+        /// 实际支付金额
+        /// </summary>
+        public decimal? ActualPaymentAmount { get; set; }
+
+        /// <summary>
+        /// 升数
+        /// </summary>
+        public decimal Qty { get; set; }
+
+        /// <summary>
+        /// 挂枪时间
+        /// </summary>
+        public DateTime FuelItemTransactionEndTime { get; set; }
+
+        /// <summary>
+        /// 交易时间
+        /// </summary>
+        public DateTime? TransactionTime { get; set; }
+
+        /// <summary>
+        /// 油品名
+        /// </summary>
+        public string Product { get; set; }
+
+        /// <summary>
+        /// 1:预支付;2:后支付
+        /// </summary>
+        public int type { get; set; }
+
+        /// <summary>
+        /// 用户id,预支付时候传入
+        /// </summary>
+        public string? userid { get; set; }
+    }
+}

+ 26 - 0
HengshanPaymentTerminal/Http/Response/Response.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.Http.Response
+{
+    /// <summary>
+    /// 云端响应数据对象
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public class Response<T>
+    {
+        public bool result {  get; set; }
+
+        public string message { get; set; }
+
+        public T data { get; set; }
+    }
+
+    public class CreateTransactionResponse
+    {
+
+    }
+}

+ 29 - 3
HengshanPaymentTerminal/MessageEntity/CommonMessage.cs

@@ -1,5 +1,6 @@
 using Edge.Core.Parser;
 using Edge.Core.Parser.BinaryParser.MessageEntity;
+using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 namespace HengshanPaymentTerminal.MessageEntity
@@ -184,8 +185,33 @@ namespace HengshanPaymentTerminal.MessageEntity
         /// <returns></returns>
         public T Bytes2Number<T>(byte[] datas,int startIndex,int length) where T: unmanaged
         {
+            int sizeOfT = Unsafe.SizeOf<T>();
             Span<byte> span = datas.AsSpan(startIndex, length);
-            if (BitConverter.IsLittleEndian) span.Reverse();
+
+            // 如果 span 的长度不够,补足长度
+            if (span.Length < sizeOfT)
+            {
+                // 使用数组而不是 stackalloc,避免栈溢出
+                byte[] paddedArray = new byte[sizeOfT];
+                Span<byte> paddedSpan = paddedArray.AsSpan();
+                // 在前面补零
+                span.CopyTo(paddedSpan.Slice(sizeOfT - span.Length));
+                if (BitConverter.IsLittleEndian)
+                {
+                    // 小端序:反转字节顺序
+                    paddedSpan.Reverse();
+                }
+
+                return MemoryMarshal.Read<T>(paddedSpan);
+            }
+
+            // 如果长度足够,直接读取
+            if (BitConverter.IsLittleEndian)
+            {
+                // 小端序:反转字节顺序
+                span.Reverse();
+            }
+
             return MemoryMarshal.Read<T>(span);
         }
         public List<Byte> addFA(List<Byte> list)
@@ -208,14 +234,14 @@ namespace HengshanPaymentTerminal.MessageEntity
             return result;
         }
 
-        public DateTime? bytes2DateTime(byte[] timeBytes)
+        public DateTime bytes2DateTime(byte[] timeBytes)
         {
             string formate = "yyyyMMddHHmmss";
             string timeStr = BitConverter.ToString(timeBytes).Replace("-", "");
             DateTime parsedDateTime;
 
             bool success = DateTime.TryParseExact(timeStr, formate, null, System.Globalization.DateTimeStyles.None, out parsedDateTime);
-            return success ? parsedDateTime : null;
+            return success ? parsedDateTime : DateTime.Now;
         }
     }
 }

+ 10 - 40
HengshanPaymentTerminal/MessageEntity/Incoming/OrderFromMachine.cs

@@ -29,12 +29,12 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
         /// <summary>
         /// 加油时间
         /// </summary>
-        public DateTime? dispenserTime { get; set; }
+        public DateTime dispenserTime { get; set; }
 
         /// <summary>
         /// 挂枪时间
         /// </summary>
-        public DateTime? endTime { get; set; }
+        public DateTime endTime { get; set; }
 
         /// <summary>
         /// 油品代码
@@ -51,16 +51,6 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
         /// </summary>
         public decimal price { get; set; }
 
-        /// <summary>
-        /// 卡交易流水
-        /// </summary>
-        public int ctc { get; set; }
-
-        /// <summary>
-        /// 升累计
-        /// </summary>
-        public decimal volumeTotal { get; set; }
-
         /// <summary>
         /// 金额
         /// </summary>
@@ -71,19 +61,9 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
         /// </summary>
         public decimal volume { get; set; }
 
-        /// <summary>
-        /// 卡号
-        /// </summary>
-        public string cardNum { get; set; }
-
-        /// <summary>
-        /// 消息鉴别码
-        /// </summary>
-        public string MAC { get; set; }
-
         public override byte[] ToCommonByteArray()
         {
-            byte[] content = new byte[] { 0x55, this.Handle, 0x00, ((byte)RESULT.OVER) };
+            byte[] content = new byte[] { 0x55, this.Handle, (byte)this.nozzleNum, ((byte)RESULT.OVER) };
             return content2data(content);
         }
 
@@ -106,24 +86,13 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
             this.payType = datas[28];
 
             ushort priceShort = Bytes2Number<ushort>(datas,29, 2);
-            this.price = priceShort / 100;
-
-            this.ctc = Bytes2Number<ushort>(datas, 31, 2);
-
-            uint volumeTotalInt = Bytes2Number<uint>(datas, 33, 4);
-            this.volumeTotal = volumeTotalInt / 100;
-
-            uint amountInt = Bytes2Number<uint>(datas, 37, 4);
-            this.amount = amountInt / 100;
-
-            uint volumeInt = Bytes2Number<uint>(datas, 40, 4);
-            this.volume = volumeInt / 100;
+            this.price = priceShort / 100m;
 
-            Span<byte> cardNumSpan = datas.AsSpan(43, 10);
-            this.cardNum = BitConverter.ToString(cardNumSpan.ToArray()).Replace("-", "");
+            uint amountInt = Bytes2Number<uint>(datas, 31, 3);
+            this.amount = amountInt / 100m;
 
-            Span<byte> MACSpan = datas.AsSpan(53, 10);
-            this.MAC = BitConverter.ToString(MACSpan.ToArray()).Replace("-", "");
+            uint volumeInt = Bytes2Number<uint>(datas, 34, 3);
+            this.volume = volumeInt / 100m;
 
             return this;
         }
@@ -141,7 +110,7 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
                 PaymentStatus = payType == (int)0x21 ? 0 : 4 ,
                 Amount = this.amount,
                 Volume = this.volume,
-                AmountPayable = this.amount,
+                //AmountPayable = this.amount,
                 UploadState = 0,
                 IsDelete = 0,
                 PaymentTime = null,
@@ -157,6 +126,7 @@ namespace HengshanPaymentTerminal.MessageEntity.Incoming
         /// <returns></returns>
         public FccOrderInfo PaddingAuthorizationOrderData(FccOrderInfo order)
         {
+            order.AuthorizationTime = this.dispenserTime;
             order.EndTime = this.endTime;
             order.Amount = this.amount;
             order.Volume = this.volume;

+ 6 - 6
HengshanPaymentTerminal/MessageTemplateLookup.cs

@@ -29,14 +29,14 @@ namespace HengshanPaymentTerminal
             messageCodeToTypeStrDict.Add("0x55",
                 "HengshanPaymentTerminal.MessageEntity.Incoming.CommonAnswerBack,HengshanPaymentTerminal");
 
-            //messageCodeToTypeStrDict.Add("0x13",
-            //    "HengshanPaymentTerminal.MessageEntity.Incoming.RegisterRequest,HengshanPaymentTerminal");
+            messageCodeToTypeStrDict.Add("0x18",
+                "HengshanPaymentTerminal.MessageEntity.Incoming.OrderFromMachine,HengshanPaymentTerminal");
 
-            //messageCodeToTypeStrDict.Add("0x15",
-            //    "HengshanPaymentTerminal.MessageEntity.Incoming.ValidateCardRequest,HengshanPaymentTerminal");
+            messageCodeToTypeStrDict.Add("0x65",
+                "HengshanPaymentTerminal.MessageEntity.Incoming.AuthorizationResponse,HengshanPaymentTerminal");
 
-            //messageCodeToTypeStrDict.Add("0x17",
-            //    "HengshanPaymentTerminal.MessageEntity.Incoming.AuthRequest,HengshanPaymentTerminal");
+            messageCodeToTypeStrDict.Add("0x66",
+                "HengshanPaymentTerminal.MessageEntity.Incoming.UnAhorizationResponse,HengshanPaymentTerminal");
             //messageCodeToTypeStrDict.Add("0x19",
             //    "HengshanPaymentTerminal.MessageEntity.Incoming.CancelAuthRequest,HengshanPaymentTerminal");
 

+ 8 - 0
src/FccLife.Web/Program.cs

@@ -11,6 +11,8 @@ using Edge.Core.Processor.Dispatcher;
 using Edge.Core.Processor;
 using Edge.Core.Processor.Dispatcher.ProcessorLoader;
 using Edge.Core.Core.database;
+using Edge.Core.HttpClient;
+using HengshanPaymentTerminal.Http;
 
 var builder = WebApplication.CreateBuilder(args);
  DefaultDispatcher processorsDispatcher = null;
@@ -19,6 +21,10 @@ builder.Services.AddDbContext<MysqlDbContext>(options =>
     options.UseMySql(builder.Configuration.GetConnectionString("DefaultConnection"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("DefaultConnection")))
     .LogTo(Console.WriteLine,LogLevel.Debug));
 
+// http Client
+builder.Services.AddHttpClient();
+builder.Services.AddSingleton<HttpClientService>();
+//builder.Services.AddSingleton<HttpClientUtils>();
 //controller
 builder.Services.AddControllers();
 
@@ -31,6 +37,8 @@ builder.Services.AddScoped<ITankInfoService, TankInfoServiceImpl>();
 builder.Services.AddScoped<ITankReposity, TankReposity>();
 builder.Services.AddScoped<INozzleInfnService, NozzleInfoServiceImpl>();
 builder.Services.AddScoped<INozzleInfoReposity, NozzleInfoReposity>();
+builder.Services.AddScoped<IHttpClient, HttpClientService>();
+builder.Services.AddScoped<IHttpClientUtil, HttpClientUtils>();
 
 //swagger
 builder.Services.AddSwaggerGen(c =>

+ 1 - 1
src/FccLife.Web/Repositories/FccNozzleInfo/INozzleInfoReposity.cs

@@ -23,6 +23,6 @@ namespace FccLite.Web.Repositories.FccNozzleInfo
         /// </summary>
         /// <param name="id"></param>
         /// <returns></returns>
-        Task<int> DeleteNozzleInfoById(long id);
+        Task<Edge.Core.Domain.FccNozzleInfo.FccNozzleInfo?> DeleteNozzleInfoById(long id);
     }
 }

+ 4 - 3
src/FccLife.Web/Repositories/FccNozzleInfo/NozzleInfoReposity.cs

@@ -60,17 +60,18 @@ namespace FccLite.Web.Repositories.FccNozzleInfo
         /// </summary>
         /// <param name="id"></param>
         /// <returns></returns>
-        public async Task<int> DeleteNozzleInfoById(long id)
+        public async Task<Edge.Core.Domain.FccNozzleInfo.FccNozzleInfo?> DeleteNozzleInfoById(long id)
         {
             Edge.Core.Domain.FccNozzleInfo.FccNozzleInfo? fccNozzleInfo = await _dbContext.NozzleInfos.FirstOrDefaultAsync(info => info.Id == id);
             if (fccNozzleInfo == null)
             {
                 Logger.Info($"find nozzle info with id : {id} for delete,result is null");
-                return 0;
+                return null;
             }
 
             _dbContext.NozzleInfos.Remove(fccNozzleInfo);
-            return await _dbContext.SaveChangesAsync();
+            await _dbContext.SaveChangesAsync();
+            return fccNozzleInfo;
         }
     }
 }

+ 2 - 0
src/FccLife.Web/Repositories/FccStationInfo/StationRepository.cs

@@ -77,6 +77,8 @@ namespace FccLite.Web.Repositories.FccStationInfo
 
                 station.BuildId = stationInfoInput.BuildId;
                 station.Name = stationInfoInput.Name != null ? stationInfoInput.Name : "";
+                station.SecretId = stationInfoInput.SecretId;
+                station.AcessKey = stationInfoInput.AcessKey;
                 station.Longitude = (decimal)(stationInfoInput.Longitude != null ? stationInfoInput.Longitude : new decimal(0));
                 station.Latitude = (decimal)(stationInfoInput.Latitude != null ? stationInfoInput.Latitude : new decimal(0));
                 station.SmallProgram = stationInfoInput.SmallProgram;

+ 7 - 0
src/FccLife.Web/Repositories/FccTankInfo/ITankReposity.cs

@@ -46,5 +46,12 @@ namespace FccLite.Web.Repositories.FccTankInfo
         /// </summary>
         /// <returns></returns>
         Task<List<DetailsNozzleInfoOutput.RelatableTank>> GetTankInfo();
+
+        /// <summary>
+        /// 获取油罐详情
+        /// </summary>
+        /// <param name="id">油罐id</param>
+        /// <returns></returns>
+        Task<DetailTankInfoForCloud?> GetTankDetail(long id);
     }
 }

+ 18 - 0
src/FccLife.Web/Repositories/FccTankInfo/TankReposity.cs

@@ -120,5 +120,23 @@ namespace FccLite.Web.Repositories.FccTankInfo
                 TankNum = info.Number
             }).ToListAsync();
         }
+
+        public async Task<DetailTankInfoForCloud?> GetTankDetail(long id)
+        {
+            var query = from tank in _dbContext.TankInfos
+                        join oil in _dbContext.OilInfos
+                        on tank.OilId equals oil.Id
+                        where tank.Id == id
+                        select new DetailTankInfoForCloud()
+                        {
+                            TankNumber = tank.Number,
+                            TankCapacity = tank.Capacity,
+                            ProductName = oil.Name,
+                            ProductCode = oil.Code,
+                            ProductPrice = oil.Price
+                        };
+
+            return await query.FirstOrDefaultAsync();
+        }
     }
 }

+ 60 - 6
src/FccLife.Web/Services/FccNozzleInfo/NozzleInfoServiceImpl.cs

@@ -1,7 +1,13 @@
 using Edge.Core.Domain.FccNozzleInfo.Input;
 using Edge.Core.Domain.FccNozzleInfo.Output;
+using Edge.Core.HttpClient;
 using FccLite.Web.Repositories.FccNozzleInfo;
 using FccLite.Web.Repositories.FccTankInfo;
+using HengshanPaymentTerminal.Http;
+using HengshanPaymentTerminal.Http.Request;
+using Newtonsoft.Json;
+using Org.BouncyCastle.Asn1.Ocsp;
+using System.Text;
 
 namespace FccLite.Web.Services.FccNozzleInfo
 {
@@ -11,10 +17,14 @@ namespace FccLite.Web.Services.FccNozzleInfo
 
         private readonly INozzleInfoReposity _nozzleInfoReposity;
         private readonly ITankReposity _tankReposity;
-        public NozzleInfoServiceImpl(INozzleInfoReposity nozzleInfoReposity,ITankReposity tankReposity)
+        private readonly IHttpClientUtil _httpClientUtils;
+        //private readonly IHttpClient _httpClient;
+        public NozzleInfoServiceImpl(INozzleInfoReposity nozzleInfoReposity,ITankReposity tankReposity, IHttpClientUtil httpClientUtils)
         {
             _nozzleInfoReposity = nozzleInfoReposity;
             _tankReposity = tankReposity;
+            _httpClientUtils = httpClientUtils;
+            //_httpClient = httpClient;
         }
         /// <summary>
         /// 新增、修改油枪信息
@@ -25,8 +35,21 @@ namespace FccLite.Web.Services.FccNozzleInfo
         {
             int row = await _nozzleInfoReposity.UploadNozzleInfo(nozzleInfoInput);
             Logger.Info($"upload nozzle info ,chage row {row}");
+
             if(row > 0)
             {
+                try
+                {
+                    var type = nozzleInfoInput.Id == null ? 1 : 2;
+                    SendNozzleInfo sendNozzleInfo = await UploadNozzleInfoInput2SendNozzleInfo(nozzleInfoInput, type);
+                    var requestJson = JsonConvert.SerializeObject(sendNozzleInfo);
+                    HttpResponseMessage httpResponseMessage = await _httpClientUtils.SendNozzleInfo(requestJson);
+                    Logger.Info($"send nozzle response : {httpResponseMessage.Content}");
+                }
+                catch (Exception e)
+                {
+                    Logger.Error($"send nozzle to cloud error:{e.Message}", e);
+                }
                 return new SetNozzleInfoOutput()
                 {
                     Result = true,
@@ -36,8 +59,25 @@ namespace FccLite.Web.Services.FccNozzleInfo
 
             return new SetNozzleInfoOutput()
             {
-                Result = false,
-                Message = "保存失败"
+                Result = true,
+                Message = "无更新"
+            };
+        }
+
+        private async Task<SendNozzleInfo> UploadNozzleInfoInput2SendNozzleInfo(UploadNozzleInfoInput uploadNozzleInfoInput,int typeValue)
+        {
+            Edge.Core.Domain.FccTankInfo.Output.DetailTankInfoForCloud? detailTank = await _tankReposity.GetTankDetail(uploadNozzleInfoInput.TankId);
+            return new SendNozzleInfo()
+            {
+                PumpId = uploadNozzleInfoInput.FuelPoint,
+                InternalGunNumber = uploadNozzleInfoInput.InternalNum,
+                ExternalGunNumber = uploadNozzleInfoInput.NozzleNum,
+                TankNumber = uploadNozzleInfoInput.TankNum,
+                TankCapacity = detailTank?.TankCapacity ?? new decimal(0.00),
+                ProductName = detailTank?.ProductName ?? "",
+                ProductCode = detailTank?.ProductCode ?? 0,
+                ProductPrice = detailTank?.ProductPrice ?? new decimal(0.00),
+                type = typeValue
             };
         }
 
@@ -80,10 +120,24 @@ namespace FccLite.Web.Services.FccNozzleInfo
         /// <returns></returns>
         public async Task<SetNozzleInfoOutput> DeleteNozzleInfoByID(long id)
         {
-            int row = await _nozzleInfoReposity.DeleteNozzleInfoById(id);
-            Logger.Info($"delete nozzle info ,chage row {row}");
-            if (row > 0)
+            Edge.Core.Domain.FccNozzleInfo.FccNozzleInfo? fccNozzleInfo = await _nozzleInfoReposity.DeleteNozzleInfoById(id);
+            Logger.Info($"delete nozzle info ,chage {fccNozzleInfo}");
+            if (fccNozzleInfo != null)
             {
+                var nozzleInfoInput = new UploadNozzleInfoInput()
+                {
+                    TankId = fccNozzleInfo.TankId,
+                    FuelPoint = fccNozzleInfo.FuelPoint,
+                    InternalNum = fccNozzleInfo.InternalNum,
+                    NozzleNum = fccNozzleInfo.ExternalNum,
+                    TankNum = fccNozzleInfo.TankNum
+                };
+                SendNozzleInfo sendNozzleInfo = await UploadNozzleInfoInput2SendNozzleInfo(nozzleInfoInput, 3);
+                var requestJson = JsonConvert.SerializeObject(sendNozzleInfo);
+                HttpResponseMessage httpResponseMessage = await _httpClientUtils.SendNozzleInfo(requestJson);
+                //var requesStr = new StringContent(requestJson, Encoding.UTF8, "application/json");
+                //HttpResponseMessage httpResponseMessage = await _httpClient.PostAsync("api/nozzle/uploadNozzle", requesStr);
+                Logger.Info($"send nozzle response : {httpResponseMessage.Content}");
                 return new SetNozzleInfoOutput()
                 {
                     Result = true,