OEM初版
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
namespace FATrace.Com
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,15 @@ namespace FATrace.Com
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据Key取Value值
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public static string GetValue(string key)
|
||||
{
|
||||
return ConfigurationManager.AppSettings[key].ToString().Trim();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据 key 读取字符串配置,不存在时返回默认值。
|
||||
/// </summary>
|
||||
|
||||
24
FATrace.Com/NVRCom.cs
Normal file
24
FATrace.Com/NVRCom.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FATrace.Com
|
||||
{
|
||||
/// <summary>
|
||||
/// NVR 公共的类
|
||||
/// </summary>
|
||||
public class NVRCom
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取视频名称
|
||||
/// </summary>
|
||||
/// <param name="configKey"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetVideoName(string Path,string Code)
|
||||
{
|
||||
return $"{Path}\\{DateTime.Now.ToString("yyyy-MM-dd HHmmss")} {Code}.mp4";
|
||||
}
|
||||
}
|
||||
}
|
||||
30
FATrace.HKNetLib/Common/NVRCamera.cs
Normal file
30
FATrace.HKNetLib/Common/NVRCamera.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FATrace.HKNetLib.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// NVR Camera 模型
|
||||
/// </summary>
|
||||
public class NVRCamera
|
||||
{
|
||||
/// <summary>
|
||||
/// 通道号
|
||||
/// </summary>
|
||||
public int ChNo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否在线
|
||||
/// </summary>
|
||||
public byte IsOnline { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IP设备ID
|
||||
/// </summary>
|
||||
public ushort IPID { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -192,4 +192,8 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FATrace.Model\FATrace.Model.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using FATrace.HKNetLib.Common;
|
||||
using FATrace.HKNetLib.Common;
|
||||
using FATrace.HKNetLib.Hardware;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FATrace.Model;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static FATrace.HKNetLib.Hardware.CHCNetSDK;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FATrace.HKNetLib.Wrapper
|
||||
{
|
||||
@@ -93,8 +91,73 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
}
|
||||
}
|
||||
|
||||
#region NVR信息
|
||||
|
||||
/// <summary>
|
||||
/// NVR IP
|
||||
/// </summary>
|
||||
public string NVR_IP { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// NVR Port
|
||||
/// </summary>
|
||||
public ushort NVR_Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// NVR UserName
|
||||
/// </summary>
|
||||
public string NVR_UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// NVR Pw
|
||||
/// </summary>
|
||||
public string NVR_Pw { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// NVR VideoSavePath 保存的地址信息
|
||||
/// </summary>
|
||||
public string NVRVideoSavePath { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 公共信息
|
||||
|
||||
/// <summary>
|
||||
/// 事件发布的消息
|
||||
/// </summary>
|
||||
public event EventHandler<VideoAction> VideoActionEventHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 下发视频进度过程的Handler
|
||||
/// </summary>
|
||||
public event EventHandler<short> NVRLoadVideoProcessEventHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 下发视频完成的Handler
|
||||
/// </summary>
|
||||
public event EventHandler<string> NVRLoadVideoCompleteEventHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 当前NVR登录信息
|
||||
/// </summary>
|
||||
public CameraLoginInfo NVRLoginInfo { get; set; } = new CameraLoginInfo();
|
||||
|
||||
/// <summary>
|
||||
/// NVR登录状态
|
||||
/// </summary>
|
||||
public bool NVRLoginState { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region NVR开发
|
||||
|
||||
/// <summary>
|
||||
/// NVRCamera 集合数据
|
||||
/// </summary>
|
||||
public List<NVRCamera> ListNVRCamera { get; set; } = new List<NVRCamera>();
|
||||
|
||||
/// <summary>
|
||||
/// NVR设备信息 DVR_DEVICEINFO_V30
|
||||
/// </summary>
|
||||
@@ -105,7 +168,14 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
/// </summary>
|
||||
public CHCNetSDK.NET_DVR_IPPARACFG_V40 DVR_IPPARACFG_V40 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模拟通道个数
|
||||
/// </summary>
|
||||
private uint dwAChanTotalNum { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 数字通道个数
|
||||
/// </summary>
|
||||
private uint dwDChanTotalNum { get; set; } = 0;
|
||||
|
||||
public NET_DVR_GET_STREAM_UNION DVR_GET_STREAM_UNION { get; set; }
|
||||
@@ -153,6 +223,7 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
{
|
||||
LastMsgErr = GetLastError();
|
||||
//MessageBox.Show(str1);
|
||||
NVRLoginState = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -161,6 +232,12 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
//MessageBox.Show("Login Success!");
|
||||
//btnLogin.Text = "Logout";
|
||||
|
||||
NVRLoginInfo.IP = DVRIPAddress;
|
||||
NVRLoginInfo.Port = (ushort)DVRPortNumber;
|
||||
NVRLoginInfo.Password = DVRPassword;
|
||||
NVRLoginInfo.UserName = DVRUserName;
|
||||
NVRLoginState = true;
|
||||
|
||||
dwAChanTotalNum = (uint)DVRDeviceInfoV30.byChanNum;
|
||||
dwDChanTotalNum = (uint)DVRDeviceInfoV30.byIPChanNum + 256 * (uint)DVRDeviceInfoV30.byHighDChanNum;
|
||||
|
||||
@@ -236,6 +313,14 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
Marshal.StructureToPtr(DVR_GET_STREAM_UNION, ptrChanInfo, false);
|
||||
DVR_IPCHANINFO = (CHCNetSDK.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(CHCNetSDK.NET_DVR_IPCHANINFO));
|
||||
|
||||
ListNVRCamera.Add(new NVRCamera()
|
||||
{
|
||||
//ChNo = DVR_IPCHANINFO.byChannel,
|
||||
ChNo = (i + 1),
|
||||
IPID = DVR_IPCHANINFO.byIPID,
|
||||
IsOnline = DVR_IPCHANINFO.byEnable
|
||||
});
|
||||
|
||||
//列出IP通道
|
||||
//ListIPChannel(i + 1, DVR_IPCHANINFO.byEnable, DVR_IPCHANINFO.byIPID);
|
||||
Marshal.FreeHGlobal(ptrChanInfo);
|
||||
@@ -250,20 +335,19 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据时间获取DVR统计信息
|
||||
/// 根据时间获取DVR 视频数据信息
|
||||
/// </summary>
|
||||
public (bool Result, string Msg) Sdk_NET_DVR_GetFileByTime_V40(DateTime startTime, DateTime endTime, string SaveVideFilePath)
|
||||
{
|
||||
if (m_lDownHandle >= 0)
|
||||
{
|
||||
//MessageBox.Show("Downloading, please stop firstly!");//正在下载,请先停止下载
|
||||
return (Result: false, Msg: "正在下载,请先停止下载");
|
||||
}
|
||||
|
||||
NET_DVR_PLAYCOND struDownPara = new NET_DVR_PLAYCOND();
|
||||
struDownPara.dwChannel = (uint)iChannelNum[(int)iSelIndex]; //通道号 Channel number
|
||||
struDownPara.dwChannel = (uint)iChannelNum[(int)iSelIndex];
|
||||
|
||||
//设置下载的开始时间 Set the starting time
|
||||
// 设置下载的开始时间
|
||||
struDownPara.struStartTime.dwYear = startTime.Year;
|
||||
struDownPara.struStartTime.dwMonth = startTime.Month;
|
||||
struDownPara.struStartTime.dwDay = startTime.Day;
|
||||
@@ -271,7 +355,7 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
struDownPara.struStartTime.dwMinute = startTime.Minute;
|
||||
struDownPara.struStartTime.dwSecond = startTime.Second;
|
||||
|
||||
//设置下载的结束时间 Set the stopping time
|
||||
// 设置下载的结束时间
|
||||
struDownPara.struStopTime.dwYear = endTime.Year;
|
||||
struDownPara.struStopTime.dwMonth = endTime.Month;
|
||||
struDownPara.struStopTime.dwDay = endTime.Day;
|
||||
@@ -279,10 +363,7 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
struDownPara.struStopTime.dwMinute = endTime.Minute;
|
||||
struDownPara.struStopTime.dwSecond = endTime.Second;
|
||||
|
||||
//string sVideoFileName; //录像文件保存路径和文件名 the path and file name to save
|
||||
//sVideoFileName = "D:\\Downtest_Channel" + struDownPara.dwChannel + ".mp4";
|
||||
|
||||
//按时间下载 Download by time
|
||||
// 按时间下载
|
||||
m_lDownHandle = CHCNetSDK.NET_DVR_GetFileByTime_V40(m_lUserID, SaveVideFilePath, ref struDownPara);
|
||||
if (m_lDownHandle < 0)
|
||||
{
|
||||
@@ -291,30 +372,153 @@ namespace FATrace.HKNetLib.Wrapper
|
||||
}
|
||||
|
||||
uint iOutValue = 0;
|
||||
//该接口指定了当前要下载的录像文件,调用成功后,还需要调用NET_DVR_PlayBackControl_V40接口的开始播放控制命令(NET_DVR_PLAYSTART)才能实现下载。
|
||||
//V5.0.3.2或以后版本,通过该接口保存录像,保存的录像文件数据超过文件最大限制字节数(默认为1024MB),SDK会自动切片,即新建文件进行保存,文件名命名规则为“在接口传入的文件名基础上增加数字标识(例如:*_1.mp4、*_2.mp4)”。
|
||||
//可以调用NET_DVR_GetSDKLocalCfg、NET_DVR_SetSDKLocalCfg(配置类型:NET_DVR_LOCAL_CFG_TYPE_GENERAL)获取和设置切片模式和文件最大限制字节数。
|
||||
// 该接口指定了当前要下载的录像文件,调用成功后,还需要调用 NET_DVR_PlayBackControl_V40 接口的开始播放控制命令(NET_DVR_PLAYSTART)才能实现下载。
|
||||
if (!CHCNetSDK.NET_DVR_PlayBackControl_V40(m_lDownHandle, CHCNetSDK.NET_DVR_PLAYSTART, IntPtr.Zero, 0, IntPtr.Zero, ref iOutValue))
|
||||
{
|
||||
LastMsgErr = GetLastError();
|
||||
try { CHCNetSDK.NET_DVR_StopGetFile(m_lDownHandle); } catch { }
|
||||
m_lDownHandle = -1;
|
||||
return (Result: false, Msg: $"[NET_DVR_PlayBackControl_V40] 执行下载控制失败:{LastMsgErr}");
|
||||
}
|
||||
|
||||
return (Result: true, Msg: "下载成功!");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取下载的进度
|
||||
/// </summary>
|
||||
/// <param name="downHandle"></param>
|
||||
/// <returns></returns>
|
||||
public int Sdk_NET_DVR_GetDownloadPos(Int32 downHandle)
|
||||
{
|
||||
return CHCNetSDK.NET_DVR_GetDownloadPos(downHandle);
|
||||
StartDownloadProgressMonitor();
|
||||
return (Result: true, Msg: "下载OK!");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 跟踪下载
|
||||
|
||||
private CancellationTokenSource _downloadCts;
|
||||
private const int _downloadPollIntervalMs = 500;
|
||||
|
||||
/// <summary>
|
||||
/// 启动下载进度轮询,定期发布 NVRLoadVideoProcessEventHandler 事件
|
||||
/// </summary>
|
||||
public void StartDownloadProgressMonitor()
|
||||
{
|
||||
// 先确保没有旧的轮询任务
|
||||
StopDownloadProgressMonitor();
|
||||
|
||||
_downloadCts = new CancellationTokenSource();
|
||||
var token = _downloadCts.Token;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!token.IsCancellationRequested && m_lDownHandle >= 0)
|
||||
{
|
||||
int progress = -1;
|
||||
try
|
||||
{
|
||||
progress = CHCNetSDK.NET_DVR_GetDownloadPos(m_lDownHandle);
|
||||
}
|
||||
catch
|
||||
{
|
||||
progress = -1;
|
||||
}
|
||||
|
||||
if (progress >= 0)
|
||||
{
|
||||
short percent = (short)Math.Min(100, progress);
|
||||
try
|
||||
{
|
||||
NVRLoadVideoProcessEventHandler?.Invoke(this, percent);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 事件订阅者异常不应中断轮询
|
||||
}
|
||||
|
||||
if (progress >= 100)
|
||||
{
|
||||
// 完成:停止下载,退出轮询
|
||||
Sdk_NET_DVR_StopGetFile();
|
||||
|
||||
NVRLoadVideoCompleteEventHandler?.Invoke(this, "下载完成");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 发生错误,尝试停止下载并退出
|
||||
Sdk_NET_DVR_StopGetFile();
|
||||
break;
|
||||
}
|
||||
|
||||
try { await Task.Delay(_downloadPollIntervalMs, token); } catch { /* ignore */ }
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 轮询线程异常吞掉,避免影响上层逻辑
|
||||
}
|
||||
}, token);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 停止下载进度轮询
|
||||
/// </summary>
|
||||
private void StopDownloadProgressMonitor()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_downloadCts != null)
|
||||
{
|
||||
if (!_downloadCts.IsCancellationRequested)
|
||||
{
|
||||
_downloadCts.Cancel();
|
||||
}
|
||||
_downloadCts.Dispose();
|
||||
_downloadCts = null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// 忽略取消中的异常
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 停止当前下载并清理资源
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public (bool Result, string Msg) Sdk_NET_DVR_StopGetFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 停止轮询
|
||||
StopDownloadProgressMonitor();
|
||||
|
||||
if (m_lDownHandle >= 0)
|
||||
{
|
||||
bool stopOk = CHCNetSDK.NET_DVR_StopGetFile(m_lDownHandle);
|
||||
m_lDownHandle = -1;
|
||||
if (!stopOk)
|
||||
{
|
||||
LastMsgErr = GetLastError();
|
||||
return (false, $"[NET_DVR_StopGetFile] 停止下载失败:{LastMsgErr}");
|
||||
}
|
||||
}
|
||||
return (true, "停止下载成功");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return (false, "停止下载异常");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
||||
public bool IsOnline()
|
||||
{
|
||||
try
|
||||
|
||||
69
FATrace.Model/OEMRawUse.cs
Normal file
69
FATrace.Model/OEMRawUse.cs
Normal file
@@ -0,0 +1,69 @@
|
||||
using FreeSql.DataAnnotations;
|
||||
|
||||
namespace FATrace.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// OEM原料使用信息
|
||||
/// </summary>
|
||||
[Table(Name = "OEMRawUse")]
|
||||
public class OEMRawUse
|
||||
{
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
[Column(IsPrimary = true, IsIdentity = true)]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内袋二维码
|
||||
/// </summary>
|
||||
[Column(Name = "InBagCode", IsNullable = false, StringLength = 100)]
|
||||
public string? InBagCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原料名称
|
||||
/// </summary>
|
||||
[Column(Name = "InBagCode", IsNullable = false, StringLength = 100)]
|
||||
public string? RawName{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频链接
|
||||
/// </summary>
|
||||
[Column(Name = "VideoUrl", IsNullable = false, StringLength = 100)]
|
||||
public string? VideoUrl{ get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户信息
|
||||
/// </summary>
|
||||
[Column(Name = "User", IsNullable = false, StringLength = 100)]
|
||||
public string? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// URl状态
|
||||
/// </summary>
|
||||
[Column(Name = "UrlState", IsNullable = false)]
|
||||
public bool UrlState { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 视频信息
|
||||
///// </summary>
|
||||
//[Column(Name = "User", IsNullable = false, StringLength = 100)]
|
||||
//public VideoAction? VideoAction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
[Column(ServerTime = DateTimeKind.Local, CanUpdate = true)]
|
||||
public DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// ///////////////////////////////////////////导航属性 LIN 一对一///////////////////////////////////////////////////////
|
||||
/// </summary>
|
||||
public long VideoActionId { get; set; } // 外键字段,必要
|
||||
/// <summary>
|
||||
/// 视频信息
|
||||
/// </summary>
|
||||
public VideoAction? VideoAction { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,12 +26,6 @@ namespace FATrace.Model
|
||||
[Column(Name = "User", IsNullable = false, StringLength = 100)]
|
||||
public string? User { get; set; }
|
||||
|
||||
///// <summary>
|
||||
///// 分类信息-CAN/LIN
|
||||
///// </summary>
|
||||
//[Column(Name = "CANLINInfo", IsNullable = false, MapType = typeof(string))]
|
||||
//public CANLIN CANLINInfo { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 视频文件路径
|
||||
/// </summary>
|
||||
|
||||
@@ -3,11 +3,16 @@
|
||||
|
||||
<appSettings>
|
||||
<add key="connecting1" value="Data Source=192.168.40.2;user instance=false;Initial Catalog=DissColorMachine;User ID=sa;Password=ABCabc123" />
|
||||
<add key="connecting" value="Data Source=CT-PC;user instance=false;Initial Catalog=MoviconDb;User ID=sa;Password=12345678" />
|
||||
<add key="connecting" value="Data Source=CT-PC;user instance=false;Initial Catalog=MoviconDb;TrustServerCertificate=True;User ID=sa;Password=12345678" />
|
||||
<add key="RemoteConnecting" value="Data Source=CT-PC;user instance=false;Initial Catalog=MoviconDb;User ID=sa;Password=12345678" />
|
||||
<add key="PLCIP" value="127.0.0.1" />
|
||||
<add key="PLCPort" value="6000" />
|
||||
<add key="PLCScan" value="600" />
|
||||
<add key="NVRIP" value="192.168.0.15" />
|
||||
<add key="NVRPort" value="8000" />
|
||||
<add key="NVRUserName" value="admin" />
|
||||
<add key="NVRPw" value="glico@2025" />
|
||||
<add key="NVRVideoSavePath" value="D:\" />
|
||||
<add key="InsCheckPort" value="COM10" />
|
||||
<add key="InsCheckRate" value="9600" />
|
||||
</appSettings>
|
||||
|
||||
@@ -415,9 +415,13 @@
|
||||
<PackageReference Include="FreeSql" Version="3.5.213" />
|
||||
<PackageReference Include="FreeSql.Provider.SqlServer" Version="3.5.213" />
|
||||
<PackageReference Include="HslCommunication" Version="12.3.0" />
|
||||
<PackageReference Include="LibVLCSharp" Version="3.9.4" />
|
||||
<PackageReference Include="LibVLCSharp.WinForms" Version="3.9.4" />
|
||||
<PackageReference Include="NLog" Version="6.0.3" />
|
||||
<PackageReference Include="NLog.Config" Version="4.7.15" />
|
||||
<PackageReference Include="ReaLTaiizor" Version="3.8.1.3" />
|
||||
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
|
||||
<PackageReference Include="RestSharp" Version="110.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
using FATrace.Com;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace FATrace.OEMApp
|
||||
{
|
||||
@@ -16,7 +11,7 @@ namespace FATrace.OEMApp
|
||||
{
|
||||
return new FreeSql.FreeSqlBuilder()
|
||||
.UseConnectionString(FreeSql.DataType.SqlServer, connectionString)
|
||||
.UseAutoSyncStructure(false)
|
||||
.UseAutoSyncStructure(true)
|
||||
.Build();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
625
FATrace.OEMApp/MainApp.Designer.cs
generated
625
FATrace.OEMApp/MainApp.Designer.cs
generated
@@ -30,20 +30,79 @@
|
||||
{
|
||||
components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainApp));
|
||||
statusStrip1 = new StatusStrip();
|
||||
imageList1 = new ImageList(components);
|
||||
materialTabControl1 = new ReaLTaiizor.Controls.MaterialTabControl();
|
||||
tabPage1 = new TabPage();
|
||||
materialCard4 = new ReaLTaiizor.Controls.MaterialCard();
|
||||
label18 = new Label();
|
||||
txtIOOutputTime = new TextBox();
|
||||
label17 = new Label();
|
||||
txtIOInputTime = new TextBox();
|
||||
label16 = new Label();
|
||||
txtIOInBagCode = new TextBox();
|
||||
txtRemainBoxCount = new TextBox();
|
||||
label15 = new Label();
|
||||
txtOutBoxCount = new TextBox();
|
||||
label14 = new Label();
|
||||
txtInBoxCount = new TextBox();
|
||||
label13 = new Label();
|
||||
label12 = new Label();
|
||||
label9 = new Label();
|
||||
txtIORawName = new TextBox();
|
||||
label10 = new Label();
|
||||
txtIOOutBagCode = new TextBox();
|
||||
label11 = new Label();
|
||||
materialCard3 = new ReaLTaiizor.Controls.MaterialCard();
|
||||
label8 = new Label();
|
||||
materialCard2 = new ReaLTaiizor.Controls.MaterialCard();
|
||||
btnTestAction = new Button();
|
||||
label7 = new Label();
|
||||
txtRURawName = new TextBox();
|
||||
label6 = new Label();
|
||||
txtRUInBagCode = new TextBox();
|
||||
label5 = new Label();
|
||||
tabPage2 = new TabPage();
|
||||
btnStopHistoryPlay = new Button();
|
||||
dataGridView1 = new DataGridView();
|
||||
materialCard1 = new ReaLTaiizor.Controls.MaterialCard();
|
||||
label4 = new Label();
|
||||
txtSearchCode = new TextBox();
|
||||
btnHistoryVideoSearch = new Button();
|
||||
label3 = new Label();
|
||||
PdtHistorySearchEnd = new ReaLTaiizor.Controls.PoisonDateTime();
|
||||
label2 = new Label();
|
||||
label1 = new Label();
|
||||
PdtHistorySearchStart = new ReaLTaiizor.Controls.PoisonDateTime();
|
||||
btnPlayHistoryVideo = new Button();
|
||||
videoView1 = new LibVLCSharp.WinForms.VideoView();
|
||||
tabPage3 = new TabPage();
|
||||
metroProgressBar1 = new ReaLTaiizor.Controls.MetroProgressBar();
|
||||
DownloadProgressBar = new ProgressBar();
|
||||
btnStopLoadVideo = new Button();
|
||||
btnLoadVideo = new Button();
|
||||
btnNVRLogin = new Button();
|
||||
DownTimer = new System.Windows.Forms.Timer(components);
|
||||
DownloadProgressBar = new ProgressBar();
|
||||
DownloadProgressBarMain = new ProgressBar();
|
||||
materialTabControl1.SuspendLayout();
|
||||
tabPage1.SuspendLayout();
|
||||
materialCard4.SuspendLayout();
|
||||
materialCard3.SuspendLayout();
|
||||
materialCard2.SuspendLayout();
|
||||
tabPage2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)dataGridView1).BeginInit();
|
||||
materialCard1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)videoView1).BeginInit();
|
||||
tabPage3.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// statusStrip1
|
||||
//
|
||||
statusStrip1.Location = new Point(3, 1005);
|
||||
statusStrip1.Name = "statusStrip1";
|
||||
statusStrip1.Size = new Size(1914, 22);
|
||||
statusStrip1.TabIndex = 1;
|
||||
statusStrip1.Text = "statusStrip1";
|
||||
//
|
||||
// imageList1
|
||||
//
|
||||
imageList1.ColorDepth = ColorDepth.Depth32Bit;
|
||||
@@ -76,6 +135,9 @@
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
tabPage1.Controls.Add(materialCard4);
|
||||
tabPage1.Controls.Add(materialCard3);
|
||||
tabPage1.Controls.Add(materialCard2);
|
||||
tabPage1.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
tabPage1.ImageKey = "set2.png";
|
||||
tabPage1.Location = new Point(4, 26);
|
||||
@@ -86,8 +148,323 @@
|
||||
tabPage1.Text = "主界面";
|
||||
tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// materialCard4
|
||||
//
|
||||
materialCard4.BackColor = Color.FromArgb(255, 255, 255);
|
||||
materialCard4.Controls.Add(label18);
|
||||
materialCard4.Controls.Add(txtIOOutputTime);
|
||||
materialCard4.Controls.Add(label17);
|
||||
materialCard4.Controls.Add(txtIOInputTime);
|
||||
materialCard4.Controls.Add(label16);
|
||||
materialCard4.Controls.Add(txtIOInBagCode);
|
||||
materialCard4.Controls.Add(txtRemainBoxCount);
|
||||
materialCard4.Controls.Add(label15);
|
||||
materialCard4.Controls.Add(txtOutBoxCount);
|
||||
materialCard4.Controls.Add(label14);
|
||||
materialCard4.Controls.Add(txtInBoxCount);
|
||||
materialCard4.Controls.Add(label13);
|
||||
materialCard4.Controls.Add(label12);
|
||||
materialCard4.Controls.Add(label9);
|
||||
materialCard4.Controls.Add(txtIORawName);
|
||||
materialCard4.Controls.Add(label10);
|
||||
materialCard4.Controls.Add(txtIOOutBagCode);
|
||||
materialCard4.Controls.Add(label11);
|
||||
materialCard4.Depth = 0;
|
||||
materialCard4.ForeColor = Color.FromArgb(222, 0, 0, 0);
|
||||
materialCard4.Location = new Point(14, 373);
|
||||
materialCard4.Margin = new Padding(14);
|
||||
materialCard4.MouseState = ReaLTaiizor.Helper.MaterialDrawHelper.MaterialMouseState.HOVER;
|
||||
materialCard4.Name = "materialCard4";
|
||||
materialCard4.Padding = new Padding(14);
|
||||
materialCard4.Size = new Size(864, 535);
|
||||
materialCard4.TabIndex = 5;
|
||||
//
|
||||
// label18
|
||||
//
|
||||
label18.AutoSize = true;
|
||||
label18.ForeColor = Color.DimGray;
|
||||
label18.Location = new Point(41, 260);
|
||||
label18.Name = "label18";
|
||||
label18.Size = new Size(88, 26);
|
||||
label18.TabIndex = 17;
|
||||
label18.Text = "出库时间";
|
||||
//
|
||||
// txtIOOutputTime
|
||||
//
|
||||
txtIOOutputTime.Location = new Point(154, 257);
|
||||
txtIOOutputTime.Name = "txtIOOutputTime";
|
||||
txtIOOutputTime.Size = new Size(446, 32);
|
||||
txtIOOutputTime.TabIndex = 16;
|
||||
//
|
||||
// label17
|
||||
//
|
||||
label17.AutoSize = true;
|
||||
label17.ForeColor = Color.DimGray;
|
||||
label17.Location = new Point(41, 211);
|
||||
label17.Name = "label17";
|
||||
label17.Size = new Size(88, 26);
|
||||
label17.TabIndex = 15;
|
||||
label17.Text = "入库时间";
|
||||
//
|
||||
// txtIOInputTime
|
||||
//
|
||||
txtIOInputTime.Location = new Point(154, 208);
|
||||
txtIOInputTime.Name = "txtIOInputTime";
|
||||
txtIOInputTime.Size = new Size(446, 32);
|
||||
txtIOInputTime.TabIndex = 14;
|
||||
//
|
||||
// label16
|
||||
//
|
||||
label16.AutoSize = true;
|
||||
label16.ForeColor = Color.DimGray;
|
||||
label16.Location = new Point(41, 109);
|
||||
label16.Name = "label16";
|
||||
label16.Size = new Size(107, 26);
|
||||
label16.TabIndex = 13;
|
||||
label16.Text = "内袋二维码";
|
||||
//
|
||||
// txtIOInBagCode
|
||||
//
|
||||
txtIOInBagCode.Location = new Point(154, 106);
|
||||
txtIOInBagCode.Name = "txtIOInBagCode";
|
||||
txtIOInBagCode.Size = new Size(446, 32);
|
||||
txtIOInBagCode.TabIndex = 12;
|
||||
//
|
||||
// txtRemainBoxCount
|
||||
//
|
||||
txtRemainBoxCount.BackColor = SystemColors.ButtonHighlight;
|
||||
txtRemainBoxCount.BorderStyle = BorderStyle.None;
|
||||
txtRemainBoxCount.Font = new Font("Microsoft YaHei UI", 21.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
txtRemainBoxCount.Location = new Point(507, 417);
|
||||
txtRemainBoxCount.Name = "txtRemainBoxCount";
|
||||
txtRemainBoxCount.ReadOnly = true;
|
||||
txtRemainBoxCount.Size = new Size(100, 37);
|
||||
txtRemainBoxCount.TabIndex = 11;
|
||||
txtRemainBoxCount.Text = "100";
|
||||
txtRemainBoxCount.TextAlign = HorizontalAlignment.Center;
|
||||
//
|
||||
// label15
|
||||
//
|
||||
label15.AutoSize = true;
|
||||
label15.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label15.ForeColor = Color.DimGray;
|
||||
label15.Location = new Point(496, 475);
|
||||
label15.Name = "label15";
|
||||
label15.Size = new Size(117, 28);
|
||||
label15.TabIndex = 10;
|
||||
label15.Text = "剩余总箱数";
|
||||
//
|
||||
// txtOutBoxCount
|
||||
//
|
||||
txtOutBoxCount.BackColor = SystemColors.ButtonHighlight;
|
||||
txtOutBoxCount.BorderStyle = BorderStyle.None;
|
||||
txtOutBoxCount.Font = new Font("Microsoft YaHei UI", 21.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
txtOutBoxCount.Location = new Point(317, 417);
|
||||
txtOutBoxCount.Name = "txtOutBoxCount";
|
||||
txtOutBoxCount.ReadOnly = true;
|
||||
txtOutBoxCount.Size = new Size(100, 37);
|
||||
txtOutBoxCount.TabIndex = 9;
|
||||
txtOutBoxCount.Text = "100";
|
||||
txtOutBoxCount.TextAlign = HorizontalAlignment.Center;
|
||||
//
|
||||
// label14
|
||||
//
|
||||
label14.AutoSize = true;
|
||||
label14.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label14.ForeColor = Color.DimGray;
|
||||
label14.Location = new Point(306, 475);
|
||||
label14.Name = "label14";
|
||||
label14.Size = new Size(117, 28);
|
||||
label14.TabIndex = 8;
|
||||
label14.Text = "出库总箱数";
|
||||
//
|
||||
// txtInBoxCount
|
||||
//
|
||||
txtInBoxCount.BackColor = SystemColors.ButtonHighlight;
|
||||
txtInBoxCount.BorderStyle = BorderStyle.None;
|
||||
txtInBoxCount.Font = new Font("Microsoft YaHei UI", 21.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
txtInBoxCount.Location = new Point(103, 417);
|
||||
txtInBoxCount.Name = "txtInBoxCount";
|
||||
txtInBoxCount.ReadOnly = true;
|
||||
txtInBoxCount.Size = new Size(100, 37);
|
||||
txtInBoxCount.TabIndex = 7;
|
||||
txtInBoxCount.Text = "100";
|
||||
txtInBoxCount.TextAlign = HorizontalAlignment.Center;
|
||||
//
|
||||
// label13
|
||||
//
|
||||
label13.AutoSize = true;
|
||||
label13.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label13.ForeColor = Color.DimGray;
|
||||
label13.Location = new Point(92, 475);
|
||||
label13.Name = "label13";
|
||||
label13.Size = new Size(117, 28);
|
||||
label13.TabIndex = 6;
|
||||
label13.Text = "入库总箱数";
|
||||
//
|
||||
// label12
|
||||
//
|
||||
label12.AutoSize = true;
|
||||
label12.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label12.ForeColor = Color.FromArgb(64, 64, 64);
|
||||
label12.Location = new Point(10, 319);
|
||||
label12.Name = "label12";
|
||||
label12.Size = new Size(159, 28);
|
||||
label12.TabIndex = 5;
|
||||
label12.Text = "成品出入库统计";
|
||||
//
|
||||
// label9
|
||||
//
|
||||
label9.AutoSize = true;
|
||||
label9.ForeColor = Color.DimGray;
|
||||
label9.Location = new Point(41, 160);
|
||||
label9.Name = "label9";
|
||||
label9.Size = new Size(88, 26);
|
||||
label9.TabIndex = 4;
|
||||
label9.Text = "原料名称";
|
||||
//
|
||||
// txtIORawName
|
||||
//
|
||||
txtIORawName.Location = new Point(154, 157);
|
||||
txtIORawName.Name = "txtIORawName";
|
||||
txtIORawName.Size = new Size(446, 32);
|
||||
txtIORawName.TabIndex = 3;
|
||||
//
|
||||
// label10
|
||||
//
|
||||
label10.AutoSize = true;
|
||||
label10.ForeColor = Color.DimGray;
|
||||
label10.Location = new Point(41, 61);
|
||||
label10.Name = "label10";
|
||||
label10.Size = new Size(107, 26);
|
||||
label10.TabIndex = 2;
|
||||
label10.Text = "外箱二维码";
|
||||
//
|
||||
// txtIOOutBagCode
|
||||
//
|
||||
txtIOOutBagCode.Location = new Point(154, 58);
|
||||
txtIOOutBagCode.Name = "txtIOOutBagCode";
|
||||
txtIOOutBagCode.Size = new Size(446, 32);
|
||||
txtIOOutBagCode.TabIndex = 1;
|
||||
//
|
||||
// label11
|
||||
//
|
||||
label11.AutoSize = true;
|
||||
label11.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label11.ForeColor = Color.FromArgb(64, 64, 64);
|
||||
label11.Location = new Point(10, 9);
|
||||
label11.Name = "label11";
|
||||
label11.Size = new Size(159, 28);
|
||||
label11.TabIndex = 0;
|
||||
label11.Text = "成品出入库信息";
|
||||
//
|
||||
// materialCard3
|
||||
//
|
||||
materialCard3.BackColor = Color.FromArgb(255, 255, 255);
|
||||
materialCard3.Controls.Add(label8);
|
||||
materialCard3.Depth = 0;
|
||||
materialCard3.ForeColor = Color.FromArgb(222, 0, 0, 0);
|
||||
materialCard3.Location = new Point(897, 8);
|
||||
materialCard3.Margin = new Padding(14);
|
||||
materialCard3.MouseState = ReaLTaiizor.Helper.MaterialDrawHelper.MaterialMouseState.HOVER;
|
||||
materialCard3.Name = "materialCard3";
|
||||
materialCard3.Padding = new Padding(14);
|
||||
materialCard3.Size = new Size(1000, 900);
|
||||
materialCard3.TabIndex = 1;
|
||||
//
|
||||
// label8
|
||||
//
|
||||
label8.AutoSize = true;
|
||||
label8.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label8.ForeColor = Color.FromArgb(64, 64, 64);
|
||||
label8.Location = new Point(12, 9);
|
||||
label8.Name = "label8";
|
||||
label8.Size = new Size(180, 28);
|
||||
label8.TabIndex = 5;
|
||||
label8.Text = "原料使用历史信息";
|
||||
//
|
||||
// materialCard2
|
||||
//
|
||||
materialCard2.BackColor = Color.FromArgb(255, 255, 255);
|
||||
materialCard2.Controls.Add(DownloadProgressBarMain);
|
||||
materialCard2.Controls.Add(btnTestAction);
|
||||
materialCard2.Controls.Add(label7);
|
||||
materialCard2.Controls.Add(txtRURawName);
|
||||
materialCard2.Controls.Add(label6);
|
||||
materialCard2.Controls.Add(txtRUInBagCode);
|
||||
materialCard2.Controls.Add(label5);
|
||||
materialCard2.Depth = 0;
|
||||
materialCard2.ForeColor = Color.FromArgb(222, 0, 0, 0);
|
||||
materialCard2.Location = new Point(14, 9);
|
||||
materialCard2.Margin = new Padding(14);
|
||||
materialCard2.MouseState = ReaLTaiizor.Helper.MaterialDrawHelper.MaterialMouseState.HOVER;
|
||||
materialCard2.Name = "materialCard2";
|
||||
materialCard2.Padding = new Padding(14);
|
||||
materialCard2.Size = new Size(864, 348);
|
||||
materialCard2.TabIndex = 0;
|
||||
//
|
||||
// btnTestAction
|
||||
//
|
||||
btnTestAction.Location = new Point(41, 223);
|
||||
btnTestAction.Name = "btnTestAction";
|
||||
btnTestAction.Size = new Size(142, 44);
|
||||
btnTestAction.TabIndex = 5;
|
||||
btnTestAction.Text = "结束操作";
|
||||
btnTestAction.UseVisualStyleBackColor = true;
|
||||
btnTestAction.Click += btnTestAction_Click;
|
||||
//
|
||||
// label7
|
||||
//
|
||||
label7.AutoSize = true;
|
||||
label7.ForeColor = Color.DimGray;
|
||||
label7.Location = new Point(41, 126);
|
||||
label7.Name = "label7";
|
||||
label7.Size = new Size(88, 26);
|
||||
label7.TabIndex = 4;
|
||||
label7.Text = "原料名称";
|
||||
//
|
||||
// txtRURawName
|
||||
//
|
||||
txtRURawName.Location = new Point(154, 123);
|
||||
txtRURawName.Name = "txtRURawName";
|
||||
txtRURawName.Size = new Size(446, 32);
|
||||
txtRURawName.TabIndex = 3;
|
||||
//
|
||||
// label6
|
||||
//
|
||||
label6.AutoSize = true;
|
||||
label6.ForeColor = Color.DimGray;
|
||||
label6.Location = new Point(41, 68);
|
||||
label6.Name = "label6";
|
||||
label6.Size = new Size(107, 26);
|
||||
label6.TabIndex = 2;
|
||||
label6.Text = "内袋二维码";
|
||||
//
|
||||
// txtRUInBagCode
|
||||
//
|
||||
txtRUInBagCode.Location = new Point(154, 65);
|
||||
txtRUInBagCode.Name = "txtRUInBagCode";
|
||||
txtRUInBagCode.Size = new Size(446, 32);
|
||||
txtRUInBagCode.TabIndex = 1;
|
||||
//
|
||||
// label5
|
||||
//
|
||||
label5.AutoSize = true;
|
||||
label5.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label5.ForeColor = Color.FromArgb(64, 64, 64);
|
||||
label5.Location = new Point(10, 9);
|
||||
label5.Name = "label5";
|
||||
label5.Size = new Size(138, 28);
|
||||
label5.TabIndex = 0;
|
||||
label5.Text = "原料使用信息";
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
tabPage2.Controls.Add(btnStopHistoryPlay);
|
||||
tabPage2.Controls.Add(dataGridView1);
|
||||
tabPage2.Controls.Add(materialCard1);
|
||||
tabPage2.Controls.Add(btnPlayHistoryVideo);
|
||||
tabPage2.Controls.Add(videoView1);
|
||||
tabPage2.Font = new Font("Microsoft YaHei UI", 14.25F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
tabPage2.ImageKey = "Load.png";
|
||||
tabPage2.Location = new Point(4, 26);
|
||||
@@ -98,8 +475,145 @@
|
||||
tabPage2.Text = "录像历史数据";
|
||||
tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// btnStopHistoryPlay
|
||||
//
|
||||
btnStopHistoryPlay.Location = new Point(628, 14);
|
||||
btnStopHistoryPlay.Name = "btnStopHistoryPlay";
|
||||
btnStopHistoryPlay.Size = new Size(116, 45);
|
||||
btnStopHistoryPlay.TabIndex = 12;
|
||||
btnStopHistoryPlay.Text = "停止播放";
|
||||
btnStopHistoryPlay.UseVisualStyleBackColor = true;
|
||||
btnStopHistoryPlay.Click += btnStopHistoryPlay_Click;
|
||||
//
|
||||
// dataGridView1
|
||||
//
|
||||
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
dataGridView1.Location = new Point(17, 328);
|
||||
dataGridView1.Name = "dataGridView1";
|
||||
dataGridView1.Size = new Size(483, 584);
|
||||
dataGridView1.TabIndex = 11;
|
||||
//
|
||||
// materialCard1
|
||||
//
|
||||
materialCard1.BackColor = Color.FromArgb(255, 255, 255);
|
||||
materialCard1.Controls.Add(label4);
|
||||
materialCard1.Controls.Add(txtSearchCode);
|
||||
materialCard1.Controls.Add(btnHistoryVideoSearch);
|
||||
materialCard1.Controls.Add(label3);
|
||||
materialCard1.Controls.Add(PdtHistorySearchEnd);
|
||||
materialCard1.Controls.Add(label2);
|
||||
materialCard1.Controls.Add(label1);
|
||||
materialCard1.Controls.Add(PdtHistorySearchStart);
|
||||
materialCard1.Depth = 0;
|
||||
materialCard1.ForeColor = Color.FromArgb(222, 0, 0, 0);
|
||||
materialCard1.Location = new Point(17, 24);
|
||||
materialCard1.Margin = new Padding(14);
|
||||
materialCard1.MouseState = ReaLTaiizor.Helper.MaterialDrawHelper.MaterialMouseState.HOVER;
|
||||
materialCard1.Name = "materialCard1";
|
||||
materialCard1.Padding = new Padding(14);
|
||||
materialCard1.Size = new Size(483, 287);
|
||||
materialCard1.TabIndex = 10;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
label4.AutoSize = true;
|
||||
label4.ForeColor = Color.Gray;
|
||||
label4.Location = new Point(196, 34);
|
||||
label4.Name = "label4";
|
||||
label4.Size = new Size(88, 26);
|
||||
label4.TabIndex = 7;
|
||||
label4.Text = "条码信息";
|
||||
//
|
||||
// txtSearchCode
|
||||
//
|
||||
txtSearchCode.Location = new Point(17, 63);
|
||||
txtSearchCode.Name = "txtSearchCode";
|
||||
txtSearchCode.Size = new Size(449, 32);
|
||||
txtSearchCode.TabIndex = 6;
|
||||
//
|
||||
// btnHistoryVideoSearch
|
||||
//
|
||||
btnHistoryVideoSearch.ForeColor = Color.DimGray;
|
||||
btnHistoryVideoSearch.Location = new Point(125, 214);
|
||||
btnHistoryVideoSearch.Name = "btnHistoryVideoSearch";
|
||||
btnHistoryVideoSearch.Size = new Size(210, 56);
|
||||
btnHistoryVideoSearch.TabIndex = 5;
|
||||
btnHistoryVideoSearch.Text = "历史记录视频搜索";
|
||||
btnHistoryVideoSearch.UseVisualStyleBackColor = true;
|
||||
btnHistoryVideoSearch.Click += btnHistoryVideoSearch_Click;
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.AutoSize = true;
|
||||
label3.ForeColor = Color.Gray;
|
||||
label3.Location = new Point(288, 117);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new Size(88, 26);
|
||||
label3.TabIndex = 4;
|
||||
label3.Text = "结束时间";
|
||||
//
|
||||
// PdtHistorySearchEnd
|
||||
//
|
||||
PdtHistorySearchEnd.FontSize = ReaLTaiizor.Extension.Poison.PoisonDateTimeSize.Medium;
|
||||
PdtHistorySearchEnd.Location = new Point(268, 155);
|
||||
PdtHistorySearchEnd.MinimumSize = new Size(0, 29);
|
||||
PdtHistorySearchEnd.Name = "PdtHistorySearchEnd";
|
||||
PdtHistorySearchEnd.Size = new Size(131, 32);
|
||||
PdtHistorySearchEnd.TabIndex = 3;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.ForeColor = Color.Gray;
|
||||
label2.Location = new Point(75, 116);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new Size(88, 26);
|
||||
label2.TabIndex = 2;
|
||||
label2.Text = "开始时间";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Font = new Font("Microsoft YaHei UI", 15.75F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
label1.ForeColor = Color.Gray;
|
||||
label1.Location = new Point(6, 7);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new Size(96, 28);
|
||||
label1.TabIndex = 1;
|
||||
label1.Text = "搜索条件";
|
||||
//
|
||||
// PdtHistorySearchStart
|
||||
//
|
||||
PdtHistorySearchStart.FontSize = ReaLTaiizor.Extension.Poison.PoisonDateTimeSize.Medium;
|
||||
PdtHistorySearchStart.Location = new Point(55, 154);
|
||||
PdtHistorySearchStart.MinimumSize = new Size(0, 29);
|
||||
PdtHistorySearchStart.Name = "PdtHistorySearchStart";
|
||||
PdtHistorySearchStart.Size = new Size(131, 32);
|
||||
PdtHistorySearchStart.TabIndex = 0;
|
||||
//
|
||||
// btnPlayHistoryVideo
|
||||
//
|
||||
btnPlayHistoryVideo.Location = new Point(506, 14);
|
||||
btnPlayHistoryVideo.Name = "btnPlayHistoryVideo";
|
||||
btnPlayHistoryVideo.Size = new Size(116, 45);
|
||||
btnPlayHistoryVideo.TabIndex = 8;
|
||||
btnPlayHistoryVideo.Text = "button1";
|
||||
btnPlayHistoryVideo.UseVisualStyleBackColor = true;
|
||||
btnPlayHistoryVideo.Click += btnPlayHistoryVideo_Click;
|
||||
//
|
||||
// videoView1
|
||||
//
|
||||
videoView1.BackColor = Color.Black;
|
||||
videoView1.Location = new Point(506, 65);
|
||||
videoView1.MediaPlayer = null;
|
||||
videoView1.Name = "videoView1";
|
||||
videoView1.Size = new Size(1394, 847);
|
||||
videoView1.TabIndex = 7;
|
||||
videoView1.Text = "videoView1";
|
||||
//
|
||||
// tabPage3
|
||||
//
|
||||
tabPage3.Controls.Add(metroProgressBar1);
|
||||
tabPage3.Controls.Add(DownloadProgressBar);
|
||||
tabPage3.Controls.Add(btnStopLoadVideo);
|
||||
tabPage3.Controls.Add(btnLoadVideo);
|
||||
@@ -112,6 +626,36 @@
|
||||
tabPage3.Text = "相机设置";
|
||||
tabPage3.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// metroProgressBar1
|
||||
//
|
||||
metroProgressBar1.BackgroundColor = Color.FromArgb(238, 238, 238);
|
||||
metroProgressBar1.BorderColor = Color.FromArgb(238, 238, 238);
|
||||
metroProgressBar1.DisabledBackColor = Color.FromArgb(238, 238, 238);
|
||||
metroProgressBar1.DisabledBorderColor = Color.FromArgb(238, 238, 238);
|
||||
metroProgressBar1.DisabledProgressColor = Color.FromArgb(120, 65, 177, 225);
|
||||
metroProgressBar1.IsDerivedStyle = true;
|
||||
metroProgressBar1.Location = new Point(252, 181);
|
||||
metroProgressBar1.Maximum = 100;
|
||||
metroProgressBar1.Minimum = 0;
|
||||
metroProgressBar1.Name = "metroProgressBar1";
|
||||
metroProgressBar1.Orientation = ReaLTaiizor.Enum.Metro.ProgressOrientation.Horizontal;
|
||||
metroProgressBar1.ProgressColor = Color.FromArgb(65, 177, 225);
|
||||
metroProgressBar1.Size = new Size(125, 23);
|
||||
metroProgressBar1.Style = ReaLTaiizor.Enum.Metro.Style.Light;
|
||||
metroProgressBar1.StyleManager = null;
|
||||
metroProgressBar1.TabIndex = 4;
|
||||
metroProgressBar1.Text = "metroProgressBar1";
|
||||
metroProgressBar1.ThemeAuthor = "Taiizor";
|
||||
metroProgressBar1.ThemeName = "MetroLight";
|
||||
metroProgressBar1.Value = 0;
|
||||
//
|
||||
// DownloadProgressBar
|
||||
//
|
||||
DownloadProgressBar.Location = new Point(247, 124);
|
||||
DownloadProgressBar.Name = "DownloadProgressBar";
|
||||
DownloadProgressBar.Size = new Size(130, 23);
|
||||
DownloadProgressBar.TabIndex = 3;
|
||||
//
|
||||
// btnStopLoadVideo
|
||||
//
|
||||
btnStopLoadVideo.Location = new Point(409, 54);
|
||||
@@ -142,22 +686,19 @@
|
||||
btnNVRLogin.UseVisualStyleBackColor = true;
|
||||
btnNVRLogin.Click += btnNVRLogin_Click;
|
||||
//
|
||||
// DownTimer
|
||||
// DownloadProgressBarMain
|
||||
//
|
||||
DownTimer.Tick += DownTimer_Tick;
|
||||
//
|
||||
// DownloadProgressBar
|
||||
//
|
||||
DownloadProgressBar.Location = new Point(247, 124);
|
||||
DownloadProgressBar.Name = "DownloadProgressBar";
|
||||
DownloadProgressBar.Size = new Size(130, 23);
|
||||
DownloadProgressBar.TabIndex = 3;
|
||||
DownloadProgressBarMain.Location = new Point(1, 324);
|
||||
DownloadProgressBarMain.Name = "DownloadProgressBarMain";
|
||||
DownloadProgressBarMain.Size = new Size(862, 23);
|
||||
DownloadProgressBarMain.TabIndex = 6;
|
||||
//
|
||||
// MainApp
|
||||
//
|
||||
AutoScaleDimensions = new SizeF(8F, 17F);
|
||||
AutoScaleMode = AutoScaleMode.Font;
|
||||
ClientSize = new Size(1920, 1030);
|
||||
Controls.Add(statusStrip1);
|
||||
Controls.Add(materialTabControl1);
|
||||
DrawerTabControl = materialTabControl1;
|
||||
Font = new Font("Microsoft YaHei UI", 9F, FontStyle.Bold, GraphicsUnit.Point, 134);
|
||||
@@ -168,12 +709,30 @@
|
||||
WindowState = FormWindowState.Maximized;
|
||||
Load += MainApp_Load;
|
||||
materialTabControl1.ResumeLayout(false);
|
||||
tabPage1.ResumeLayout(false);
|
||||
materialCard4.ResumeLayout(false);
|
||||
materialCard4.PerformLayout();
|
||||
materialCard3.ResumeLayout(false);
|
||||
materialCard3.PerformLayout();
|
||||
materialCard2.ResumeLayout(false);
|
||||
materialCard2.PerformLayout();
|
||||
tabPage2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)dataGridView1).EndInit();
|
||||
materialCard1.ResumeLayout(false);
|
||||
materialCard1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)videoView1).EndInit();
|
||||
tabPage3.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
PerformLayout();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private StatusStrip statusStrip1;
|
||||
|
||||
private ImageList imageList1;
|
||||
|
||||
|
||||
private ReaLTaiizor.Controls.MaterialTabControl materialTabControl1;
|
||||
private TabPage tabPage1;
|
||||
private TabPage tabPage2;
|
||||
@@ -181,7 +740,49 @@
|
||||
private Button btnNVRLogin;
|
||||
private Button btnLoadVideo;
|
||||
private Button btnStopLoadVideo;
|
||||
private System.Windows.Forms.Timer DownTimer;
|
||||
private ProgressBar DownloadProgressBar;
|
||||
private ReaLTaiizor.Controls.MetroProgressBar metroProgressBar1;
|
||||
private LibVLCSharp.WinForms.VideoView videoView1;
|
||||
private Button btnPlayHistoryVideo;
|
||||
private ReaLTaiizor.Controls.MaterialCard materialCard1;
|
||||
private ReaLTaiizor.Controls.PoisonDateTime PdtHistorySearchStart;
|
||||
private Label label1;
|
||||
private Button btnHistoryVideoSearch;
|
||||
private Label label3;
|
||||
private ReaLTaiizor.Controls.PoisonDateTime PdtHistorySearchEnd;
|
||||
private Label label2;
|
||||
private Label label4;
|
||||
private TextBox txtSearchCode;
|
||||
private DataGridView dataGridView1;
|
||||
private Button btnStopHistoryPlay;
|
||||
private ReaLTaiizor.Controls.MaterialCard materialCard2;
|
||||
private Label label5;
|
||||
private Label label6;
|
||||
private TextBox txtRUInBagCode;
|
||||
private Label label7;
|
||||
private TextBox txtRURawName;
|
||||
private ReaLTaiizor.Controls.MaterialCard materialCard3;
|
||||
private Label label8;
|
||||
private ReaLTaiizor.Controls.MaterialCard materialCard4;
|
||||
private Label label9;
|
||||
private TextBox txtIORawName;
|
||||
private Label label10;
|
||||
private TextBox txtIOOutBagCode;
|
||||
private Label label11;
|
||||
private Label label12;
|
||||
private Label label13;
|
||||
private TextBox txtInBoxCount;
|
||||
private TextBox txtOutBoxCount;
|
||||
private Label label14;
|
||||
private TextBox txtRemainBoxCount;
|
||||
private Label label15;
|
||||
private Label label16;
|
||||
private TextBox txtIOInBagCode;
|
||||
private Label label18;
|
||||
private TextBox txtIOOutputTime;
|
||||
private Label label17;
|
||||
private TextBox txtIOInputTime;
|
||||
private Button btnTestAction;
|
||||
private ProgressBar DownloadProgressBarMain;
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,32 @@
|
||||
using FATrace.Com;
|
||||
using FATrace.HKNetLib.Hardware;
|
||||
using FATrace.HKNetLib.Wrapper;
|
||||
using FATrace.Model;
|
||||
using LibVLCSharp.Shared;
|
||||
using ReaLTaiizor.Forms;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace FATrace.OEMApp
|
||||
{
|
||||
public partial class MainApp : MaterialForm
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 海康Camera 客户端
|
||||
/// </summary>
|
||||
public HkCamera HkCameraClient { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通道集合
|
||||
/// </summary>
|
||||
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 96, ArraySubType = UnmanagedType.U4)]
|
||||
private int[] iChannelNum;
|
||||
// 历史表列头中文映射
|
||||
private readonly Dictionary<string, string> _historyHeaderMap = new Dictionary<string, string>
|
||||
{
|
||||
{ nameof(VideoAction.Id), "编号" },
|
||||
{ nameof(VideoAction.Code), "条码" },
|
||||
{ nameof(VideoAction.User), "用户" },
|
||||
{ nameof(VideoAction.VideoFilePath), "视频路径" },
|
||||
{ nameof(VideoAction.VideoName), "视频名称" },
|
||||
{ nameof(VideoAction.StartTime), "开始时间" },
|
||||
{ nameof(VideoAction.EndTime), "结束时间" },
|
||||
{ nameof(VideoAction.CreateTime), "创建时间" }
|
||||
};
|
||||
|
||||
public MainApp()
|
||||
{
|
||||
@@ -31,8 +39,20 @@ namespace FATrace.OEMApp
|
||||
HkCameraClient = new HkCamera();
|
||||
//保存SDK日志
|
||||
CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);
|
||||
iChannelNum = new int[96];
|
||||
|
||||
//读取配置
|
||||
//HkCameraClient.NVR_IP = ConfigHelper.GetValue("NVRIP");
|
||||
//HkCameraClient.NVR_Port = ConfigHelper.GetValue("NVRPort");
|
||||
//HkCameraClient.NVR_UserName = ConfigHelper.GetValue("NVRUserName");
|
||||
|
||||
HkCameraClient.NVRVideoSavePath = ConfigHelper.GetValue("NVRVideoSavePath");
|
||||
|
||||
|
||||
|
||||
InitMediaPlayer();
|
||||
InitHistoryGridBinding();
|
||||
|
||||
//materialListView1.DataBindings
|
||||
try
|
||||
{
|
||||
var systemName = Program.SystemName;
|
||||
@@ -56,24 +76,43 @@ namespace FATrace.OEMApp
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前登录用户
|
||||
/// </summary>
|
||||
public string CurUserName { get; set; }
|
||||
|
||||
#region 视频处理变量
|
||||
|
||||
/// <summary>
|
||||
/// 当前播放的视频
|
||||
/// </summary>
|
||||
public string CurrentVideoPath { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 内包信息
|
||||
|
||||
/// <summary>
|
||||
/// 内包条码
|
||||
/// </summary>
|
||||
public string CurInBagCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 内包条码 原料名称
|
||||
/// </summary>
|
||||
public string CurInBagRawName { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
private void btnNVRLogin_Click(object sender, EventArgs e)
|
||||
{
|
||||
//var Result = HkCameraClient.Login(new CameraLoginInfo()
|
||||
//{
|
||||
// IP = "192.168.1.168",
|
||||
// Port = 8000,
|
||||
// UserName = "admin",
|
||||
// Password = "glico@2025",
|
||||
//});
|
||||
HkCameraClient.NVR_IP = ConfigHelper.GetValue("NVRIP");
|
||||
HkCameraClient.NVR_Port = ushort.Parse(ConfigHelper.GetValue("NVRPort"));
|
||||
HkCameraClient.NVR_UserName = ConfigHelper.GetValue("NVRUserName");
|
||||
HkCameraClient.NVR_Pw = ConfigHelper.GetValue("NVRPw");
|
||||
|
||||
//if (Result)
|
||||
//{
|
||||
// MessageBox.Show("登录成功");
|
||||
// return;
|
||||
//}
|
||||
//MessageBox.Show("登录失败");
|
||||
|
||||
var result = HkCameraClient.Sdk_NET_DVR_Login_V30("192.168.1.168", 8000, "admin", "glico@2025");
|
||||
var result = HkCameraClient.Sdk_NET_DVR_Login_V30(HkCameraClient.NVR_IP, HkCameraClient.NVR_Port, HkCameraClient.NVR_UserName, HkCameraClient.NVR_Pw);
|
||||
if (result)
|
||||
{
|
||||
MessageBox.Show("登录成功");
|
||||
@@ -83,24 +122,35 @@ namespace FATrace.OEMApp
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
private void btnLoadVideo_Click(object sender, EventArgs e)
|
||||
{
|
||||
CurrentVideoPath = NVRCom.GetVideoName(HkCameraClient.NVRVideoSavePath, "CODE");
|
||||
|
||||
var Result = HkCameraClient.Sdk_NET_DVR_GetFileByTime_V40(DateTime.Now.AddMinutes(-5), DateTime.Now, $"D:\\Downtest_Channel{DateTime.Now.ToString("yyyy-MM-dd HHmmss")}.mp4");
|
||||
var Result = HkCameraClient.Sdk_NET_DVR_GetFileByTime_V40(DateTime.Now.AddMinutes(-5), DateTime.Now, CurrentVideoPath);
|
||||
if (Result.Result)
|
||||
{
|
||||
DownTimer.Interval = 2000;
|
||||
DownTimer.Enabled = true;
|
||||
HkCameraClient.NVRLoadVideoProcessEventHandler -= HkCameraClient_NVRLoadVideoProcessEventHandler;
|
||||
HkCameraClient.NVRLoadVideoProcessEventHandler += HkCameraClient_NVRLoadVideoProcessEventHandler;
|
||||
// 进度轮询已在库方法内部自动启动,这里无需再次调用
|
||||
HkCameraClient.StartDownloadProgressMonitor();
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"[Sdk_NET_DVR_GetFileByTime_V40] 执行失败:{Result.Msg}");
|
||||
}
|
||||
|
||||
|
||||
//btnStopDownload.Enabled = true;
|
||||
}
|
||||
|
||||
private void HkCameraClient_NVRLoadVideoProcessEventHandler(object? sender, short value)
|
||||
{
|
||||
this.BeginInvoke(new Action(() =>
|
||||
{
|
||||
DownloadProgressBarMain.Value = value;
|
||||
}));
|
||||
}
|
||||
|
||||
private void btnDownloadName_Click(object sender, EventArgs e)
|
||||
{
|
||||
//if (m_lDownHandle >= 0)
|
||||
@@ -151,59 +201,266 @@ namespace FATrace.OEMApp
|
||||
|
||||
private void btnStopLoadVideo_Click(object sender, EventArgs e)
|
||||
{
|
||||
//if (m_lDownHandle < 0)
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
//if (!CHCNetSDK.NET_DVR_StopGetFile(m_lDownHandle))
|
||||
//{
|
||||
// iLastErr = CHCNetSDK.NET_DVR_GetLastError();
|
||||
// str = "NET_DVR_StopGetFile failed, error code= " + iLastErr; //下载控制失败,输出错误号
|
||||
// MessageBox.Show(str);
|
||||
// return;
|
||||
//}
|
||||
|
||||
//timerDownload.Stop();
|
||||
|
||||
//MessageBox.Show("The downloading has been stopped succesfully!");
|
||||
//m_lDownHandle = -1;
|
||||
//DownloadProgressBar.Value = 0;
|
||||
//btnStopDownload.Enabled = true;
|
||||
var Result = HkCameraClient.Sdk_NET_DVR_StopGetFile();
|
||||
if (Result.Result)
|
||||
{
|
||||
MessageBox.Show($"[暂停成功] :{Result.Msg}");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"[暂停失败] :{Result.Msg}");
|
||||
}
|
||||
}
|
||||
|
||||
private void DownTimer_Tick(object sender, EventArgs e)
|
||||
#region 视频播放
|
||||
|
||||
private LibVLC _libVLC;
|
||||
private MediaPlayer _mediaPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化MediaPlay
|
||||
/// </summary>
|
||||
private void InitMediaPlayer()
|
||||
{
|
||||
DownloadProgressBar.Maximum = 100;
|
||||
DownloadProgressBar.Minimum = 0;
|
||||
_libVLC = new LibVLC();
|
||||
_mediaPlayer = new MediaPlayer(_libVLC);
|
||||
videoView1.MediaPlayer = _mediaPlayer;
|
||||
|
||||
int iPos = 0;
|
||||
}
|
||||
|
||||
//获取下载进度
|
||||
iPos = HkCameraClient.Sdk_NET_DVR_GetDownloadPos(HkCameraClient.m_lDownHandle);
|
||||
|
||||
if ((iPos > DownloadProgressBar.Minimum) && (iPos < DownloadProgressBar.Maximum))
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 测试手动播放
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void btnPlayHistoryVideo_Click(object sender, EventArgs e)
|
||||
{
|
||||
string path = "D:\\Downtest_Channel2025-09-12 102454.mp4";
|
||||
_mediaPlayer.Play(new Media(_libVLC, path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停止播放当前的视频文件
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void btnStopHistoryPlay_Click(object sender, EventArgs e)
|
||||
{
|
||||
_mediaPlayer.Stop();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理播放资源
|
||||
/// </summary>
|
||||
private void CleanMediaPlay()
|
||||
{
|
||||
_mediaPlayer.Stop();
|
||||
_mediaPlayer.Dispose();
|
||||
_libVLC.Dispose();
|
||||
}
|
||||
|
||||
|
||||
#region 历史数据查询
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 采用 BindingList + BindingSource,使数据变化自动触发 UI 刷新
|
||||
/// </summary>
|
||||
private BindingSource historyBindingSource { get; set; }
|
||||
private BindingList<VideoAction> historyVideoBindingList { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化历史记录表格的数据绑定
|
||||
/// </summary>
|
||||
private void InitHistoryGridBinding()
|
||||
{
|
||||
historyBindingSource = new BindingSource();
|
||||
historyVideoBindingList = new BindingList<VideoAction>();
|
||||
historyBindingSource.DataSource = historyVideoBindingList;
|
||||
// 绑定到 WinForms 原生 DataGridView
|
||||
dataGridView1.AutoGenerateColumns = true;
|
||||
dataGridView1.DataSource = historyBindingSource;
|
||||
// 绑定完成后统一调整列头与可见性
|
||||
dataGridView1.DataBindingComplete -= DataGridView1_DataBindingComplete;
|
||||
dataGridView1.DataBindingComplete += DataGridView1_DataBindingComplete;
|
||||
// 双击行播放对应视频
|
||||
dataGridView1.CellDoubleClick -= DataGridView1_CellDoubleClick;
|
||||
dataGridView1.CellDoubleClick += DataGridView1_CellDoubleClick;
|
||||
// 若此时已存在列,立即调整一次
|
||||
ConfigureHistoryGridColumns();
|
||||
}
|
||||
|
||||
|
||||
private void btnHistoryVideoSearch_Click(object sender, EventArgs e)
|
||||
{
|
||||
var query = FSqlContext.FDb.Select<VideoAction>();
|
||||
if (!string.IsNullOrEmpty(txtSearchCode.Text.Trim()))
|
||||
{
|
||||
DownloadProgressBar.Value = iPos;
|
||||
query = query.Where(a => a.Code!.Contains(txtSearchCode.Text.Trim()));
|
||||
}
|
||||
query.Where(a => a.CreateTime >= PdtHistorySearchStart.Value && a.CreateTime <= PdtHistorySearchEnd.Value);
|
||||
|
||||
if (iPos == 100) //下载完成
|
||||
// 拉取结果并刷新绑定列表
|
||||
var resultList = query.ToList();
|
||||
// 暂停变更通知,批量更新提高效率
|
||||
historyVideoBindingList.RaiseListChangedEvents = false;
|
||||
historyVideoBindingList.Clear();
|
||||
foreach (var item in resultList)
|
||||
{
|
||||
DownloadProgressBar.Value = iPos;
|
||||
if (!CHCNetSDK.NET_DVR_StopGetFile(HkCameraClient.m_lDownHandle))
|
||||
historyVideoBindingList.Add(item);
|
||||
}
|
||||
historyVideoBindingList.RaiseListChangedEvents = true;
|
||||
// 通知 UI 刷新
|
||||
historyVideoBindingList.ResetBindings();
|
||||
}
|
||||
|
||||
// 与历史记录表格列配置相关的成员(WinForms DataGridView)
|
||||
private void DataGridView1_DataBindingComplete(object? sender, DataGridViewBindingCompleteEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
ConfigureHistoryGridColumns();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 仅记录,不中断界面
|
||||
System.Diagnostics.Debug.WriteLine($"[DataBindingComplete] 列配置失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 双击行,播放该行对应的视频文件
|
||||
/// </summary>
|
||||
private void DataGridView1_CellDoubleClick(object? sender, DataGridViewCellEventArgs e)
|
||||
{
|
||||
if (e.RowIndex < 0) return; // 双击列头等
|
||||
try
|
||||
{
|
||||
var row = dataGridView1.Rows[e.RowIndex];
|
||||
if (row?.DataBoundItem is VideoAction va)
|
||||
{
|
||||
MessageBox.Show($"[NET_DVR_StopGetFile] 执行失败:{HkCameraClient.GetLastError()}");
|
||||
return;
|
||||
var path = va.VideoFilePath;
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
MessageBox.Show("该记录没有可播放的视频路径。", "播放提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
return;
|
||||
}
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
MessageBox.Show($"未找到视频文件:\n{path}", "播放失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
_mediaPlayer?.Stop();
|
||||
_mediaPlayer?.Play(new LibVLCSharp.Shared.Media(_libVLC, path));
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"播放失败: {ex.Message}", "播放失败", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 按照 _historyHeaderMap 配置列头、隐藏不需要的列,并做常用格式化
|
||||
/// </summary>
|
||||
private void ConfigureHistoryGridColumns()
|
||||
{
|
||||
if (dataGridView1 == null || dataGridView1.Columns.Count == 0) return;
|
||||
|
||||
foreach (DataGridViewColumn col in dataGridView1.Columns)
|
||||
{
|
||||
var propName = col.DataPropertyName;
|
||||
|
||||
// 设置列头中文
|
||||
if (!string.IsNullOrWhiteSpace(propName) && _historyHeaderMap.TryGetValue(propName, out var headerText))
|
||||
{
|
||||
col.HeaderText = headerText;
|
||||
}
|
||||
|
||||
// 隐藏 Id 列
|
||||
if (propName == nameof(VideoAction.Id))
|
||||
{
|
||||
col.Visible = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
//// 常用列宽与格式
|
||||
//if (propName is nameof(VideoAction.Code))
|
||||
//{
|
||||
// col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||||
//}
|
||||
//else if (propName is nameof(VideoAction.VideoFilePath))
|
||||
//{
|
||||
// col.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
|
||||
//}
|
||||
|
||||
// 时间列格式化
|
||||
if (propName is nameof(VideoAction.StartTime) or nameof(VideoAction.EndTime) or nameof(VideoAction.CreateTime))
|
||||
{
|
||||
col.DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss";
|
||||
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
|
||||
}
|
||||
HkCameraClient.m_lDownHandle = -1;
|
||||
DownTimer.Stop();
|
||||
}
|
||||
|
||||
if (iPos == 200) //网络异常,下载失败
|
||||
// 选中整行,易于操作
|
||||
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
|
||||
dataGridView1.MultiSelect = false;
|
||||
dataGridView1.ReadOnly = true;
|
||||
dataGridView1.AllowUserToAddRows = false;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 操作结束
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void btnTestAction_Click(object sender, EventArgs e)
|
||||
{
|
||||
var Result = HkCameraClient.Sdk_NET_DVR_GetFileByTime_V40(DateTime.Now.AddMinutes(-5), DateTime.Now, NVRCom.GetVideoName(HkCameraClient.NVRVideoSavePath, "cODE"));
|
||||
if (Result.Result)
|
||||
{
|
||||
MessageBox.Show("The downloading is abnormal for the abnormal network!");
|
||||
DownTimer.Stop();
|
||||
HkCameraClient.NVRLoadVideoProcessEventHandler -= HkCameraClient_NVRLoadVideoProcessEventHandler;
|
||||
HkCameraClient.NVRLoadVideoProcessEventHandler += HkCameraClient_NVRLoadVideoProcessEventHandler;
|
||||
|
||||
HkCameraClient.NVRLoadVideoCompleteEventHandler -= HkCameraClient_NVRLoadVideoCompleteEventHandler;
|
||||
HkCameraClient.NVRLoadVideoCompleteEventHandler += HkCameraClient_NVRLoadVideoCompleteEventHandler;
|
||||
|
||||
// 进度轮询已在库方法内部自动启动,这里无需再次调用
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show($"[Sdk_NET_DVR_GetFileByTime_V40] 执行失败:{Result.Msg}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the event triggered when the NVR (Network Video Recorder) completes loading a video.
|
||||
/// Video下载完成
|
||||
/// </summary>
|
||||
/// <param name="sender">The source of the event. This can be <see langword="null"/> if the event is not raised by a specific object.</param>
|
||||
/// <param name="e">A string containing information about the completed video load operation.</param>
|
||||
private void HkCameraClient_NVRLoadVideoCompleteEventHandler(object? sender, string e)
|
||||
{
|
||||
//先保存当前的信息
|
||||
var returnValues = FSqlContext.FDb.Insert<OEMRawUse>(new OEMRawUse()
|
||||
{
|
||||
InBagCode=CurInBagCode,
|
||||
RawName=CurInBagRawName,
|
||||
User= CurUserName,
|
||||
UrlState=false,
|
||||
VideoUrl="",//暂时无法获取URL,因为服务器还没有扫描到文件信息
|
||||
}).ExecuteInserted();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +117,9 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>134, 17</value>
|
||||
</metadata>
|
||||
<metadata name="imageList1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
@@ -124,8 +127,8 @@
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAfCEAAAJNU0Z0AUkBTAIBAQgB
|
||||
AAF4AQABeAEAARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAATADAAEBAQABIAYAATD/
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAaiEAAAJNU0Z0AUkBTAIBAQgB
|
||||
AAEwAQEBMAEBARABAAEQAQAE/wEhAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAATADAAEBAQABIAYAATD/
|
||||
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AFIAAdsBlgESAf8B2wGWARIB/wQAAxIBGANJAYgB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAHbAZYB
|
||||
@@ -159,120 +162,117 @@
|
||||
+QH/AgAC/wP1Af8CAAL/AgAC/wIAAv8CAAL/AgAC/wIAAv8CxwH2Af8D9QH/AgAC/wIAAfwB/wJoAe4B
|
||||
/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AlEBUAGfBAABkgF2AUQB8wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8B2wGWARIB/ywAAdsBlgESAf8B2wGWARIB
|
||||
/wNGAX8CAgFMAf8CAgHoAf8CAAHwAf8CiQH0Af8D9QH/AgAB9QH/AgAB9QH/A/UB/wIAAfUB/wIAAfUB
|
||||
/wP1Af8CAAH1Af8CAAHwAf8CBgHrAf8CYgHqAf8DKgFAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8DSQGIBAADBgEIAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/1AAAdsB
|
||||
lgESAf8B2wGWARIB/ywAAdsBlgESAf8B2wGWARIB/wNGAX8CAgFAAf8CIAHdAf8CCgHgAf8CAwHhAf8D
|
||||
9QH/AgMB4QH/AgMB4QH/A/UB/wIDAeEB/wP1Af8D9QH/AgMB4QH/AiAB5AH/AiAB3QH/AlsB5AH/BAAD
|
||||
CQEMAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/DAADDAEQAdsBlgESAf8B2wGWARIB/wFpAWMBWgHfFAAB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8DKAE8BAADUgGgAdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/wHbAZYB
|
||||
EgH/KAADHQEoAdsBlgESAf8B2wGWARIB/wNGAX8CAgE0Af8COAHUAf8COAHYAf8COAHbAf8CAwHRAf8D
|
||||
9QH/AgMB0QH/A/UB/wIDAdEB/wP1Af8CDQHSAf8COAHbAf8COAHYAf8COAHUAf8CVAHeAf8IAAHbAZYB
|
||||
EgH/AdsBlgESAf8UAAHbAZYBEgH/AdsBlgESAf8UAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/CAAB2wGWARIB/wHbAZYBEgH/DAAB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8MAAHbAZYBEgH/AdsBlgESAf8EAANGAX8CAgEpAf8CUQHNAf8CTwHUAf8C
|
||||
TwHVAf8CTwHVAf8D9QH/Ao0B4QH/Ak8B1QH/A/UB/wP1Af8CTwHVAf8CTwHVAf8CTwHUAf8CUQHNAf8C
|
||||
TAHXAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/DAAB2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8CXwFcAcgIAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAADRgF/AgEBHgH/AmgBzAH/AmgB0QH/AmgB
|
||||
0gH/AmgB0gH/AmgB0gH/A/UB/wJoAdIB/wP1Af8CaAHSAf8CaAHSAf8CaAHSAf8CaAHRAf8CaAHMAf8C
|
||||
QwHKAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8DUgGgDAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wwAAdsBlgESAf8MAAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wwAAdsBlgESAf8IAANGAX8CAQEUAf8CgAHOAf8CgAHRAf8CgAHSAf8CgAHSAf8C
|
||||
gAHSAf8D9QH/A/UB/wKAAdIB/wKAAdIB/wKAAdIB/wKAAdIB/wKAAdEB/wKAAc4B/wI5AboB/wQAAdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AlEBUAGfBAACbwFgAfMB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8sAAHbAZYBEgH/AdsBlgESAf8D
|
||||
RgF/AgIBTAH/AgIB6AH/AgAB8AH/AokB9AH/A/UB/wIAAfUB/wIAAfUB/wP1Af8CAAH1Af8CAAH1Af8D
|
||||
9QH/AgAB9QH/AgAB8AH/AgYB6wH/AmIB6gH/AyoBQAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/A0kBiAQAAwYBCAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf9QAAHbAZYB
|
||||
EgH/AdsBlgESAf8sAAHbAZYBEgH/AdsBlgESAf8DRgF/AgIBQAH/AiAB3QH/AgoB4AH/AgMB4QH/A/UB
|
||||
/wIDAeEB/wIDAeEB/wP1Af8CAwHhAf8D9QH/A/UB/wIDAeEB/wIgAeQB/wIgAd0B/wJbAeQB/wQAAwkB
|
||||
DAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wwAAwwBEAHbAZYBEgH/AdsBlgESAf8CYwFdAd8UAAHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wMoATwEAANSAaAB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8o
|
||||
AAMdASgB2wGWARIB/wHbAZYBEgH/A0YBfwICATQB/wI4AdQB/wI4AdgB/wI4AdsB/wIDAdEB/wP1Af8C
|
||||
AwHRAf8D9QH/AgMB0QH/A/UB/wINAdIB/wI4AdsB/wI4AdgB/wI4AdQB/wJUAd4B/wgAAdsBlgESAf8B
|
||||
2wGWARIB/xQAAdsBlgESAf8B2wGWARIB/xQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8cAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xgAAyoB
|
||||
PwIEAU8B/wKWAb8B/wKXAdYB/wKXAdYB/wKXAdYB/wKXAdYB/wKXAdYB/wP1Af8ClwHWAf8ClwHWAf8C
|
||||
lwHWAf8ClwHWAf8ClwHWAf8ClwHTAf8CCgF3Af8IAAMyAU8EAANaAb8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8DWgG/HAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8MAAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wwAAdsBlgESAf8B2wGWARIB/wQAA0YBfwICASkB/wJRAc0B/wJPAdQB/wJPAdUB
|
||||
/wJPAdUB/wP1Af8CjQHhAf8CTwHVAf8D9QH/A/UB/wJPAdUB/wJPAdUB/wJPAdQB/wJRAc0B/wJMAdcB
|
||||
/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/EAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/HAACCAFoAf8CVwFpAf8CrgHGAf8C
|
||||
rwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8CrwHeAf8C
|
||||
CAF1Af8CCgFuAf8UAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/yAAA1gBuAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/HAADIQEvAggBZgH/AggBawH/AggBbgH/AggBbgH/AggBbgH/AggBbgH/AggBbgH/AggBbgH/AggB
|
||||
bgH/AggBbgH/AggBbgH/AggBagH/AhABfgH/GAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8kAAJaAVgB
|
||||
twHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8MAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8DSQGHHAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8kAAMqAT8D
|
||||
RgF/A0YBfwNGAX8DRgF/A0YBfwNGAX8DRgF/A0YBfwNGAX9oAAJiAV0B3AHbAZYBEgH/AdsBlgESAf8D
|
||||
PQFoJAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xgAAwwB
|
||||
EAJHAUYBgAMtAUQUAAM6AWADOgFgbAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/HAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/GAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/CAACWwFZAcAB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/EAACWwFZAcAB2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8D
|
||||
KgFAGAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8YAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8BqQF9ATUB+BAAAaUBhQE3AfcB2wGWARIB/wwAAzMBUAHbAZYBEgH/BAAB
|
||||
2wGWARIB/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBQAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsB
|
||||
lgESAf8UAAHbAZYBEgH/BAAB2wGWARIB/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBAAAdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8QAAMSARgB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/xQAAdsBlgESAf8E
|
||||
AAHbAZYBEgH/EAAB2wGWARIB/xAAAlsBWQHACAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/BAACRwFGAYADKgFAEAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xQAAz0B
|
||||
aAHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AzoBYAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/GAADGAEgAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/EAAB2wGWARIB
|
||||
/wQAAdsBlgESAf8QAAHbAZYBEgH/EAACWwFZAcAgAAJHAUYBgAMqAUAQAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/ygAAdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/DAABdAFsAVcB5wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8E
|
||||
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAJbAVkBwAgAAdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AkcBRgGAAyoBQBAAAdsBlgESAf8B
|
||||
kwGAAUEB9ygAAdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/HAAB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf9QAAJbAVkBwCAAAkcBRgGAAyoBQBAAAdsBlgESAf8oAAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/HAAB2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8MAAJBAUABcAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAJbAVkBwAgAAlsBWQHAAlsBWQHAAlsB
|
||||
WQHADAACRwFGAYADKgFAGAAB2wGWARIB/wHbAZYBEgH/GAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8cAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/CAAB2wGWARIB/xAAAdsBlgESAf8EAAHbAZYBEgH/DAADKgFAAdsBlgESAf8Q
|
||||
AAJbAVkBwAgAAzoBYAM6AWADOgFgDAACRwFGAYADKgFAFAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8DDAEQAwYBCAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8UAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8EAAHbAZYBEgH/FAAB2wGWARIB/wQAAdsBlgESAf8QAAHbAZYBEgH/EAACWwFZAcAg
|
||||
AAJHAUYBgAMqAUAUAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
lgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wJfAVwByAgAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/CAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAANGAX8CAQEeAf8CaAHMAf8CaAHRAf8CaAHSAf8C
|
||||
aAHSAf8CaAHSAf8D9QH/AmgB0gH/A/UB/wJoAdIB/wJoAdIB/wJoAdIB/wJoAdEB/wJoAcwB/wJDAcoB
|
||||
/wQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wNSAaAMAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/DAAB2wGWARIB/wwAAdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/DAAB2wGWARIB/wgAA0YBfwIBARQB/wKAAc4B/wKAAdEB/wKAAdIB/wKAAdIB/wKAAdIB
|
||||
/wP1Af8D9QH/AoAB0gH/AoAB0gH/AoAB0gH/AoAB0gH/AoAB0QH/AoABzgH/AjkBugH/BAAB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8UAAHbAZYBEgH/BAAB
|
||||
2wGWARIB/xAAAdsBlgESAf8QAAJbAVkBwAJpAV0B6AMYASADGAEgAxgBIAMYASADGAEgAxgBIAMYASAB
|
||||
2wGWARIB/wMqAUAYAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/A1YBsAgAAdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/GAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8QAAHbAZYBEgH/AdsBlgESAf8QAAHbAZYBEgH/BAAB
|
||||
2wGWARIB/xAAAdsBlgESAf8UAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/yAAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/ygAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/xgAAdsBlgESAf8B2wGWARIB/wMqAUAB2wGWARIB/wHbAZYBEgH/CAAB
|
||||
2wGWARIB/wHbAZYBEgH/AWQBYQFbAdgCWwFZAcAB2wGWARIB/wHbAZYBEgH/YAAB2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/yQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/DAAB2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8YAAJHAUYBgAFpAWMBWgHfAlgBVgGzFAABaQFjAVoB3wFpAWMBWgHfAwYBCKAAAxgB
|
||||
IAwAAlEBUAGfVAABQgFNAT4HAAE+AwABKAMAAUADAAEwAwABAQEAAQEFAAGAAQEWAAP/gQAB/wHyAQAB
|
||||
gAH4AQ8BwAEBAf8BwAEAAYAB4AEDAYABAAH/AewBAAGAAcMB4wGAAQAB+AHMAQABgAHPAfkCAAH4AcAB
|
||||
AAGAAY8B+QIAAdABQwEAAYABnwH8AgABgAEPAoABnwH8AgABAgEHAv8BnwH8AgABhwEPAoABnwH4AgAB
|
||||
zwGfAQABgAHOATkCAAGHAQ8BAAGAAcYBMQIAAYIBBwEAAYAB7gE7AgABgAEPAQABgAH+AT8CAAHQAX8B
|
||||
AAGAAf4BPwGAAQAB+AH/AQABgAH+AT8BgAEBAfgB/wGBAcAB/gE/AeABBwL/Af4BHwHxAccB4wHnA/8B
|
||||
BwHwAQ8BwQGBAeABAwHxAYMB8AEHAZwBvQHvAfMB4QHBAYABAAG+Ab0B7wHzAcEB4QGDAcABvgG9AewB
|
||||
EwHDAeIBBwHgAd4BvQHvAfMBxwH+AccB8QHAAYMB7AEDAc8B/AHHAfEC/wHvAfMB3wH4AccB8QHAAYMB
|
||||
7AFzAfMB8AGHAfAB3gG5AewBcwHhAeABAwHgAb4BvQHvAfMB4AHBAYABAAG+Ab0B4AEDAfABYwHwAQcB
|
||||
ngG9AfABBwH4AT8B8AEPAcEBgQL/Af4BHwHxAccC4wT/Af0B3wL/Cw==
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/EAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/GAADKgE/AgQB
|
||||
TwH/ApYBvwH/ApcB1gH/ApcB1gH/ApcB1gH/ApcB1gH/ApcB1gH/A/UB/wKXAdYB/wKXAdYB/wKXAdYB
|
||||
/wKXAdYB/wKXAdYB/wKXAdMB/wIKAXcB/wgAAzIBTwQAA1oBvwHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wNaAb8cAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/HAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8cAAIIAWgB/wJXAWkB/wKuAcYB/wKvAd4B
|
||||
/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wKvAd4B/wIIAXUB
|
||||
/wIKAW4B/xQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/IAADWAG4AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8EAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/HAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8c
|
||||
AAMhAS8CCAFmAf8CCAFrAf8CCAFuAf8CCAFuAf8CCAFuAf8CCAFuAf8CCAFuAf8CCAFuAf8CCAFuAf8C
|
||||
CAFuAf8CCAFuAf8CCAFqAf8CEAF+Af8YAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/yQAAloBWAG3AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wwAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wNJAYccAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/yQAAyoBPwNGAX8D
|
||||
RgF/A0YBfwNGAX8DRgF/A0YBfwNGAX8DRgF/A0YBf2gAAmIBXQHcAdsBlgESAf8B2wGWARIB/wM9AWgk
|
||||
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wwAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/GAADDAEQAkcB
|
||||
RgGAAy0BRBQAAzoBYAM6AWBsAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8c
|
||||
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8YAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAJbAVkBwAHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8QAAJbAVkBwAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wMqAUAY
|
||||
AAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/xgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wJ8AVMB+BAAAXkBbwFRAfcB2wGWARIB/wwAAzMBUAHbAZYBEgH/BAAB2wGWARIB
|
||||
/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8MAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8U
|
||||
AAHbAZYBEgH/BAAB2wGWARIB/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoBQBAAAdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8QAAMSARgB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/xQAAdsBlgESAf8EAAHbAZYB
|
||||
EgH/EAAB2wGWARIB/xAAAlsBWQHACAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/BAACRwFGAYADKgFAEAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xQAAz0BaAHbAZYB
|
||||
EgH/AdsBlgESAf8EAAHbAZYBEgH/AzoBYAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/GAAD
|
||||
GAEgAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/EAAB2wGWARIB/wQAAdsB
|
||||
lgESAf8QAAHbAZYBEgH/EAACWwFZAcAgAAJHAUYBgAMqAUAQAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/ygAAdsBlgESAf8IAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/DAACZQFcAecB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/FAACWwFZAcAIAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wJHAUYBgAMqAUAQAAHbAZYBEgH/Am8BUQH3KAAB
|
||||
2wGWARIB/wHbAZYBEgH/CAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8cAAHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/1AAAlsBWQHAIAACRwFGAYADKgFAEAAB2wGWARIB/ygAAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/CAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8cAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wwAAkEB
|
||||
QAFwAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wQAAdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xQAAlsBWQHACAACWwFZAcACWwFZAcACWwFZAcAMAAJHAUYB
|
||||
gAMqAUAYAAHbAZYBEgH/AdsBlgESAf8YAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/xwAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8IAAHbAZYBEgH/EAAB2wGWARIB/wQAAdsBlgESAf8MAAMqAUAB2wGWARIB/xAAAlsBWQHACAAD
|
||||
OgFgAzoBYAM6AWAMAAJHAUYBgAMqAUAUAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/EAAB
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wMMARADBgEIAdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/xQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wQAAdsBlgESAf8UAAHbAZYBEgH/BAAB2wGWARIB/xAAAdsBlgESAf8QAAJbAVkBwCAAAkcBRgGAAyoB
|
||||
QBQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/BAAB2wGWARIB/xQAAdsBlgESAf8EAAHbAZYBEgH/EAAB
|
||||
2wGWARIB/xAAAlsBWQHAAmkBYAHoAxgBIAMYASADGAEgAxgBIAMYASADGAEgAxgBIAHbAZYBEgH/AyoB
|
||||
QBgAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8DVgGwCAAB2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8YAAHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/AdsBlgESAf8B2wGWARIB/xAAAdsBlgESAf8B2wGWARIB/xAAAdsBlgESAf8EAAHbAZYBEgH/EAAB
|
||||
2wGWARIB/xQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsB
|
||||
lgESAf8B2wGWARIB/wHbAZYBEgH/IAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYB
|
||||
EgH/KAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B2wGWARIB
|
||||
/wHbAZYBEgH/GAAB2wGWARIB/wHbAZYBEgH/AyoBQAHbAZYBEgH/AdsBlgESAf8IAAHbAZYBEgH/AdsB
|
||||
lgESAf8CXwFbAdgCWwFZAcAB2wGWARIB/wHbAZYBEgH/YAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8B
|
||||
2wGWARIB/yQAAdsBlgESAf8B2wGWARIB/wHbAZYBEgH/DAAB2wGWARIB/wHbAZYBEgH/AdsBlgESAf8Y
|
||||
AAJHAUYBgAJjAV0B3wJYAVYBsxQAAmMBXQHfAmMBXQHfAwYBCKAAAxgBIAwAAlEBUAGfVAABQgFNAT4H
|
||||
AAE+AwABKAMAAUADAAEwAwABAQEAAQEFAAGAAQEWAAP/gQAB/wHyAQABgAH4AQ8BwAEBAf8BwAEAAYAB
|
||||
4AEDAYABAAH/AewBAAGAAcMB4wGAAQAB+AHMAQABgAHPAfkCAAH4AcABAAGAAY8B+QIAAdABQwEAAYAB
|
||||
nwH8AgABgAEPAoABnwH8AgABAgEHAv8BnwH8AgABhwEPAoABnwH4AgABzwGfAQABgAHOATkCAAGHAQ8B
|
||||
AAGAAcYBMQIAAYIBBwEAAYAB7gE7AgABgAEPAQABgAH+AT8CAAHQAX8BAAGAAf4BPwGAAQAB+AH/AQAB
|
||||
gAH+AT8BgAEBAfgB/wGBAcAB/gE/AeABBwL/Af4BHwHxAccB4wHnA/8BBwHwAQ8BwQGBAeABAwHxAYMB
|
||||
8AEHAZwBvQHvAfMB4QHBAYABAAG+Ab0B7wHzAcEB4QGDAcABvgG9AewBEwHDAeIBBwHgAd4BvQHvAfMB
|
||||
xwH+AccB8QHAAYMB7AEDAc8B/AHHAfEC/wHvAfMB3wH4AccB8QHAAYMB7AFzAfMB8AGHAfAB3gG5AewB
|
||||
cwHhAeABAwHgAb4BvQHvAfMB4AHBAYABAAG+Ab0B4AEDAfABYwHwAQcBngG9AfABBwH4AT8B8AEPAcEB
|
||||
gQL/Af4BHwHxAccC4wT/Af0B3wL/Cw==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="DownTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>134, 17</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
|
||||
65
FATrace.OEMApp/Model/Jellyfin/JellyfinModels.cs
Normal file
65
FATrace.OEMApp/Model/Jellyfin/JellyfinModels.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace FATrace.OEMApp.Model.Jellyfin
|
||||
{
|
||||
/// <summary>
|
||||
/// Jellyfin /Items 接口响应模型
|
||||
/// </summary>
|
||||
public sealed class JellyfinItemsResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回的项目集合
|
||||
/// </summary>
|
||||
[JsonPropertyName("Items")]
|
||||
public List<JellyfinItem> Items { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 记录总数
|
||||
/// </summary>
|
||||
[JsonPropertyName("TotalRecordCount")]
|
||||
public int TotalRecordCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 起始索引
|
||||
/// </summary>
|
||||
[JsonPropertyName("StartIndex")]
|
||||
public int StartIndex { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Jellyfin 媒体条目最小字段模型
|
||||
/// </summary>
|
||||
public sealed class JellyfinItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[JsonPropertyName("Name")]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 服务器 ID
|
||||
/// </summary>
|
||||
[JsonPropertyName("ServerId")]
|
||||
public string? ServerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 项目 ID
|
||||
/// </summary>
|
||||
[JsonPropertyName("Id")]
|
||||
public string? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 频道 ID(可能为 null)
|
||||
/// </summary>
|
||||
[JsonPropertyName("ChannelId")]
|
||||
public string? ChannelId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 类型,如 Movie、Series
|
||||
/// </summary>
|
||||
[JsonPropertyName("Type")]
|
||||
public string? Type { get; set; }
|
||||
}
|
||||
}
|
||||
245
FATrace.OEMApp/Services/JellyfinClient.cs
Normal file
245
FATrace.OEMApp/Services/JellyfinClient.cs
Normal file
@@ -0,0 +1,245 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using FATrace.OEMApp.Model.Jellyfin;
|
||||
using NLog;
|
||||
using RestSharp;
|
||||
|
||||
namespace FATrace.OEMApp.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Jellyfin 客户端配置选项
|
||||
/// </summary>
|
||||
public sealed class JellyfinClientOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Jellyfin 基础地址,例如:http://192.168.0.30:8096
|
||||
/// </summary>
|
||||
public required string BaseUrl { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// API 密钥(建议使用 Jellyfin 后台创建的密钥)。
|
||||
/// </summary>
|
||||
public required string ApiKey { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 超时时间,毫秒。默认 10000 毫秒。
|
||||
/// </summary>
|
||||
public int TimeoutMs { get; init; } = 10000;
|
||||
|
||||
/// <summary>
|
||||
/// 是否将 api_key 作为查询参数传递。默认 true。
|
||||
/// 若为 false,则通过请求头 X-Emby-Token 传递。
|
||||
/// </summary>
|
||||
public bool UseQueryApiKey { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 自定义 User-Agent。若为空将使用默认。
|
||||
/// </summary>
|
||||
public string? UserAgent { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Jellyfin HTTP 异常
|
||||
/// </summary>
|
||||
public sealed class JellyfinHttpException : Exception
|
||||
{
|
||||
public HttpStatusCode StatusCode { get; }
|
||||
public string? ResponseContent { get; }
|
||||
|
||||
public JellyfinHttpException(string message, HttpStatusCode statusCode, string? content, Exception? inner = null)
|
||||
: base(message, inner)
|
||||
{
|
||||
StatusCode = statusCode;
|
||||
ResponseContent = content;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Jellyfin API 客户端封装(基于 RestSharp)
|
||||
/// </summary>
|
||||
public sealed class JellyfinClient : IJellyfinClient, IDisposable
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly RestClient _client;
|
||||
private readonly JellyfinClientOptions _options;
|
||||
private readonly JsonSerializerOptions _jsonOptions = new()
|
||||
{
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
|
||||
public JellyfinClient(JellyfinClientOptions options)
|
||||
{
|
||||
_options = options ?? throw new ArgumentNullException(nameof(options));
|
||||
if (string.IsNullOrWhiteSpace(_options.BaseUrl))
|
||||
throw new ArgumentException("BaseUrl 不能为空", nameof(options));
|
||||
if (string.IsNullOrWhiteSpace(_options.ApiKey))
|
||||
throw new ArgumentException("ApiKey 不能为空", nameof(options));
|
||||
|
||||
if (!Uri.TryCreate(_options.BaseUrl, UriKind.Absolute, out var baseUri))
|
||||
{
|
||||
throw new ArgumentException($"无效的 BaseUrl: {_options.BaseUrl}", nameof(options));
|
||||
}
|
||||
|
||||
var restOptions = new RestClientOptions(baseUri)
|
||||
{
|
||||
MaxTimeout = _options.TimeoutMs,
|
||||
ThrowOnAnyError = false,
|
||||
// UseUnsafeSerializer = false // 保持默认 System.Text.Json
|
||||
};
|
||||
|
||||
_client = new RestClient(restOptions);
|
||||
|
||||
// 默认头
|
||||
_client.AddDefaultHeader("Accept", "application/json");
|
||||
_client.AddDefaultHeader("Accept-Charset", "utf-8");
|
||||
if (!string.IsNullOrWhiteSpace(_options.UserAgent))
|
||||
{
|
||||
_client.AddDefaultHeader("User-Agent", _options.UserAgent);
|
||||
}
|
||||
|
||||
// 通过 Header 传递 Token(若未使用 Query)
|
||||
if (!_options.UseQueryApiKey)
|
||||
{
|
||||
_client.AddDefaultHeader("X-Emby-Token", _options.ApiKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取 Jellyfin Items 列表。
|
||||
/// </summary>
|
||||
/// <param name="parentId">父级目录/库 ID</param>
|
||||
/// <param name="sortBy">排序字段(默认 DateCreated)</param>
|
||||
/// <param name="sortOrder">排序方向(Ascending/Descending,默认 Descending)</param>
|
||||
/// <param name="limit">限制返回数量,默认 10</param>
|
||||
/// <param name="includeItemTypes">包含的类型(例如 Movie, Series),默认 Movie</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
public async Task<JellyfinItemsResponse> GetItemsAsync(
|
||||
string parentId,
|
||||
string sortBy = "DateCreated",
|
||||
string sortOrder = "Descending",
|
||||
int? limit = 10,
|
||||
string includeItemTypes = "Movie",
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(parentId))
|
||||
throw new ArgumentException("parentId 不能为空", nameof(parentId));
|
||||
|
||||
var request = new RestRequest("Items", Method.Get);
|
||||
request.AddQueryParameter("ParentId", parentId);
|
||||
if (!string.IsNullOrWhiteSpace(sortBy)) request.AddQueryParameter("SortBy", sortBy);
|
||||
if (!string.IsNullOrWhiteSpace(sortOrder)) request.AddQueryParameter("SortOrder", sortOrder);
|
||||
if (limit.HasValue && limit.Value > 0) request.AddQueryParameter("Limit", limit.Value.ToString());
|
||||
if (!string.IsNullOrWhiteSpace(includeItemTypes)) request.AddQueryParameter("IncludeItemTypes", includeItemTypes);
|
||||
|
||||
if (_options.UseQueryApiKey)
|
||||
{
|
||||
request.AddQueryParameter("api_key", _options.ApiKey);
|
||||
}
|
||||
|
||||
return await ExecuteAndDeserializeAsync<JellyfinItemsResponse>(request, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 仅返回 Items 列表的便捷方法。
|
||||
/// </summary>
|
||||
public async Task<System.Collections.Generic.IReadOnlyList<JellyfinItem>> GetItemsOnlyAsync(
|
||||
string parentId,
|
||||
string sortBy = "DateCreated",
|
||||
string sortOrder = "Descending",
|
||||
int? limit = 10,
|
||||
string includeItemTypes = "Movie",
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var resp = await GetItemsAsync(parentId, sortBy, sortOrder, limit, includeItemTypes, cancellationToken).ConfigureAwait(false);
|
||||
return resp.Items ?? new System.Collections.Generic.List<JellyfinItem>();
|
||||
}
|
||||
|
||||
private async Task<T> ExecuteAndDeserializeAsync<T>(RestRequest request, CancellationToken ct)
|
||||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
Logger.Info("Jellyfin 请求: {Method} {Resource}", request.Method, request.Resource);
|
||||
|
||||
var response = await _client.ExecuteAsync(request, ct).ConfigureAwait(false);
|
||||
sw.Stop();
|
||||
|
||||
if (!response.IsSuccessful)
|
||||
{
|
||||
Logger.Warn("Jellyfin 响应失败: Status={StatusCode}, Elapsed={Elapsed}ms, ContentLength={Length}",
|
||||
(int)response.StatusCode, sw.ElapsedMilliseconds, response.Content?.Length ?? 0);
|
||||
|
||||
throw new JellyfinHttpException(
|
||||
$"请求失败,HTTP {(int)response.StatusCode} {response.StatusDescription}",
|
||||
response.StatusCode,
|
||||
response.Content,
|
||||
response.ErrorException);
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(response.Content))
|
||||
{
|
||||
throw new JellyfinHttpException("响应内容为空", response.StatusCode, null);
|
||||
}
|
||||
|
||||
var result = JsonSerializer.Deserialize<T>(response.Content, _jsonOptions);
|
||||
if (result == null)
|
||||
{
|
||||
throw new JellyfinHttpException("响应反序列化失败,返回结果为 null", response.StatusCode, response.Content);
|
||||
}
|
||||
|
||||
Logger.Debug("Jellyfin 调用成功: {Method} {Resource}, Elapsed={Elapsed}ms", request.Method, request.Resource, sw.ElapsedMilliseconds);
|
||||
return result;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
sw.Stop();
|
||||
Logger.Warn("Jellyfin 请求被取消: {Resource}, Elapsed={Elapsed}ms", request.Resource, sw.ElapsedMilliseconds);
|
||||
throw;
|
||||
}
|
||||
catch (JellyfinHttpException)
|
||||
{
|
||||
// 已包含上下文,直接抛出
|
||||
throw;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
sw.Stop();
|
||||
Logger.Error(ex, "Jellyfin 请求异常: {Resource}, Elapsed={Elapsed}ms", request.Resource, sw.ElapsedMilliseconds);
|
||||
throw new JellyfinHttpException("请求执行异常", HttpStatusCode.InternalServerError, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// RestClient 在新版本基于 HttpClient,通常无需显式释放。
|
||||
// 如需自定义 HttpMessageHandler,可在此释放。
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Jellyfin 客户端接口,便于后续依赖注入与单元测试。
|
||||
/// </summary>
|
||||
public interface IJellyfinClient
|
||||
{
|
||||
Task<JellyfinItemsResponse> GetItemsAsync(
|
||||
string parentId,
|
||||
string sortBy = "DateCreated",
|
||||
string sortOrder = "Descending",
|
||||
int? limit = 10,
|
||||
string includeItemTypes = "Movie",
|
||||
CancellationToken cancellationToken = default);
|
||||
|
||||
Task<System.Collections.Generic.IReadOnlyList<JellyfinItem>> GetItemsOnlyAsync(
|
||||
string parentId,
|
||||
string sortBy = "DateCreated",
|
||||
string sortOrder = "Descending",
|
||||
int? limit = 10,
|
||||
string includeItemTypes = "Movie",
|
||||
CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user