mirror of
https://gitee.com/ThingsGateway/ThingsGateway.git
synced 2025-10-21 03:01:28 +08:00
优化opcua质量戳提示;添加数据转换基础方法;TCP等待返回时默认断开连接立即返回
This commit is contained in:
@@ -2,8 +2,6 @@ using Mapster;
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
using NewLife.Reflection;
|
||||
|
||||
using Opc.Ua;
|
||||
using Opc.Ua.Server;
|
||||
|
||||
@@ -203,10 +201,18 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
if (initialItemValue != null)
|
||||
{
|
||||
var code = variable.quality == 192 ? StatusCodes.Good : StatusCodes.Bad;
|
||||
if (uaTag.Value != initialItemValue)
|
||||
ChangeNodeData(uaTag.NodeId.ToString(), initialItemValue, variable.changeTime);
|
||||
if (code == StatusCodes.Good)
|
||||
{
|
||||
ChangeNodeData(uaTag, initialItemValue, variable.changeTime);
|
||||
}
|
||||
|
||||
if (uaTag.StatusCode != code)
|
||||
uaTag.SetStatusCode(SystemContext, code, variable.changeTime);
|
||||
{
|
||||
uaTag.StatusCode = code;
|
||||
}
|
||||
uaTag.ClearChangeMasks(SystemContext, false);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,28 +234,22 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在服务器端直接更改对应数据节点的值,并通知客户端
|
||||
/// 在服务器端直接更改对应数据节点的值
|
||||
/// </summary>
|
||||
private void ChangeNodeData(string nodeId, object value, DateTime dateTime)
|
||||
private void ChangeNodeData(OPCUATag tag, object value, DateTime dateTime)
|
||||
{
|
||||
if (_idTags.ContainsKey(nodeId))
|
||||
object newValue;
|
||||
try
|
||||
{
|
||||
lock (Lock)
|
||||
{
|
||||
object newValue;
|
||||
try
|
||||
{
|
||||
newValue=Convert.ChangeType(value, _idTags[nodeId].NETDataType);
|
||||
}
|
||||
catch
|
||||
{
|
||||
newValue= value;
|
||||
}
|
||||
_idTags[nodeId].Value = newValue;
|
||||
_idTags[nodeId].Timestamp = dateTime;
|
||||
_idTags[nodeId].ClearChangeMasks(SystemContext, false);
|
||||
}
|
||||
newValue = Convert.ChangeType(value, tag.NETDataType);
|
||||
}
|
||||
catch
|
||||
{
|
||||
newValue = value;
|
||||
}
|
||||
tag.Value = newValue;
|
||||
tag.Timestamp = dateTime;
|
||||
//_idTags[nodeId].ClearChangeMasks(SystemContext, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -302,9 +302,10 @@ public class ThingsGatewayNodeManager : CustomNodeManager2
|
||||
variable.AccessLevel = level;
|
||||
variable.UserAccessLevel = level;
|
||||
variable.Historizing = variableRunTime.HisEnable;
|
||||
variable.StatusCode = StatusCodes.Good;
|
||||
variable.Timestamp = DateTime.UtcNow;
|
||||
variable.Value = Opc.Ua.TypeInfo.GetDefaultValue(variable.DataType, ValueRanks.Scalar, Server.TypeTree);
|
||||
var code = variableRunTime.Quality == 192 ? StatusCodes.Good : StatusCodes.Bad;
|
||||
variable.StatusCode = code;
|
||||
variable.Timestamp = variableRunTime.CollectTime;
|
||||
variable.OnWriteValue = OnWriteDataValue;
|
||||
if (parent != null)
|
||||
{
|
||||
|
@@ -60,6 +60,22 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="value">等待转化的数据</param>
|
||||
/// <returns>buffer数据</returns>
|
||||
byte[] GetBytes(short value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(short[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(ushort[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(int[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(uint[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(long[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(ulong[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(float[] value);
|
||||
/// <inheritdoc/>
|
||||
byte[] GetBytes(double[] value);
|
||||
|
||||
/// <summary>
|
||||
/// ushort变量转化缓存数据,一个ushort数据可以转为2个字节的Byte数组<br />
|
||||
@@ -151,6 +167,10 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="buffer">等待提取的缓存数据</param>
|
||||
/// <param name="offset">位的索引,注意:是从0开始的位索引,10则表示 buffer[1] 的第二位。</param>
|
||||
bool ToBoolean(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
bool[] ToBoolean(byte[] buffer, int offset, int len);
|
||||
|
||||
/// <inheritdoc/>
|
||||
byte ToByte(byte[] buffer, int offset);
|
||||
|
||||
@@ -164,7 +184,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>double对象</returns>
|
||||
double ToDouble(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
double[] ToDouble(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取short结果,需要指定起始的字节索引,按照字节为单位,一个short占用两个字节<br />
|
||||
/// </summary>
|
||||
@@ -172,7 +193,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>short对象</returns>
|
||||
short ToInt16(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
short[] ToInt16(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取int结果,需要指定起始的字节索引,按照字节为单位,一个int占用四个字节<br />
|
||||
/// </summary>
|
||||
@@ -180,6 +202,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>int对象</returns>
|
||||
int ToInt32(byte[] buffer, int offset);
|
||||
/// <inheritdoc/>
|
||||
int[] ToInt32(byte[] buffer, int offset, int len);
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中提取long结果,需要指定起始的字节索引,按照字节为单位,一个long占用八个字节<br />
|
||||
@@ -188,7 +212,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>long对象</returns>
|
||||
long ToInt64(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
long[] ToInt64(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取float结果,需要指定起始的字节索引,按照字节为单位,一个float占用四个字节<b />
|
||||
/// </summary>
|
||||
@@ -196,7 +221,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>float对象</returns>
|
||||
float ToSingle(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
float[] ToSingle(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取string结果,使用指定的编码将全部的缓存转为字符串<br />
|
||||
/// </summary>
|
||||
@@ -220,7 +246,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>ushort对象</returns>
|
||||
ushort ToUInt16(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
ushort[] ToUInt16(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取uint结果,需要指定起始的字节索引,按照字节为单位,一个uint占用四个字节<br />
|
||||
/// </summary>
|
||||
@@ -228,7 +255,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>uint对象</returns>
|
||||
uint ToUInt32(byte[] buffer, int offset);
|
||||
|
||||
/// <inheritdoc/>
|
||||
uint[] ToUInt32(byte[] buffer, int offset, int len);
|
||||
/// <summary>
|
||||
/// 从缓存中提取ulong结果,需要指定起始的字节索引,按照字节为单位,一个ulong占用八个字节<b />
|
||||
/// </summary>
|
||||
@@ -236,6 +264,8 @@ namespace ThingsGateway.Foundation
|
||||
/// <param name="offset">索引位置</param>
|
||||
/// <returns>ulong对象</returns>
|
||||
ulong ToUInt64(byte[] buffer, int offset);
|
||||
/// <inheritdoc/>
|
||||
ulong[] ToUInt64(byte[] buffer, int offset, int len);
|
||||
|
||||
#endregion ToValue
|
||||
}
|
||||
|
@@ -1,5 +1,7 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
namespace ThingsGateway.Foundation
|
||||
{
|
||||
/// <summary>
|
||||
@@ -84,6 +86,17 @@ namespace ThingsGateway.Foundation
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(short[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort value)
|
||||
@@ -95,43 +108,113 @@ namespace ThingsGateway.Foundation
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ushort[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(int[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(uint[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(long[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(ulong[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float value)
|
||||
{
|
||||
return ByteTransDataFormat4(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(float[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double value)
|
||||
{
|
||||
return ByteTransDataFormat8(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(double[] value)
|
||||
{
|
||||
byte[] numArray = new byte[value.Length * 2];
|
||||
for (int index = 0; index < value.Length; ++index)
|
||||
{
|
||||
byte[] bytes = GetBytes(value[index]);
|
||||
bytes.CopyTo(numArray, 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public byte[] GetBytes(string value)
|
||||
{
|
||||
@@ -412,5 +495,103 @@ namespace ThingsGateway.Foundation
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool[] ToBoolean(byte[] buffer, int offset, int len)
|
||||
{
|
||||
bool[] flagArray = new bool[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
flagArray[index] = buffer.GetBoolByIndex(offset + index);
|
||||
}
|
||||
return flagArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public double[] ToDouble(byte[] buffer, int offset, int len)
|
||||
{
|
||||
double[] numArray = new double[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToDouble(buffer, offset + 8 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public short[] ToInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
short[] numArray = new short[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToInt16(buffer, offset + 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int[] ToInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
int[] numArray = new int[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToInt32(buffer, offset + 4 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long[] ToInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
long[] numArray = new long[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToInt64(buffer, offset + 8 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
/// <inheritdoc/>
|
||||
public float[] ToSingle(byte[] buffer, int offset, int len)
|
||||
{
|
||||
float[] numArray = new float[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToSingle(buffer, offset + 4 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ushort[] ToUInt16(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ushort[] numArray = new ushort[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToUInt16(buffer, offset + 2 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public uint[] ToUInt32(byte[] buffer, int offset, int len)
|
||||
{
|
||||
uint[] numArray = new uint[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToUInt32(buffer, offset + 4 * index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong[] ToUInt64(byte[] buffer, int offset, int len)
|
||||
{
|
||||
ulong[] numArray = new ulong[len];
|
||||
for (int index = 0; index < len; ++index)
|
||||
{
|
||||
numArray[index] = ToUInt64(buffer, offset + 8* index);
|
||||
}
|
||||
return numArray;
|
||||
}
|
||||
}
|
||||
}
|
@@ -342,10 +342,9 @@ namespace TouchSocket.Sockets
|
||||
|
||||
private void BreakOut(string msg, bool manual)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
EasyLock.Lock();
|
||||
privateEasyLock.Lock();
|
||||
if (this.CanSend)
|
||||
{
|
||||
this.CanSend = false;
|
||||
@@ -359,7 +358,7 @@ namespace TouchSocket.Sockets
|
||||
}
|
||||
finally
|
||||
{
|
||||
EasyLock.UnLock();
|
||||
privateEasyLock.UnLock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -396,7 +395,7 @@ namespace TouchSocket.Sockets
|
||||
{
|
||||
try
|
||||
{
|
||||
EasyLock.Lock();
|
||||
privateEasyLock.Lock();
|
||||
|
||||
if (this.CanSend)
|
||||
{
|
||||
@@ -480,7 +479,7 @@ namespace TouchSocket.Sockets
|
||||
|
||||
finally
|
||||
{
|
||||
EasyLock.UnLock();
|
||||
privateEasyLock.UnLock();
|
||||
|
||||
}
|
||||
|
||||
@@ -495,7 +494,7 @@ namespace TouchSocket.Sockets
|
||||
return this;
|
||||
}
|
||||
|
||||
private EasyLock EasyLock { get; set; } = new();
|
||||
private EasyLock privateEasyLock { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 异步连接服务器
|
||||
@@ -504,7 +503,7 @@ namespace TouchSocket.Sockets
|
||||
{
|
||||
try
|
||||
{
|
||||
await EasyLock.LockAsync();
|
||||
await privateEasyLock.LockAsync();
|
||||
|
||||
if (this.CanSend)
|
||||
{
|
||||
@@ -614,7 +613,7 @@ namespace TouchSocket.Sockets
|
||||
}
|
||||
finally
|
||||
{
|
||||
EasyLock.UnLock();
|
||||
privateEasyLock.UnLock();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@@ -14,6 +14,7 @@ namespace ThingsGateway.Foundation
|
||||
/// <returns></returns>
|
||||
public static IWaitingClient<TClient> GetTGWaitingClient<TClient>(this TClient client, WaitingOptions waitingOptions) where TClient : IClient, IDefaultSender, ISender
|
||||
{
|
||||
waitingOptions.BreakTrigger = true;
|
||||
TGWaitingClient<TClient> waitingClient = new TGWaitingClient<TClient>(client, waitingOptions);
|
||||
return waitingClient;
|
||||
}
|
||||
|
@@ -19,13 +19,28 @@ namespace ThingsGateway.Web.Foundation
|
||||
{
|
||||
IServiceScopeFactory _scopeFactory;
|
||||
/// <inheritdoc cref="CollectDbInfoControler"/>
|
||||
public CollectDbInfoControler(IServiceScopeFactory scopeFactory, IVariableService variableService)
|
||||
public CollectDbInfoControler(IServiceScopeFactory scopeFactory, IVariableService variableService, ICollectDeviceService collectDeviceService)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
_variableService = variableService;
|
||||
_collectDeviceService = collectDeviceService;
|
||||
}
|
||||
|
||||
IVariableService _variableService { get; set; }
|
||||
ICollectDeviceService _collectDeviceService { get; set; }
|
||||
/// <summary>
|
||||
/// 获取采集设备信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("collectDeviceList")]
|
||||
[Description("获取采集设备信息")]
|
||||
public async Task<SqlSugarPagedList<CollectDevice>> GetCollectDeviceList([FromQuery] CollectDevicePageInput input)
|
||||
{
|
||||
var data = await _collectDeviceService.PageAsync(input);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取变量信息
|
||||
/// </summary>
|
||||
@@ -38,8 +53,6 @@ namespace ThingsGateway.Web.Foundation
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -108,7 +108,7 @@ public class CollectVariableRunTime : CollectDeviceVariable
|
||||
time = dateTime;
|
||||
}
|
||||
CollectTime = DateTime.UtcNow;
|
||||
if (data?.ToString() != _value?.ToString() && LastSetValue?.ToString() != data?.ToString())
|
||||
if (data?.ToString() != _value?.ToString() && LastSetValue?.ToString() != data?.ToString()||qualityChanged)
|
||||
{
|
||||
ChangeTime = DateTime.UtcNow;
|
||||
if (Quality == 192)
|
||||
@@ -151,12 +151,30 @@ public class CollectVariableRunTime : CollectDeviceVariable
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
[AdaptIgnore]
|
||||
public VariableCahngeEventHandler VariableValueChange { get; set; }
|
||||
|
||||
private int quality;
|
||||
private bool qualityChanged;
|
||||
/// <summary>
|
||||
/// 质量戳
|
||||
/// </summary>
|
||||
[Description("质量戳")]
|
||||
[OrderTable(Order = 5)]
|
||||
public int Quality { get; private set; }
|
||||
public int Quality { get => quality; private set
|
||||
{
|
||||
if (quality != value)
|
||||
{
|
||||
quality = value;
|
||||
qualityChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
qualityChanged = false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region LoadSourceRead
|
||||
|
Reference in New Issue
Block a user