Jelajahi Sumber

feat:心跳、油枪状态、油枪信息

Zhenghanjv 6 bulan lalu
induk
melakukan
6053652f41

+ 13 - 0
Edge.Core/Parser/BinaryParser/MessageEntity/MessageTemplateBase.cs

@@ -109,5 +109,18 @@ namespace Edge.Core.Parser.BinaryParser.MessageEntity
 
             return propertyNameValueString;
         }
+
+        /// <summary>
+        /// 将数据转成数据对象
+        /// </summary>
+        /// <param name="datas">数据</param>
+        /// <returns></returns>
+        public virtual MessageTemplateBase ToObject(byte[] datas) { return this; }
+
+        /// <summary>
+        /// 将数据对象转为数组
+        /// </summary>
+        /// <returns></returns>
+        public virtual  byte[] ToCommonByteArray() { return new byte[0]; }
     }
 }

+ 3 - 6
Edge.Core/Parser/BinaryParser/ParserBase.cs

@@ -84,13 +84,10 @@ namespace Edge.Core.Parser.BinaryParser
         /// <returns></returns>
         public virtual MessageTemplateBase Deserialize(byte[] rawData)
         {
-            //if (rawData.Length < 5)
-            //{
-            //    return default(MessageTemplateBase);
-            //}
-
             if (this.templateLookup == null) throw new ArgumentNullException("Must specify a 'TemplateLookup' to start Deserialize");
-            return this.Deserialize(rawData, templateLookup.GetMessageTemplateByRawBytes(rawData));
+            MessageTemplateBase messageTemplateBase = templateLookup.GetMessageTemplateByRawBytes(rawData);
+            return messageTemplateBase.ToObject(rawData);
+            //return this.Deserialize(rawData, templateLookup.GetMessageTemplateByRawBytes(rawData));
         }
 
         public virtual MessageTemplateBase Deserialize(byte[] rawData, MessageTemplateBase withTemplate)

+ 20 - 1
Edge.Core/Processor/Communicator/IMessageCutter.cs

@@ -66,7 +66,14 @@ namespace Edge.Core.Processor.Communicator
                     this.OnWindowFull(this.list);
             }
         }
-
+        
+        public void Add(List<T> list)
+        {
+            this.list.AddRange(list);
+            if (OnWindowFull != null)
+                this.OnWindowFull(this.list);
+        }
+        
         #region MyRegion
 
         public void Clear()
@@ -114,6 +121,18 @@ namespace Edge.Core.Processor.Communicator
         {
             return this.list.Remove(item);
         }
+
+        /// <summary>
+        /// 删除特定范围的数据
+        /// </summary>
+        /// <param name="startIndex"></param>
+        /// <param name="count"></param>
+        public void RemoveRange(int startIndex,int count)
+        {
+            if (startIndex < 0 || startIndex >= this.list.Count || startIndex+count > this.list.Count) return;
+            this.list.RemoveRange(startIndex, count);
+            this.size = this.list.Count;
+        }
         #endregion
 
         /// <summary>

+ 2 - 1
Edge.Core/Processor/Communicator/TcpClientCommunicator.cs

@@ -155,7 +155,8 @@ namespace Edge.Core.Processor.Communicator
             byte[] rawData;
             try
             {
-                rawData = this.parser.Serialize(message);
+                //rawData = this.parser.Serialize(message);
+                rawData = message.ToCommonByteArray();
                 var safe = this.OnRawDataWriting;
                 var arg = new CommunicatorEventArg<byte[], T>() { Data = rawData, Message = message, Continue = true };
                 safe?.Invoke(this, arg);

+ 3 - 2
Edge.Core/Processor/Communicator/TcpServerCommunicator.cs

@@ -102,7 +102,7 @@ namespace Edge.Core.Processor.Communicator
                     try
                     {
                         eventArg.Data = this.messageCutter.Message;
-                        //eventArg.Message = this.parser.Deserialize(this.messageCutter.Message.ToArray()) as T;
+                        eventArg.Message = this.parser.Deserialize(this.messageCutter.Message.ToArray()) as T;
                         if (logger.IsEnabled(LogLevel.Debug))
                             this.logger.LogDebug("      Parsed: " + eventArg.Message.ToLogString());
                     }
@@ -298,7 +298,8 @@ namespace Edge.Core.Processor.Communicator
             byte[] rawData;
             try
             {
-                rawData = this.parser.Serialize(message);
+                rawData = message.ToCommonByteArray();
+                //rawData = this.parser.Serialize(message);
                 var arg = new CommunicatorEventArg<byte[], T>() { Data = rawData, Message = message, Continue = true };
                 this.OnRawDataWriting?.Invoke(this, arg);
                 if (this.exclusiveTcpClient == null || !arg.Continue) { this.logger.LogError("Write failed, this.tcpClient is null: " + (this.exclusiveTcpClient is null)); return false; }

+ 81 - 8
HengshanPaymentTerminal/HengshanPayTermHandler.cs

@@ -27,7 +27,7 @@ namespace HengshanPaymentTerminal
         {
             "lang-zh-cn:恒山IC卡终端lang-en-us:HengshanICTerminal"
         })]
-    public class HengshanPayTermHandler : IEnumerable<IFdcPumpController>, IDeviceHandler<byte[], CardMessageBase>
+    public class HengshanPayTermHandler : IEnumerable<IFdcPumpController>, IDeviceHandler<byte[], CommonMessage>
     {
         #region Fields
 
@@ -37,10 +37,11 @@ namespace HengshanPaymentTerminal
         private string pumpSiteNozzleNos;
         private string nozzleLogicIds;
 
-        private IContext<byte[], CardMessageBase> _context;
+        private IContext<byte[], CommonMessage> _context;
         private List<HengshanPumpHandler> pumpHandlers = new List<HengshanPumpHandler>();
 
         public Queue<CardMessageBase> queue = new Queue<CardMessageBase>();
+        public Queue<CommonMessage> commonQueue = new Queue<CommonMessage>();
         private object syncObj = new object();
 
         private ConcurrentDictionary<int, PumpStateHolder> statusDict = new ConcurrentDictionary<int, PumpStateHolder>();
@@ -157,7 +158,7 @@ namespace HengshanPaymentTerminal
 
         public List<int> AssociatedPumpIds { get; private set; }
 
-        public IContext<byte[], CardMessageBase> Context
+        public IContext<byte[], CommonMessage> Context
         {
             get { return _context; }
         }
@@ -388,7 +389,7 @@ namespace HengshanPaymentTerminal
 
         #region IHandler implementation
 
-        public void Init(IContext<byte[], CardMessageBase> context)
+        public void Init(IContext<byte[], CommonMessage> context)
         {
             CommIdentity = context.Processor.Communicator.Identity;
             _context = context;
@@ -396,9 +397,18 @@ namespace HengshanPaymentTerminal
 
         public string CommIdentity { get; private set; }
 
-        public async Task Process(IContext<byte[], CardMessageBase> context)
+        public async Task Process(IContext<byte[], CommonMessage> context)
         {
             
+            switch(context.Incoming.Message.Handle)
+            {
+                //通用
+                case 0x55:
+
+                    break;
+            }
+            
+            context.Outgoing.Write(context.Incoming.Message);
         }
 
         private void CheckStatus(CheckCmdRequest request)
@@ -469,12 +479,12 @@ namespace HengshanPaymentTerminal
             }
         }
 
-        public void Write(CardMessageBase cardMessage)
+        public void Write(CommonMessage cardMessage)
         {
             _context.Outgoing.Write(cardMessage);
         }
 
-        public async Task<CardMessageBase> WriteAsync(CardMessageBase request, Func<CardMessageBase, CardMessageBase, bool> responseCapture,
+        public async Task<CommonMessage> WriteAsync(CommonMessage request, Func<CommonMessage, CommonMessage, bool> responseCapture,
             int timeout)
         {
             var resp = await _context.Outgoing.WriteAsync(request, responseCapture, timeout);
@@ -512,7 +522,7 @@ namespace HengshanPaymentTerminal
                 if (queue.Count > 0)
                 {
                     DebugLog($"queue count: {queue.Count}");
-                    var message = queue.Dequeue();
+                    var message = commonQueue.Dequeue();
                     Write(message);
                     return true;
                 }
@@ -568,6 +578,69 @@ namespace HengshanPaymentTerminal
         }
 
         #endregion
+
+        #region 二维码加油机相关方法
+
+        /// <summary>
+        /// 移除多余FA,有效数据中,一个 0xfa 会转成两个 0xfa
+        /// </summary>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        private static Byte[] RemoveFA(Byte[] input)
+        {
+            List<byte> resultList = new List<byte>();
+
+            for (int i = 0; i < input.Length; i++)
+            {
+                if (i < input.Length - 1 && input[i] == 0xFA && input[i + 1] == 0xFA)
+                {
+                    resultList.Add(0xFA);
+                    i++; // 跳过下一个元素  
+                }
+                else
+                {
+                    resultList.Add(input[i]);
+                }
+            }
+
+            return resultList.ToArray();
+        }
+
+        // CRC16 constants  
+        const ushort CRC_ORDER16 = 16;
+        const ushort CRC_POLYNOM16 = 0x1021;
+        const ushort CRC_CRCINIT16 = 0xFFFF;
+        const ushort CRC_CRCXOR16 = 0x0000;
+        const ushort CRC_MASK = 0xFFFF;
+        const ushort CRC_HIGHEST_BIT = (ushort)(1 << (CRC_ORDER16 - 1));
+        const ushort TGT_CRC_DEFAULT_INIT = 0xFFFF;
+        public static ushort Crc16(byte[] buffer, ushort length)
+        {
+            ushort crc_rc = TGT_CRC_DEFAULT_INIT;
+
+            for (int i = 0; i < length; i++)
+            {
+                byte c = buffer[i];
+                for (ushort j = 0x80; j != 0; j >>= 1)
+                {
+                    ushort crc_bit = (ushort)((crc_rc & CRC_HIGHEST_BIT) != 0 ? 1 : 0);
+                    crc_rc <<= 1;
+
+                    if ((c & j) != 0)
+                    {
+                        crc_bit = (ushort)((crc_bit == 0) ? 1 : 0);
+                    }
+
+                    if (crc_bit != 0)
+                    {
+                        crc_rc ^= CRC_POLYNOM16;
+                    }
+                }
+            }
+
+            return (ushort)((crc_rc ^ CRC_CRCXOR16) & CRC_MASK);
+        }
+        #endregion
     }
 
     public class HengshanPayTerminalHanlderGroupConfigV1

+ 6 - 0
HengshanPaymentTerminal/HengshanPaymentTerminal.csproj

@@ -7,7 +7,13 @@
   </PropertyGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
     <PackageReference Include="NLog" Version="5.3.4" />
+    <PackageReference Include="xunit" Version="2.9.2" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
   </ItemGroup>
 
   <ItemGroup>

+ 16 - 16
HengshanPaymentTerminal/HengshanPumpHandler.cs

@@ -361,22 +361,22 @@ namespace HengshanPaymentTerminal
             return Task.FromResult(state);
         }
 
-        public void QueryTotalizerAsync(int pumpId, byte logicalNozzleId)
-        {
-            Log($"Query totalizer internally...");
-
-            var request = new ReadVolumeTotal
-            {
-                Prefix = 0xFA,
-                SourceAddress = Convert.ToByte(pumpId),
-                DestinationAddress = Convert.ToByte(pumpId),
-                FrameSqNoByte = frameSqNo,
-                Handle = (byte)MessageEntity.Command.ReadVolumeTotalizer,
-                NozzleNo = logicalNozzleId
-            };
-
-            terminalHandler.Write(request);
-        }
+        //public void QueryTotalizerAsync(int pumpId, byte logicalNozzleId)
+        //{
+        //    Log($"Query totalizer internally...");
+
+        //    var request = new ReadVolumeTotal
+        //    {
+        //        Prefix = 0xFA,
+        //        SourceAddress = Convert.ToByte(pumpId),
+        //        DestinationAddress = Convert.ToByte(pumpId),
+        //        FrameSqNoByte = frameSqNo,
+        //        Handle = (byte)MessageEntity.Command.ReadVolumeTotalizer,
+        //        NozzleNo = logicalNozzleId
+        //    };
+
+        //    terminalHandler.Write(request);
+        //}
 
         public Task<Tuple<long, long>> QueryTotalizerAsync(byte logicalNozzleId)
         {

+ 19 - 0
HengshanPaymentTerminal/MessageEntity/CardMessageBase.cs

@@ -328,5 +328,24 @@ namespace HengshanPaymentTerminal.MessageEntity
             return GetType().Name + "    " + base.ToLogString().Replace(
                 "FrameSqNoByte:", "(Caller: " + Caller + ", FrameNo: " + FrameNo + ")FrameSqNoByte:");
         }
+
+        /// <summary>
+        /// 将数据转成数据对象
+        /// </summary>
+        /// <param name="datas">数据</param>
+        /// <returns></returns>
+        public override MessageTemplateBase ToObject(byte[] datas)
+        {
+            return this;
+        }
+
+        /// <summary>
+        /// 将数据对象转为数组
+        /// </summary>
+        /// <returns></returns>
+        public override byte[] ToCommonByteArray()
+        {
+            return new byte[0];
+        }
     }
 }

+ 187 - 0
HengshanPaymentTerminal/MessageEntity/CommonMessage.cs

@@ -0,0 +1,187 @@
+using Edge.Core.Parser;
+using Edge.Core.Parser.BinaryParser.MessageEntity;
+
+namespace HengshanPaymentTerminal.MessageEntity
+{
+    /// <summary>
+    /// 与油机通讯的基础数据包对象
+    /// </summary>
+    public abstract class CommonMessage: MessageTemplateBase
+    {
+        public enum Command
+        {
+            /// <summary>
+            /// 通用应答命令字
+            /// </summary>
+            COMMON = 0x55,
+
+            /// <summary>
+            /// 心跳命令字
+            /// </summary>
+            HEART_BRET = 0x10,
+
+            /// <summary>
+            /// 油枪信息命令字
+            /// </summary>
+            NOZZLE_INFO = 0x61,
+
+            /// <summary>
+            /// 油枪状态命令字
+            /// </summary>
+            NOZZLE_STATE = 0x62,
+
+            /// <summary>
+            /// 发送二维码给油机命令字
+            /// </summary>
+            SEND_QR_CODE = 0x63,
+
+            /// <summary>
+            /// 获取单价命令字
+            /// </summary>
+            GET_PRICE = 0x64,
+
+            /// <summary>
+            /// 授权命令字
+            /// </summary>
+            ACCREDIT = 0x65,
+
+            /// <summary>
+            /// 取消授权命令字
+            /// </summary>
+            CANCEL_ACCREDIT = 0x66,
+
+            /// <summary>
+            /// 接收油机订单命令字
+            /// </summary>
+            RECIEVE_TRANX = 0x18,
+
+            /// <summary>
+            /// 发送应付金额给油机命令字
+            /// </summary>
+            SEND_NEED_AMOUNT = 0x19
+
+
+        }
+        /// <summary>
+        /// 包头 0xFA
+        /// </summary>
+        public Byte Head { get; set; }
+
+        /// <summary>
+        /// 目标地址
+        /// </summary>
+        public Byte DestinationAddr { get; set; }
+
+        /// <summary>
+        /// 源地址
+        /// </summary>
+        public Byte SourceAddr { get; set; }
+
+        /// <summary>
+        /// 帧号
+        /// </summary>
+        public int FrameNum { get; set; }
+
+        /// <summary>
+        /// 有效数据长度,标识油机数据包中,有效数据的长度
+        /// </summary>
+        public int DataLength { get; set; }
+
+        /// <summary>
+        /// 命令字,用来标识数据包传递的数据
+        /// </summary>
+        public Byte Handle { get; set; }
+
+        /// <summary>
+        /// crc 校验值
+        /// </summary>
+        public Byte[] CRC { get; set; }
+
+        public CommonMessage getBaseData(byte[] data)
+        {
+            this.Handle = data[0];
+            this.DestinationAddr = data[1];
+            this.SourceAddr = data[2];
+            this.FrameNum = data[3];
+            this.DataLength = Bcd2Int(data[4], data[5]);
+            this.Handle = data[6];
+            this.CRC = new byte[]{ data[data.Length - 2],data[data.Length - 1] };
+            return this;
+        }
+
+        /// <summary>
+        /// 传入有效数据,拼接为要发送给油机包
+        /// </summary>
+        /// <param name="content"></param>
+        /// <returns></returns>
+        public byte[] content2data(byte[] content)
+        {
+            List<byte> list = new List<byte>();
+            //目标地址,源地址,帧号
+            byte[] head = new byte[] { this.SourceAddr, this.DestinationAddr, (byte)this.FrameNum };
+            byte[] length = Int2BCD(content.Length);
+            list.AddRange(head);
+            list.AddRange(length);
+            list.AddRange(content);
+            byte[] crc = HengshanCRC16.ComputeChecksumToBytes(list.ToArray());
+            list.AddRange(crc);
+            List<byte> addFAList = addFA(list);
+            addFAList.Insert(0,0xFA);
+            return addFAList.ToArray();
+        }
+
+        public int Bcd2Int(byte byte1, byte byte2)
+        {
+            // 提取第一个字节的高四位和低四位  
+            int digit1 = (byte1 >> 4) & 0x0F; // 高四位  
+            int digit2 = byte1 & 0x0F;        // 低四位  
+
+            // 提取第二个字节的高四位和低四位  
+            int digit3 = (byte2 >> 4) & 0x0F; // 高四位  
+            int digit4 = byte2 & 0x0F;        // 低四位  
+
+            // 组合成一个整数  
+            int result = digit1 * 1000 + digit2 * 100 + digit3 * 10 + digit4;
+
+            return result;
+        }
+
+        public byte[] Int2BCD(int number)
+        {
+            // 提取千位、百位、十位和个位  
+            int thousands = number / 1000;
+            int hundreds = (number / 100) % 10;
+            int tens = (number / 10) % 10;
+            int units = number % 10;
+
+            // 将千位和百位组合成一个字节(千位在高四位,百位在低四位)  
+            byte firstByte = (byte)((thousands * 16) + hundreds); // 乘以16相当于左移4位  
+
+            // 将十位和个位组合成一个字节(十位在高四位,个位在低四位)  
+            byte secondByte = (byte)((tens * 16) + units);
+
+            // 返回结果数组  
+            return new byte[] { firstByte, secondByte };
+        }
+
+        public List<Byte> addFA(List<Byte> list)
+        {
+            List<byte> result = new List<byte>();
+
+            foreach (byte b in list)
+            {
+                if (b == 0xFA)
+                {
+                    result.Add(0xFA);
+                    result.Add(0xFA);
+                }
+                else
+                {
+                    result.Add(b);
+                }
+            }
+
+            return result;
+        }
+    }
+}

+ 78 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/CommonAnswerBack.cs

@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// 普通应答格式数据包
+    /// </summary>
+    public class CommonAnswerBack : CommonMessage
+    {
+        /// <summary>
+        /// 原命令字
+        /// </summary>
+        public Byte Command { get; set; }
+
+        /// <summary>
+        /// 枪号,无枪号填0
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 应答命令状态
+        /// </summary>
+        public RESULT Result { get; set; }
+
+        //public override string ToLogString()
+        //{
+        //    return "";
+        //}
+
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override byte[] ToCommonByteArray()
+        {
+            throw new NotImplementedException();
+        }
+    }
+
+    public enum RESULT
+    {
+        /// <summary>
+        /// 命令收到,处理完成
+        /// </summary>
+        OVER = 0x01,
+
+        /// <summary>
+        /// 命令收到,在处理,需通过轮询返回结果
+        /// </summary>
+        IN_PROCESS = 0x02,
+
+        /// <summary>
+        /// 某差错造成不能处理的命令,可重发 1 次
+        /// </summary>
+        CANNOT_PROCESS = 0x03,
+
+        /// <summary>
+        /// 命令收到,也正确,但不适合处理或不处理
+        /// </summary>
+        NO_PROCESS = 0x04,
+
+        /// <summary>
+        /// 收到交易数据,正确
+        /// </summary>
+        GOT_TRN_RIGHT = 0x05,
+
+        /// <summary>
+        /// 收到交易数据,T-MAC 错
+        /// </summary>
+        GOT_TRN_TMAC_ERR = 0x06
+
+    }
+}

+ 68 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/HeartBeatMessage.cs

@@ -0,0 +1,68 @@
+using Edge.Core.IndustryStandardInterface.Pump.Fdc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// 心跳包数据对象
+    /// </summary>
+    public class HeartBeatMessage : CommonMessage
+    {
+        /// <summary>
+        /// 油枪数
+        /// </summary>
+        public int GunCount { get; set; }
+
+        /// <summary>
+        /// 各油枪状态
+        /// </summary>
+        public List<HeartBeatNozzleState> NozzleStatus { get; set; }
+        
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            this.getBaseData(datas);
+            this.GunCount = datas[7];
+            List<HeartBeatNozzleState> nozzleStates = new List<HeartBeatNozzleState>();
+            for (int index = 8;index < datas.Length - 2;index += 3)
+            {
+                HeartBeatNozzleState nozzle = new HeartBeatNozzleState()
+                {
+                    NozzleNum = datas[index],
+                    WorkState = datas[index + 1],
+                    AccreditState = datas[index + 2]
+                };
+                nozzleStates.Add(nozzle);
+            }
+            this.NozzleStatus = nozzleStates;
+            return this;
+        }
+
+        public override byte[] ToCommonByteArray()
+        {
+            byte[] content = new byte[] { 0x55, this.Handle, 0x00, ((byte)RESULT.OVER) };
+            return content2data(content);
+        }
+    }
+
+    public class HeartBeatNozzleState
+    {
+        /// <summary>
+        /// 油枪号
+        /// </summary>
+        public int NozzleNum { get; set; }
+
+        /// <summary>
+        /// 上下班状态 0:下班;1:上班
+        /// </summary>
+        public int WorkState { get; set; }
+
+        /// <summary>
+        /// 授权模式状态 0表示前庭;1表示后台
+        /// </summary>
+        public int AccreditState { get; set; }
+    }
+}

+ 88 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/NozzleInfo.cs

@@ -0,0 +1,88 @@
+using Edge.Core.Parser.BinaryParser.MessageEntity;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// 油机发送油枪信息数据对象
+    /// </summary>
+    public class NozzleInfo : CommonMessage
+    {
+        /// <summary>
+        /// 油枪数
+        /// </summary>
+        public int GunNum { get; set; }
+
+        /// <summary>
+        /// 各油枪信息
+        /// </summary>
+        public List<Nozzle> nozzles { get; set; }
+        public class Nozzle
+        {
+            /// <summary>
+            /// 加油点
+            /// </summary>
+            public int fpoint { get; set; }
+
+            /// <summary>
+            /// 内部枪号
+            /// </summary>
+            public int internalNum { get; set; }
+
+            /// <summary>
+            /// 外部枪号
+            /// </summary>
+            public int externalNum { get; set; }
+
+            /// <summary>
+            /// 单价
+            /// </summary>
+            public decimal price { get; set; }
+
+            /// <summary>
+            /// 油品代码
+            /// </summary>
+            public string oilCode { get; set; }
+
+        }
+
+        public override byte[] ToCommonByteArray()
+        {
+            byte[] content = new byte[] { 0x55, this.Handle, 0x00, ((byte)RESULT.OVER) };
+            return content2data(content);
+        }
+
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            getBaseData(datas);
+            this.GunNum = datas[7];
+            int index = 8;
+            List<Nozzle> nozzles = new List<Nozzle>();
+            while (index + 7 <= datas.Length)
+            {
+                Nozzle nozzle = new Nozzle();
+                nozzle.fpoint =  datas[index];
+                nozzle.internalNum = datas[index + 1];
+                nozzle.externalNum = datas[index + 2];
+                Span<byte> priceSpan = datas.AsSpan(index + 3, 2);
+                if (BitConverter.IsLittleEndian)
+                {
+                    priceSpan.Reverse();
+                }
+                ushort priceShort = MemoryMarshal.Read<ushort>(priceSpan);
+                nozzle.price = priceShort / 100;
+                nozzle.oilCode = Bcd2Int(datas[index + 5], datas[index+6]).ToString();
+
+                nozzles.Add(nozzle);
+                index += 7;
+            }
+            this.nozzles = nozzles;
+            return this;
+        }
+    }
+}

+ 67 - 0
HengshanPaymentTerminal/MessageEntity/Incoming/NozzleState.cs

@@ -0,0 +1,67 @@
+using Edge.Core.Parser.BinaryParser.MessageEntity;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HengshanPaymentTerminal.MessageEntity.Incoming
+{
+    /// <summary>
+    /// 油枪状态数据对象
+    /// </summary>
+    public class NozzleState : CommonMessage
+    {
+        public enum NozzleStateEnum
+        {
+            /// <summary>
+            /// 离线
+            /// </summary>
+            OFF_LINE = 0x01,
+            /// <summary>
+            /// 锁枪
+            /// </summary>
+            LOCK = 0x02,
+            /// <summary>
+            /// 空闲
+            /// </summary>
+            IDLE = 0x03,
+            /// <summary>
+            /// 提枪
+            /// </summary>
+            LIFT = 0x04,
+            /// <summary>
+            /// 开始加油
+            /// </summary>
+            START = 0x05,
+            /// <summary>
+            /// 加油中
+            /// </summary>
+            FUELING = 0x06
+        }
+
+        /// <summary>
+        /// 枪号
+        /// </summary>
+        public int nozzleNum {  get; set; }
+
+        /// <summary>
+        /// 状态
+        /// </summary>
+        public NozzleStateEnum stateEnum { get; set; }
+
+        public override byte[] ToCommonByteArray()
+        {
+            byte[] content = new byte[] { 0x55, this.Handle, 0x00, ((byte)RESULT.OVER) };
+            return content2data(content);
+        }
+
+        public override CommonMessage ToObject(byte[] datas)
+        {
+            getBaseData(datas);
+            this.nozzleNum = datas[7];
+            this.stateEnum = (NozzleStateEnum)datas[8];
+            return this;
+        }
+    }
+}

+ 32 - 29
HengshanPaymentTerminal/MessageTemplateLookup.cs

@@ -24,48 +24,51 @@ namespace HengshanPaymentTerminal
         static MessageTemplateLookup()
         {
             messageCodeToTypeStrDict.Add("0x10",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.CheckCmdRequest,HengshanPaymentTerminal");
+                "HengshanPaymentTerminal.MessageEntity.Incoming.HeartBeatMessage,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x13",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.RegisterRequest,HengshanPaymentTerminal");
+            messageCodeToTypeStrDict.Add("0x55",
+                "HengshanPaymentTerminal.MessageEntity.Incoming.CommonAnswerBack,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x15",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.ValidateCardRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x13",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.RegisterRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x17",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.AuthRequest,HengshanPaymentTerminal");
-            messageCodeToTypeStrDict.Add("0x19",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.CancelAuthRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x15",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.ValidateCardRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x1C",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.FuelingDataRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x17",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.AuthRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x19",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.CancelAuthRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x20",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.ChangeAuthModeAck,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x1C",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.FuelingDataRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x21",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.QueryGrayRecordRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x20",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.ChangeAuthModeAck,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x2D",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.TransactionDataRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x21",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.QueryGrayRecordRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x30",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.PaymentRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x2D",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.TransactionDataRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x45",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.LockOrUnlockPumpAck,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x30",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.PaymentRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x24",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.VolumeTotal,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x45",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.LockOrUnlockPumpAck,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x25",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.DataDownloadRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x24",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.VolumeTotal,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x27",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.DataContentRequest,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x25",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.DataDownloadRequest,HengshanPaymentTerminal");
 
-            messageCodeToTypeStrDict.Add("0x49",
-                "HengshanPaymentTerminal.MessageEntity.Incoming.Totalizer,HengshanPaymentTerminal");
+            //messageCodeToTypeStrDict.Add("0x27",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.DataContentRequest,HengshanPaymentTerminal");
+
+            //messageCodeToTypeStrDict.Add("0x49",
+            //    "HengshanPaymentTerminal.MessageEntity.Incoming.Totalizer,HengshanPaymentTerminal");
         }
 
         public MessageTemplateBase GetMessageTemplateByRawBytes(byte[] bytes)

+ 41 - 0
HengshanPaymentTerminal/Parser.cs

@@ -6,6 +6,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
+using AutoMapper.Execution;
 
 
 namespace HengshanPaymentTerminal
@@ -138,6 +139,11 @@ namespace HengshanPaymentTerminal
         0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040
         };
 
+        // CRC-16/CCITT-FALSE多项式  
+        private const ushort Polynomial = 0x1021;
+        // 初始值  
+        private const ushort InitialValue = 0xFFFF;
+
         public static ushort ComputeCrc(byte[] data)
         {
             ushort crc = 0x0001;
@@ -156,5 +162,40 @@ namespace HengshanPaymentTerminal
             ushort result = ComputeCrc(data);
             return BitConverter.GetBytes(result).Reverse().ToArray();
         }
+
+        // 计算CRC-16/CCITT-FALSE校验值  
+        public static ushort ComputeChecksum(byte[] data)
+        {
+            ushort crc = InitialValue;
+
+            foreach (byte b in data)
+            {
+                crc ^= (ushort)((b << 8) & 0xFF00); // 将字节数据左移8位并与0xFF00进行与操作  
+
+                for (int i = 0; i < 8; i++)
+                {
+                    if ((crc & 0x8000) != 0) // 检查最高位是否为1  
+                    {
+                        crc = (ushort)((crc << 1) ^ Polynomial); // 左移1位并与多项式进行异或  
+                    }
+                    else
+                    {
+                        crc <<= 1; // 仅左移1位  
+                    }
+                }
+            }
+
+            return crc;
+        }
+
+        // 计算CRC-16/CCITT-FALSE校验值,返回数组
+        public static byte[] ComputeChecksumToBytes(byte[] data)
+        {
+            byte[] result = new byte[2];
+            ushort value = ComputeChecksum(data);
+            result[0] = (byte)((value >> 8) & 0xFF); // 高8位  
+            result[1] = (byte)(value & 0xFF); // 低8位  
+            return result;
+        }
     }
 }

+ 85 - 139
HengshanPaymentTerminal/StateMachineMessageCutter.cs

@@ -32,7 +32,7 @@ namespace HengshanPaymentTerminal
         private string loggerAppendix = "HengshanPay Terminal";
         private readonly SizableWindow<byte> window;
 
-        private State nextState = State.Uninitialized;
+        //private State nextState = State.Uninitialized;
 
         private const int STX = 0xFA;
 
@@ -50,132 +50,67 @@ namespace HengshanPaymentTerminal
 
             window.OnWindowFull += (data) =>
             {
-                Message = window.ToArray();
+                byte[] tempBytes = window.ToArray();
+
+                //查找包头位置
+                int findIndex = -1;
+                for (int index = 0;index < tempBytes.Length - 1;index++)
+                {
+                    if (tempBytes[index] == STX && tempBytes[index + 1] != STX)
+                    {
+                        findIndex = index;
+                        break;
+                    }
+                }
+                //若没有找到包头,证明目前缓存中都是垃圾数据,清掉
+                if (findIndex == -1)
+                {
+                    window.RemoveRange(0, tempBytes.Length);
+                    return;
+                }
+                //长度不够表示有粘包,部分数据还未接收到,等待下一轮接收数据再处理
+                //1byte FA + 1 byte 目标地址 + 1 byte 源地址 + 1 byte 帧号 + 2 byte 有效数据长度 + 2 byte 数据校验 = 8byte
+                if(findIndex + 8 > tempBytes.Length)
+                {
+                    innerLogger.Info($"Insufficient data length,at least ,need {findIndex + 8},but length is {tempBytes.Length}");
+                    return;
+                }
+                //获取有效数据长度
+                int dataLen = Bcd2Int(tempBytes[4], tempBytes[5]);
+                byte[] reduceFAData = Reduce0xFAPair(tempBytes);
+                //去除多余FA后,实际数据不足有效数据长度,表示有粘包,仍非完整数据,等待下一轮接收数据再处理
+                if(reduceFAData.Length < dataLen + 2)
+                {
+                    innerLogger.Info("Insufficient data length");
+                    return;
+                }
+                //计算crc,若值对应不上,表示数据错误
+                ushort calculatorValue = HengshanCRC16.ComputeChecksum(reduceFAData.AsSpan(1,reduceFAData.Length - 3).ToArray());
+                byte highByte = reduceFAData[reduceFAData.Length - 2];
+                byte lowByte = reduceFAData[reduceFAData.Length - 1];
+                int crcValue = (highByte << 8) | lowByte;
+                if (calculatorValue != crcValue)
+                {
+                    innerLogger.Info($"crc value error,get value is {crcValue},calculator value is {calculatorValue}");
+                    return;
+                }
+
+                //获取到实际数据包,并将缓存数据删除
+                Message = reduceFAData;
                 var safe = OnMessageCut;
                 safe?.Invoke(this, null);
-                nextState = State.Uninitialized;
-                window.Clear();
-                //switch (nextState)
-                //{
-                //    case State.Uninitialized:
-                //        if (data.First() == STX)
-                //        {
-                //            window.NewSize = 6;
-                //            nextState = State.LengthReady;
-                //        }
-                //        else
-                //        {
-                //            OnInvalidMessageRead?.Invoke(this, new MessageCutterInvalidMessageReadEventArg()
-                //            {
-                //                Message = "invalid byte[0]: 0x" + data.First().ToString("x2") + ", will skip"
-                //            });
-                //            window.Clear();
-                //        }
-                //        break;
-
-                //    case State.LengthReady:
-
-                //        var countSTX = window.Count(b => b == STX);
-                //        if (countSTX > 1)
-                //        {
-                //            //Console.WriteLine($"0xFA count: {countSTX}");
-                //            innerLogger.Info($"0xFA count: {countSTX}");
-                //            int index = window.ToList().LastIndexOf(STX);
-
-
-                //            var tempArray = window.Skip(index).ToArray();
-                //            window.Clear();
-                //            nextState = State.Uninitialized;
-                //            Feed(tempArray);
-
-                //            return;
-
-
-                //        }
-
-
-
-                //        int bodyLen = window[4] * 10 + window[5];
-
-                //        if (bodyLen > 256 || bodyLen < 2)
-                //        {
-                //            var safe8 = this.OnInvalidMessageRead;
-                //            safe8?.Invoke(this, new MessageCutterInvalidMessageReadEventArg()
-                //            {
-                //                Message = "Message body length is not valid, len is: " + bodyLen
-                //            });
-                //            nextState = State.Uninitialized;
-                //            window.Clear();
-                //            window.NewSize = 1;
-                //            return;
-                //        }
-
-                //        window.NewSize += bodyLen;
-                //        nextState = State.BodyReady;
-
-                //        break;
-
-                //    case State.BodyReady:
-
-                //        window.NewSize = window.Skip(4).Take(2).ToArray().ToInt32() + 6 + 3;
-                //        nextState = State.CrcReady;
-                //        break;
-
-                //    case State.CrcReady:
-
-                //        var stxCount = window.Count(b => b == STX);
-                //        if (stxCount > 1)
-                //        {
-                //            //Console.WriteLine($"0xFA count: {stxCount}");
-                //            innerLogger.Info($"0xFA count: {stxCount}");
-                //            int length = window.Count;
-                //            if (window[length - 3] == 0xFF)
-                //            {
-                //                //Console.WriteLine("ETX exists, consider it a complete message");
-                //                innerLogger.Info("ETX exists, consider it a complete message");
-                //            }
-                //            else
-                //            {
-                //                int index = window.ToList().LastIndexOf(STX);
-
-                //                if (index + 2 <= window.Count - 1)
-                //                {
-                //                    byte trailingByte1 = window[index + 1];
-                //                    byte trailingByte2 = window[index + 2];
-
-                //                    if (trailingByte1 == trailingByte2 && trailingByte1 <= 6 && trailingByte1 > 0)
-                //                    {
-                //                        //Console.WriteLine("Possible mix of incompleted messages");
-                //                        innerLogger.Info("Possible mix of incompleted messages");
-                //                        var tempArray = window.Skip(index).ToArray();
-                //                        window.Clear();
-                //                        nextState = State.Uninitialized;
-                //                        Feed(tempArray);
-
-                //                        return;
-                //                    }
-                //                }
-                //            }
-                //        }
-
-                //        Message = window.ToArray();
-                //        var safe = OnMessageCut;
-                //        safe?.Invoke(this, null);
-                //        nextState = State.Uninitialized;
-                //        window.Clear();
-                //        break;
-                //    default:
-                //        throw new ArgumentOutOfRangeException();
-                //}
+                window.RemoveRange(0, tempBytes.Length);
             };
         }
 
         public void Feed(byte[] data)
         {
-            for (int i = 0; i < data.Length; i++)
-            {
-                window.Add(data[i]);
-            }
+            List<byte> list = new(data);
+            window.Add(list);
+            //for (int i = 0; i < data.Length; i++)
+            //{
+            //    window.Add(data[i]);
+            //}
         }
 
         private int Get0xFAPairCountInWindow(IEnumerable<byte> data)
@@ -183,32 +118,43 @@ namespace HengshanPaymentTerminal
             return (int)Math.Round(((double)(data.Count(w => w == 0xFA)) / 2), MidpointRounding.AwayFromZero);
         }
 
-        public int Reduce0xFAPair(IList<byte> target, int startIndex)
+        /// <summary>
+        /// 删除多余的FA,在接收到的一个完整数据包中,数据包头为FA,其余数据中每一个FA会替换为两个FA,这里要删除多余的fa来获取实际数据包
+        /// </summary>
+        /// <param name="data">原数据包</param>
+        /// <returns></returns>
+        public byte[] Reduce0xFAPair(byte[] data)
         {
-            int reducedCount = 0;
-            var faAppearedPositions = new List<int>();
-            for (int i = startIndex; i < target.Count; i++)
+            List<byte> list = new();
+            for (int index = 0; index < data.Length; index++)
             {
-                if (target[i] == 0xFA)
+                if (index < data.Length -1 && data[index] == STX && data[index + 1] == STX)
                 {
-                    if (i <= (target.Count - 2))
-                    {
-                        if (target[i + 1] == 0xFA)
-                        {
-                            faAppearedPositions.Add(i);
-                            i++;
-                        }
-                    }
+                    list.Add(STX);
+                    index++;
+                } 
+                else
+                {
+                    list.Add(data[index]);
                 }
             }
+            return list.ToArray();
+        }
 
-            for (int i = 0; i < faAppearedPositions.Count; i++)
-            {
-                target.RemoveAt(faAppearedPositions[i] - i);
-                reducedCount++;
-            }
+        public int Bcd2Int(byte byte1,byte byte2)
+        {
+            // 提取第一个字节的高四位和低四位  
+            int digit1 = (byte1 >> 4) & 0x0F; // 高四位  
+            int digit2 = byte1 & 0x0F;        // 低四位  
+
+            // 提取第二个字节的高四位和低四位  
+            int digit3 = (byte2 >> 4) & 0x0F; // 高四位  
+            int digit4 = byte2 & 0x0F;        // 低四位  
+
+            // 组合成一个整数  
+            int result = digit1 * 1000 + digit2 * 100 + digit3 * 10 + digit4;
 
-            return reducedCount;
+            return result;
         }
     }
 }

+ 84 - 0
HengshanPaymentTerminal/Test/CalculatorTest.cs

@@ -0,0 +1,84 @@
+using AutoMapper.Execution;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace HengshanPaymentTerminal.Test
+{
+    public class CalculatorTest
+    {
+        
+
+        [Fact]
+        public void crc16()
+        {
+            byte[] bytes = { 0x12,0x66,0xfb};
+            ushort value = HengshanCRC16.ComputeChecksum(bytes);
+            byte[] bytes1 = HengshanCRC16.ComputeChecksumToBytes(bytes);
+            Console.WriteLine($"CRC TEST RESULT:{value}");
+        }
+
+        [Fact]
+        public void testByte2Int()
+        {
+            int int1 = Bcd2Int(0x00, 0x00 );
+            int int2 = Bcd2Int(0x00, 0x01 );
+            int int3 = Bcd2Int(0x00, 0x09 );
+            int int4 = Bcd2Int(0x00, 0x10 );
+            int int5 = Bcd2Int(0x01, 0x10 );
+            int int6 = Bcd2Int(0x09, 0x10 );
+            int int7 = Bcd2Int(0x10, 0x10 );
+            int int8 = Bcd2Int(0x99, 0x99 );
+            Console.WriteLine();
+        }
+
+        public int Bcd2Int(byte byte1, byte byte2)
+        {
+            // 提取第一个字节的高四位和低四位  
+            int digit1 = (byte1 >> 4) & 0x0F; // 高四位  
+            int digit2 = byte1 & 0x0F;        // 低四位  
+
+            // 提取第二个字节的高四位和低四位  
+            int digit3 = (byte2 >> 4) & 0x0F; // 高四位  
+            int digit4 = byte2 & 0x0F;        // 低四位  
+
+            // 组合成一个整数  
+            int result = digit1 * 1000 + digit2 * 100 + digit3 * 10 + digit4;
+
+            return result;
+        }
+
+        [Fact]
+        public void testInt2Bytes()
+        {
+            byte[] byte1 = Int2Bytes(0);
+            byte[] byte2 = Int2Bytes(01);
+            byte[] byte3 = Int2Bytes(99);
+            byte[] byte4 = Int2Bytes(100);
+            byte[] byte5 = Int2Bytes(9999);
+            Console.WriteLine();
+        }
+        
+        public byte[] Int2Bytes(int number)
+        {
+            // 提取千位、百位、十位和个位  
+            int thousands = number / 1000;
+            int hundreds = (number / 100) % 10;
+            int tens = (number / 10) % 10;
+            int units = number % 10;
+
+            // 将千位和百位组合成一个字节(千位在高四位,百位在低四位)  
+            byte firstByte = (byte)((thousands * 16) + hundreds); // 乘以16相当于左移4位  
+
+            // 将十位和个位组合成一个字节(十位在高四位,个位在低四位)  
+            byte secondByte = (byte)((tens * 16) + units);
+
+            // 返回结果数组  
+            return new byte[] { firstByte, secondByte };
+        }
+    }
+}

+ 3 - 0
src/FccLife.Web/Core/database/MysqlDbContext.cs

@@ -8,6 +8,9 @@ namespace FccLite.Web.utils.database
 {
     public class MysqlDbContext:DbContext
     {
+        public MysqlDbContext() { }
+
+        [ActivatorUtilitiesConstructor]
         public MysqlDbContext(DbContextOptions<MysqlDbContext> options):base(options) { }
 
         public DbSet<FccStationInfo> FccStationInfos { get; set; }

+ 3 - 0
src/FccLife.Web/Services/FccStaionInfo/StationServiceImpl.cs

@@ -1,6 +1,7 @@
 using FccLite.Web.Domain.FccStationInfo.Input;
 using FccLite.Web.Domain.FccStationInfo.Output;
 using FccLite.Web.Repositories.FccStationInfo;
+using FccLite.Web.utils.database;
 using System.Text.Json;
 
 namespace FccLite.Web.Services.FccStaionInfo
@@ -10,11 +11,13 @@ namespace FccLite.Web.Services.FccStaionInfo
         static NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
 
         private readonly IStationRepository _stationRepository;
+
         public StationServiceImpl(IStationRepository stationRepository)
         {
             _stationRepository = stationRepository;
         }
 
+
         /// <summary>
         /// 分页查询站点信息
         /// </summary>