first commit
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
using System;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
public class Challenge
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 挑战件条码
|
||||
/// </summary>
|
||||
public String ChallengeBarCode { get; set; }
|
||||
/// <summary>
|
||||
/// 电芯信息
|
||||
/// </summary>
|
||||
public String CodeMessage { get; set; }
|
||||
/// <summary>
|
||||
/// 焊前/焊后CCD
|
||||
/// </summary>
|
||||
public String WeldingCCD { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 通信设备实体类
|
||||
/// </summary>
|
||||
public class Device
|
||||
{
|
||||
/// <summary>
|
||||
/// IP地址
|
||||
/// </summary>
|
||||
public string IPAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 端口
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// PLC类型
|
||||
/// </summary>
|
||||
public string PLCType { get; set; }
|
||||
/// <summary>
|
||||
/// 当前设备的连接状态
|
||||
/// </summary>
|
||||
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否是首次连接
|
||||
/// </summary>
|
||||
|
||||
public bool IsFirstConnect { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 重连周期
|
||||
/// </summary>
|
||||
|
||||
public int ReConnectTime { get; set; } = 2000;
|
||||
|
||||
/// <summary>
|
||||
/// 休眠时间
|
||||
/// </summary>
|
||||
|
||||
public int SleepTime { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 大小端
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public int DataFormat { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 出错次数
|
||||
/// </summary>
|
||||
public int ErrorTimes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 容错次数
|
||||
/// </summary>
|
||||
public int AllowErrorTimes { get; set; } = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 多线程取消源标志位
|
||||
/// </summary>
|
||||
public CancellationTokenSource Cts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 计时器
|
||||
/// </summary>
|
||||
|
||||
public Stopwatch Stopwatch { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 所有归档变量的集合
|
||||
/// </summary>
|
||||
|
||||
public List<Variable> StoreVarList { get; set; } = new List<Variable>();
|
||||
|
||||
/// <summary>
|
||||
/// 按工位读取
|
||||
/// </summary>
|
||||
|
||||
public List<Group> WorkVarList { get; set; } = new List<Group>();
|
||||
/// <summary>
|
||||
/// 通信组集合
|
||||
/// </summary>
|
||||
public List<Group> GroupList { get; set; } = new List<Group>();
|
||||
/// <summary>
|
||||
/// 所有变量的集合
|
||||
/// </summary>
|
||||
public List<Variable> VarList { get; set; } = new List<Variable>();
|
||||
|
||||
/// <summary>
|
||||
/// 所有变量名称与值的集合
|
||||
/// </summary>
|
||||
public Dictionary<string, object> CurrentValue { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// 定义报警触发和消除事件
|
||||
/// </summary>
|
||||
public event Action<bool, Variable> AlarmTrigEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 变量初始化
|
||||
/// </summary>
|
||||
public void Init()
|
||||
{
|
||||
foreach (var gp in GroupList)
|
||||
{
|
||||
|
||||
if (gp.IsTiggerRead)
|
||||
{
|
||||
WorkVarList.Add(gp);
|
||||
}
|
||||
foreach (var variable in gp.VarList)
|
||||
{
|
||||
if (!gp.IsTiggerRead)
|
||||
{
|
||||
VarList.Add(variable);
|
||||
|
||||
|
||||
if (CurrentValue.ContainsKey(variable.VarName))
|
||||
{
|
||||
CurrentValue[variable.VarName] = "NA";
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentValue.Add(variable.VarName, "NA");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 索引器,通过键名获取到数据
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
[JsonIgnore]
|
||||
public object this[string key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (CurrentValue.ContainsKey(key))
|
||||
{
|
||||
return CurrentValue[key];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实时更新
|
||||
/// </summary>
|
||||
/// <param name="variable"></param>
|
||||
public void Update(Variable variable)
|
||||
{
|
||||
//更新处理
|
||||
if (CurrentValue.ContainsKey(variable.VarName))
|
||||
{
|
||||
CurrentValue[variable.VarName] = variable.VarValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentValue.Add(variable.VarName, variable.VarValue);
|
||||
}
|
||||
|
||||
//报警处理
|
||||
if (variable.HighAlarmEnable || variable.LowAlarmEnable)
|
||||
{
|
||||
float compareValue = 0.0f;
|
||||
|
||||
if (variable.DataType.ToLower() == "bool")
|
||||
{
|
||||
compareValue = Convert.ToBoolean(variable.VarValue) ? 1.0f : 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
compareValue = Convert.ToSingle(variable.VarValue);
|
||||
}
|
||||
|
||||
int compareResult = 0;
|
||||
//高报警时,触发事件
|
||||
if (variable.HighAlarmEnable)
|
||||
{
|
||||
compareResult = Compare(compareValue, variable.HighAlarmValue, variable.HighAlarmCacheValue, true);
|
||||
|
||||
if (compareResult != 0)
|
||||
{
|
||||
//通过事件做通知
|
||||
|
||||
OnAlarmAckEvent(variable, new AlarmEventArgs()
|
||||
{
|
||||
Name = variable.VarName,
|
||||
CurrentValue = variable.VarValue.ToString(),
|
||||
SetValue = variable.HighAlarmValue.ToString(),
|
||||
AlarmNote = variable.HighAlarmNote,
|
||||
IsTrigger = compareResult == 1
|
||||
});
|
||||
}
|
||||
|
||||
variable.HighAlarmCacheValue = compareValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
compareResult = Compare(compareValue, variable.LowAlarmValue, variable.LowAlarmCacheValue, false);
|
||||
|
||||
if (compareResult != 0)
|
||||
{
|
||||
//通过事件做通知
|
||||
|
||||
OnAlarmAckEvent(variable, new AlarmEventArgs()
|
||||
{
|
||||
Name = variable.VarName,
|
||||
CurrentValue = variable.VarValue.ToString(),
|
||||
SetValue = variable.LowAlarmValue.ToString(),
|
||||
AlarmNote = variable.LowAlarmNote,
|
||||
IsTrigger = compareResult == 1
|
||||
});
|
||||
|
||||
}
|
||||
variable.LowAlarmCacheValue = compareValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 报警触发的事件
|
||||
/// </summary>
|
||||
//public event AlarmTriggerEventDelegate AlarmTriggerEvent;
|
||||
|
||||
/// <summary>
|
||||
/// 触发事件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void OnAlarmAckEvent(object sender, AlarmEventArgs e)
|
||||
{
|
||||
//AlarmTriggerEvent?.Invoke(sender, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 报警比较
|
||||
/// </summary>
|
||||
/// <param name="current">当前值</param>
|
||||
/// <param name="set">设置值</param>
|
||||
/// <param name="last">缓存值</param>
|
||||
/// <param name="isPositive">上升沿还是下降沿</param>
|
||||
/// <returns>比较结果,1表示触发,-1表示消除,0表示无变化</returns>
|
||||
private int Compare(float current, float set, float last, bool isPositive)
|
||||
{
|
||||
if (isPositive)
|
||||
{
|
||||
if (current >= set && last < set)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (current < set && last >= set)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (current <= set && last > set)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (current > set && last <= set)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class AlarmEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 变量名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前值
|
||||
/// </summary>
|
||||
public string CurrentValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报警说明
|
||||
/// </summary>
|
||||
public string AlarmNote { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 报警设定值
|
||||
/// </summary>
|
||||
public string SetValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否为触发
|
||||
/// </summary>
|
||||
public bool IsTrigger { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 所有窗体枚举,小于临界窗体的为固定窗体,不执行关闭
|
||||
/// </summary>
|
||||
public enum FormNames
|
||||
{
|
||||
集中监控,
|
||||
数据监控,
|
||||
日志报警,
|
||||
临界窗体,
|
||||
数据分析,
|
||||
数据追溯,
|
||||
参数设置,
|
||||
系统设置,
|
||||
用户管理
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using MiniExcelLibs.Attributes;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 通信组实体类
|
||||
/// </summary>
|
||||
public class Group
|
||||
{
|
||||
/// <summary>
|
||||
///通信组名称
|
||||
/// </summary>
|
||||
public string GroupName { get; set; }
|
||||
/// <summary>
|
||||
/// 起始地址
|
||||
/// </summary>
|
||||
public string Start { get; set; }
|
||||
/// <summary>
|
||||
/// 长度
|
||||
/// </summary>
|
||||
public ushort Length { get; set; }
|
||||
/// <summary>
|
||||
/// 是否为触发读取
|
||||
/// </summary>
|
||||
public bool IsTiggerRead { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否需要反馈结果到PLC
|
||||
/// </summary>
|
||||
public bool IsFeedbackPlc { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用
|
||||
/// </summary>
|
||||
public bool IsActive { get; set; }
|
||||
/// <summary>
|
||||
/// 备注说明
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
/// <summary>
|
||||
/// 变量集合
|
||||
/// </summary>
|
||||
[ExcelIgnore]
|
||||
public List<Variable> VarList { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class ParamBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ParamBase()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 序号
|
||||
/// </summary>
|
||||
public System.Int32? fNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 参数名称
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public System.String ParaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 备注
|
||||
/// </summary>
|
||||
public System.String Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
public class ParamList
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public System.String ModelName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public System.String ParaName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String ParaValueMin { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String ParaValueMax { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String Uint { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String Remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.DateTime? UpdateTime { get; set; } = System.DateTime.Now;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
public class ProductModel
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public System.String ModelName { get; set; }
|
||||
/// <summary>
|
||||
/// 物料编码
|
||||
/// </summary>
|
||||
public System.String MaterialCode { get; set; }
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String Remark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 产品型号参数范围
|
||||
/// </summary>
|
||||
public class ProductModelParam
|
||||
{
|
||||
/// <summary>
|
||||
/// 入壳压力1MAX
|
||||
/// </summary>
|
||||
public decimal PrePressure1Max { set; get; }
|
||||
/// <summary>
|
||||
/// 入壳压力2MAX
|
||||
/// </summary>
|
||||
public decimal PrePressure2Max { set; get; }
|
||||
/// <summary>
|
||||
/// 入壳压力3MAX
|
||||
/// </summary>
|
||||
public decimal PrePressure3Max { set; get; }
|
||||
/// <summary>
|
||||
/// 入壳压力下限
|
||||
/// </summary>
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using SqlSugar;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录实体类型
|
||||
/// </summary>
|
||||
public class SysAdmin
|
||||
{
|
||||
[SugarColumn(IsPrimaryKey = true, IsIgnore = true)]
|
||||
public int LoginId { get; set; }
|
||||
public string LoginName { get; set; }
|
||||
public string LoginPwd { get; set; }
|
||||
public string LoginUid { get; set; }
|
||||
public string LoginLevel { get; set; }
|
||||
public bool SystemLog { get; set; }
|
||||
public bool CpkData { get; set; }
|
||||
public bool HistoryData { get; set; }
|
||||
public bool ParamSet { get; set; }
|
||||
public bool SystemSet { get; set; }
|
||||
public bool UserManage { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
public class SysConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 开机自动启动
|
||||
/// </summary>
|
||||
public bool AutoStart { get; set; }
|
||||
/// <summary>
|
||||
///启动自动登录
|
||||
/// </summary>
|
||||
public bool AutoLogin { get; set; }
|
||||
/// <summary>
|
||||
///无操作自动锁屏
|
||||
/// </summary>
|
||||
public bool AutoLock { get; set; }
|
||||
/// <summary>
|
||||
///锁屏间隙时间,单位是分钟
|
||||
/// </summary>
|
||||
public int LockPeriod { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///无操作自动锁屏
|
||||
/// </summary>
|
||||
public bool AutoQieHuanM { get; set; }
|
||||
/// <summary>
|
||||
///锁屏间隙时间,单位是分钟
|
||||
/// </summary>
|
||||
public int QieHuanMPeriod { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
///曲线显示数量
|
||||
/// </summary>
|
||||
public int ShowSeriesCount { get; set; }
|
||||
/// <summary>
|
||||
/// 开启刷卡模式
|
||||
/// </summary>
|
||||
public bool SwipeCardMode { get; set; }
|
||||
/// <summary>
|
||||
/// MES/非MES模式切换
|
||||
/// </summary>
|
||||
public bool MesModeSwitching { get; set; }
|
||||
/// <summary>
|
||||
/// 切屏
|
||||
/// </summary>
|
||||
public bool ScreenCutting { get; set; }
|
||||
/// <summary>
|
||||
/// 获取MES参数
|
||||
/// </summary>
|
||||
public bool GetMesParam { get; set; }
|
||||
/// <summary>
|
||||
/// 切换强制OK模式
|
||||
/// </summary>
|
||||
public bool OKSwitching { get; set; }
|
||||
/// <summary>
|
||||
/// 线程耗时日志保存
|
||||
/// </summary>
|
||||
public bool SaveThreadTime { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
public class SysLog
|
||||
{
|
||||
/// <summary>
|
||||
/// 插入时间
|
||||
/// </summary>
|
||||
public string InsertTime { get; set; }
|
||||
/// <summary>
|
||||
/// 报警类型
|
||||
/// </summary>
|
||||
public string LogType { get; set; }
|
||||
/// <summary>
|
||||
/// 日志信息
|
||||
/// </summary>
|
||||
public string Note { get; set; }
|
||||
/// <summary>
|
||||
/// 操作人员
|
||||
/// </summary>
|
||||
public string Operater { get; set; }
|
||||
/// <summary>
|
||||
/// 变量名称
|
||||
/// </summary>
|
||||
public string VarName { get; set; }
|
||||
/// <summary>
|
||||
/// 报警设置值
|
||||
/// </summary>
|
||||
public string AlarmSet { get; set; }
|
||||
/// <summary>
|
||||
/// 报警值
|
||||
/// </summary>
|
||||
public string AlarmValue { get; set; }
|
||||
/// <summary>
|
||||
/// 报警类型
|
||||
/// </summary>
|
||||
public string AlarmType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using MiniExcelLibs.Attributes;
|
||||
|
||||
namespace JinYuan.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// 变量属性类
|
||||
/// </summary>
|
||||
public class Variable
|
||||
{
|
||||
/// <summary>
|
||||
/// 变量名称
|
||||
/// </summary>
|
||||
public string VarName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 变量地址
|
||||
/// </summary>
|
||||
public string VarAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 起始索引
|
||||
/// </summary>
|
||||
public string Start { get; set; }
|
||||
/// <summary>
|
||||
/// 数据类型
|
||||
/// </summary>
|
||||
public string DataType { get; set; }
|
||||
/// <summary>
|
||||
/// 偏移或长度
|
||||
/// </summary>
|
||||
public int OffsetOrLenght { get; set; }
|
||||
/// <summary>
|
||||
/// 所属通信组名称
|
||||
/// </summary>
|
||||
public string GroupName { get; set; }
|
||||
/// <summary>
|
||||
/// 备注说明
|
||||
/// </summary>
|
||||
public string Remark { get; set; }
|
||||
/// <summary>
|
||||
/// 是否上升沿报警
|
||||
/// </summary>
|
||||
public bool PosAlarm { get; set; }
|
||||
/// <summary>
|
||||
/// 是否下降沿报警
|
||||
/// </summary>
|
||||
public bool NegAlarm { get; set; }
|
||||
/// <summary>
|
||||
/// 转换系数
|
||||
/// </summary>
|
||||
public float Scale { get; set; } = 1.0f;
|
||||
/// <summary>
|
||||
/// 偏移值
|
||||
/// </summary>
|
||||
public float Offset { get; set; } = 0.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 变量的值
|
||||
/// </summary>
|
||||
[ExcelIgnore]
|
||||
public object VarValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 高报警启用
|
||||
/// </summary>
|
||||
public bool HighAlarmEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 高报警设定值
|
||||
/// </summary>
|
||||
public float HighAlarmValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 高报警说明
|
||||
/// </summary>
|
||||
public string HighAlarmNote { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 高报警缓存值
|
||||
/// </summary>
|
||||
[ExcelIgnore]
|
||||
public float HighAlarmCacheValue { get; set; }
|
||||
/// <summary>
|
||||
/// 低报警启用
|
||||
/// </summary>
|
||||
public bool LowAlarmEnable { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 低报警设定值
|
||||
/// </summary>
|
||||
public float LowAlarmValue { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 低报警说明
|
||||
/// </summary>
|
||||
public string LowAlarmNote { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 低报警缓存值
|
||||
/// </summary>
|
||||
[ExcelIgnore]
|
||||
public float LowAlarmCacheValue { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user