简单的修改

This commit is contained in:
2025-12-02 17:27:09 +08:00
parent 4b98b61f10
commit e25d344f8a
7 changed files with 116 additions and 26 deletions

View File

@@ -16,37 +16,44 @@ namespace FATrace.Model
public long Id { get; set; } public long Id { get; set; }
/// <summary> /// <summary>
/// 业务条码/编号(用于与 OEMRawUse/VideoAction 关联)。 /// 业务条码/编号
/// 内袋二维码
/// </summary> /// </summary>
[Column(StringLength = 100, IsNullable = false)] [Column(StringLength = 100, IsNullable = false)]
public string? Code { get; set; } public string? Code { get; set; }
/// <summary> /// <summary>
/// 原料名称 /// 原料名称
/// </summary> /// </summary>
[Column(StringLength = 100, IsNullable = false)] [Column(StringLength = 100, IsNullable = false)]
public string? RawName { get; set; } public string? RawName { get; set; }
/// <summary> /// <summary>
/// 操作用户标识。 /// 原料条码
/// </summary>
[Column(StringLength = 100, IsNullable = false)]
public string? RawCode { get; set; }
/// <summary>
/// 操作用户标识
/// </summary> /// </summary>
[Column(StringLength = 100, IsNullable = false)] [Column(StringLength = 100, IsNullable = false)]
public string? User { get; set; } public string? User { get; set; }
/// <summary> /// <summary>
/// 任务状态Pending/Running/Completed/Failed/Canceled /// 任务状态Pending/Running/Completed/Failed/Canceled
/// </summary> /// </summary>
[Column(IsNullable = false)] [Column(IsNullable = false)]
public TaskStatus Status { get; set; } = TaskStatus.Pending; public TaskStatus Status { get; set; } = TaskStatus.Pending;
/// <summary> /// <summary>
/// 下载进度 0-100 /// 下载进度 0-100
/// </summary> /// </summary>
[Column(IsNullable = false)] [Column(IsNullable = false)]
public short Progress { get; set; } = 0; public short Progress { get; set; } = 0;
/// <summary> /// <summary>
/// 目标视频保存路径(生成的本地文件全路径) /// 目标视频保存路径(生成的本地文件全路径)
/// </summary> /// </summary>
[Column(StringLength = 200)] [Column(StringLength = 200)]
public string? VideoFilePath { get; set; } public string? VideoFilePath { get; set; }
@@ -58,33 +65,34 @@ namespace FATrace.Model
public string? Error { get; set; } public string? Error { get; set; }
/// <summary> /// <summary>
/// 已尝试次数(每次 Running 前加一) /// 已尝试次数(每次 Running 前加一)
/// </summary> /// </summary>
[Column(IsNullable = false)] [Column(IsNullable = false)]
public int TryCount { get; set; } = 0; public int TryCount { get; set; } = 0;
/// <summary> /// <summary>
/// NVR 下载的开始时间(默认当前时间 - 5 分钟)。 /// NVR 下载的开始时间(默认当前时间 - 30秒
/// </summary> /// </summary>
[Column(IsNullable = false)] [Column(IsNullable = false)]
public DateTime NvrStartTime { get; set; } public DateTime NvrStartTime { get; set; }
/// <summary> /// <summary>
/// NVR 下载的结束时间(默认当前时间) /// NVR 下载的结束时间(默认当前时间)
/// </summary> /// </summary>
[Column(IsNullable = false)] [Column(IsNullable = false)]
public DateTime NvrEndTime { get; set; } public DateTime NvrEndTime { get; set; }
/// <summary> /// <summary>
/// 创建时间 /// 创建时间
/// </summary> /// </summary>
[Column(ServerTime = DateTimeKind.Local, CanUpdate = true)] [Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
public DateTime CreateTime { get; set; } public DateTime CreateTime { get; set; }
/// <summary> /// <summary>
/// 最近一次更新时间 /// 最近一次更新时间
/// </summary> /// </summary>
[Column(ServerTime = DateTimeKind.Local, CanUpdate = true)] [Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
public DateTime UpdateTime { get; set; } public DateTime UpdateTime { get; set; }
} }
} }

View File

@@ -26,10 +26,16 @@ namespace FATrace.Model
[Column(Name = "RawName", IsNullable = false, StringLength = 100)] [Column(Name = "RawName", IsNullable = false, StringLength = 100)]
public string? RawName{ get; set; } public string? RawName{ get; set; }
/// <summary>
/// 原料条码
/// </summary>
[Column(StringLength = 100, IsNullable = false)]
public string? RawCode { get; set; }
/// <summary> /// <summary>
/// 视频链接 /// 视频链接
/// </summary> /// </summary>
[Column(Name = "VideoUrl", IsNullable = false, StringLength = 256)] [Column(Name = "VideoUrl", IsNullable = false, StringLength = 500)]
public string? VideoUrl{ get; set; } public string? VideoUrl{ get; set; }
/// <summary> /// <summary>
@@ -60,6 +66,7 @@ namespace FATrace.Model
/// ///////////////////////////////////////////导航属性 LIN 一对一/////////////////////////////////////////////////////// /// ///////////////////////////////////////////导航属性 LIN 一对一///////////////////////////////////////////////////////
/// </summary> /// </summary>
public long VideoActionId { get; set; } // 外键字段,必要 public long VideoActionId { get; set; } // 外键字段,必要
/// <summary> /// <summary>
/// 视频信息 /// 视频信息
/// </summary> /// </summary>

View File

@@ -8,27 +8,27 @@ namespace FATrace.Model
public enum TaskStatus public enum TaskStatus
{ {
/// <summary> /// <summary>
/// 待处理(已入队但尚未开始) /// 待处理(已入队但尚未开始)
/// </summary> /// </summary>
Pending = 0, Pending = 0,
/// <summary> /// <summary>
/// 运行中(正在处理) /// 运行中(正在处理)
/// </summary> /// </summary>
Running = 1, Running = 1,
/// <summary> /// <summary>
/// 已完成(处理成功) /// 已完成(处理成功)
/// </summary> /// </summary>
Completed = 2, Completed = 2,
/// <summary> /// <summary>
/// 失败(处理过程中出现错误) /// 失败(处理过程中出现错误)
/// </summary> /// </summary>
Failed = 3, Failed = 3,
/// <summary> /// <summary>
/// 已取消(由用户或系统取消处理) /// 已取消(由用户或系统取消处理)
/// </summary> /// </summary>
Canceled = 4 Canceled = 4
} }

View File

@@ -8,6 +8,8 @@
<add key="PLCIP" value="127.0.0.1" /> <add key="PLCIP" value="127.0.0.1" />
<add key="PLCPort" value="6000" /> <add key="PLCPort" value="6000" />
<add key="PLCScan" value="600" /> <add key="PLCScan" value="600" />
<add key="PDAScanCode" value="D1000" />
<add key="DownloadTaskMaxRetry" value="3" />
<add key="NVRIP" value="192.168.0.15" /> <add key="NVRIP" value="192.168.0.15" />
<add key="NVRPort" value="8000" /> <add key="NVRPort" value="8000" />
<add key="NVRUserName" value="admin" /> <add key="NVRUserName" value="admin" />
@@ -22,5 +24,5 @@
<add key="JellyfinPollIntervalMs" value="5000" /> <add key="JellyfinPollIntervalMs" value="5000" />
<add key="JellyfinPollMaxWaitMs" value="600000" /> <add key="JellyfinPollMaxWaitMs" value="600000" />
</appSettings> </appSettings>
</configuration> </configuration>

View File

@@ -42,6 +42,11 @@ namespace FATrace.OEMApp
InitializeComponent(); InitializeComponent();
} }
/// <summary>
/// PLC数据服务
/// </summary>
private PLCDataService PLCDataService { get; set; }
/// <summary> /// <summary>
/// 主窗体加载: /// 主窗体加载:
/// - 初始化海康客户端与基础配置(日志目录与保存路径) /// - 初始化海康客户端与基础配置(日志目录与保存路径)
@@ -61,6 +66,10 @@ namespace FATrace.OEMApp
//HkCameraClient.NVR_Port = ConfigHelper.GetValue("NVRPort"); //HkCameraClient.NVR_Port = ConfigHelper.GetValue("NVRPort");
//HkCameraClient.NVR_UserName = ConfigHelper.GetValue("NVRUserName"); //HkCameraClient.NVR_UserName = ConfigHelper.GetValue("NVRUserName");
PLCDataService = new PLCDataService();
PLCDataService.PlcConnectedEventHandler += PLCDataService_PlcConnectedEventHandler;
PLCDataService.ScanCodeEventHandler += PLCDataService_ScanCodeEventHandler;
HkCameraClient.NVRVideoSavePath = ConfigHelper.GetValue("NVRVideoSavePath"); HkCameraClient.NVRVideoSavePath = ConfigHelper.GetValue("NVRVideoSavePath");
//NVR登录 //NVR登录
NVRLogin(); NVRLogin();
@@ -109,6 +118,26 @@ namespace FATrace.OEMApp
} }
} }
/// <summary>
/// PLC数据服务扫描条码
/// </summary>
/// <param name="sender"></param>
/// <param name="Code"></param>
private void PLCDataService_ScanCodeEventHandler(object? sender, string Code)
{
}
/// <summary>
/// PLC数据服务PLC连接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void PLCDataService_PlcConnectedEventHandler(object? sender, string e)
{
}
private void NVRLogin() private void NVRLogin()
{ {
HkCameraClient.NVR_IP = ConfigHelper.GetValue("NVRIP"); HkCameraClient.NVR_IP = ConfigHelper.GetValue("NVRIP");

View File

@@ -62,11 +62,12 @@ namespace FATrace.OEMApp.Services
var maxRetry = ConfigHelper.GetIntOrDefault("DownloadTaskMaxRetry", 3); var maxRetry = ConfigHelper.GetIntOrDefault("DownloadTaskMaxRetry", 3);
db.Update<DownloadTask>() db.Update<DownloadTask>()
.Set(a => a.Status, TaskStatus.Pending) .Set(a => a.Status, TaskStatus.Pending)
.Set(a => a.Error, null) .Set(a => a.Error, "")
.Set(a => a.Progress, 0) .Set(a => a.Progress, 0)
.Set(a => a.UpdateTime, DateTime.Now) .Set(a => a.UpdateTime, DateTime.Now)
.Where(a => a.Status == TaskStatus.Failed && a.TryCount < maxRetry) .Where(a => a.Status == TaskStatus.Failed && a.TryCount < maxRetry)
.ExecuteAffrows(); .ExecuteAffrows();
} }
catch { } catch { }
_cts = new CancellationTokenSource(); _cts = new CancellationTokenSource();
@@ -125,9 +126,9 @@ namespace FATrace.OEMApp.Services
} }
/// <summary> /// <summary>
/// 后台主循环:定期拉取最早的 Pending 任务并顺序处理 /// 后台主循环:定期拉取最早的 Pending 任务并顺序处理
/// </summary> /// </summary>
/// <param name="token">取消令牌</param> /// <param name="token">取消令牌</param>
private async Task RunAsync(CancellationToken token) private async Task RunAsync(CancellationToken token)
{ {
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
@@ -211,8 +212,9 @@ namespace FATrace.OEMApp.Services
.ExecuteAffrowsAsync(); .ExecuteAffrowsAsync();
// 事件 -> TCS // 事件 -> TCS
// 订阅两个事件:进度与完成。进度事件写回数据库;完成事件用于唤醒等待 // 订阅两个事件:进度与完成。进度事件写回数据库;完成事件用于唤醒等待
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously); var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
void OnProgress(object? s, short p) void OnProgress(object? s, short p)
{ {
try try

View File

@@ -19,12 +19,17 @@ namespace FATrace.OEMApp.Services
public PLCDataService() public PLCDataService()
{ {
PLCLinkInitial(); PLCLinkInitial();
StartPlcScan(); StartPlcScan();
PadCodeAddress= ConfigHelper.GetStringOrDefault("PDAScanCode", "D1050");
} }
/// <summary>
/// PAD地址
/// </summary>
private string PadCodeAddress { get; set; }
/// <summary> /// <summary>
/// 扫码事件 /// 扫码事件
/// </summary> /// </summary>
@@ -53,11 +58,11 @@ namespace FATrace.OEMApp.Services
{ {
if (value) if (value)
{ {
PlcConnectedEventHandler.Invoke(this, "OK"); if (PlcConnectedEventHandler != null) PlcConnectedEventHandler.Invoke(this, "OK");
} }
else else
{ {
PlcConnectedEventHandler.Invoke(this, "NG"); if (PlcConnectedEventHandler != null) PlcConnectedEventHandler.Invoke(this, "NG");
} }
_PlcConnected = value; _PlcConnected = value;
} }
@@ -65,6 +70,37 @@ namespace FATrace.OEMApp.Services
} }
private string _ScanCode = string.Empty;
/// <summary>
/// 扫描结果
/// </summary>
public string ScanCode
{
get { return _ScanCode; }
set
{
if (_ScanCode != value)
{
if (!string.IsNullOrEmpty(value))
{
if (ScanCodeEventHandler != null) ScanCodeEventHandler.Invoke(this, value);
}
else
{
Logger.Error($"PLC条码数据为空: 数据改变但是数据为空");
}
_ScanCode = value;
}
}
}
/// <summary>
/// 扫描结果
/// </summary>
private OperateResult<string> OperateResultPDAScanCode { get; set; }
// 扫描控制 // 扫描控制
private CancellationTokenSource? _plcScanCts; private CancellationTokenSource? _plcScanCts;
private Task? _plcScanTask; private Task? _plcScanTask;
@@ -175,6 +211,12 @@ namespace FATrace.OEMApp.Services
PLCLinkInitial(); PLCLinkInitial();
} }
//内包扫码
OperateResultPDAScanCode = KeyencePlcMcNet!.ReadString(PadCodeAddress, 40);
if (OperateResultPDAScanCode.IsSuccess)
{
ScanCode = RevData(OperateResultPDAScanCode.Content).Replace("\r", "").Replace("\n", "").Trim();
}
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {