diff --git a/Cis.Application/Core/Center/CameraDataCenter.cs b/Cis.Application/Core/Center/CameraDataCenter.cs index fb20e6e..6dfef8b 100644 --- a/Cis.Application/Core/Center/CameraDataCenter.cs +++ b/Cis.Application/Core/Center/CameraDataCenter.cs @@ -1,312 +1,317 @@ using Cis.Application.Cb; using Cis.Application.Cm; using Cis.Application.Tb; +using Microsoft.Extensions.Logging; using System.Collections.Concurrent; namespace Cis.Application.Core; public class CameraDataCenter { - #region Attr - - private readonly SqlSugarRepository _cbCameraRep; - private readonly SqlSugarRepository _cmMarkLableRep; - private readonly SqlSugarRepository _tbPtzCameraRep; - private readonly PtzServerApi _ptzServerApi; - private readonly CameraDataOptions options = App.GetOptions(); - - private Thread _thread { get; set; } - - /// - /// (cbCameraId, cbCameraIp) - /// - private Dictionary _cbCameraId2IpDict { get; set; } = new(); - - /// - /// (cameraIp, TbPtzCamera) - /// - private ConcurrentDictionary _tbPtzCameraDict { get; set; } = new(); - - /// - /// (cameraIp, PtzInfo) - /// - private ConcurrentDictionary _cameraPtzInfoDict { get; set; } = new(); - - /// - /// _markSearcherDict 锁对象,写锁 - /// - private static ReaderWriterLockSlim msDictLock { get; } = new(); - - /// - /// (cbCameraId, MarkSearcherBase) - /// - private ConcurrentDictionary _markSearcherDict { get; set; } = new(); - - /// - /// (cameraId, List(MarkLabelCalcResult)) - /// - - private ConcurrentDictionary> _markLabelCalcResultListDict { get; set; } = new(); - - #endregion Attr - - public CameraDataCenter() - { - _cbCameraRep = App.GetService>(); - _cmMarkLableRep = App.GetService>(); - _tbPtzCameraRep = App.GetService>(); - _ptzServerApi = App.GetService(); - Init(); - } - - private void Init() - { - if (!options.LazyInit) - { - List list = _tbPtzCameraRep.GetList(); - // 根据 Ip 去重 - foreach (TbPtzCamera item in list) - { - if (!_tbPtzCameraDict.ContainsKey(item.Ip)) - _tbPtzCameraDict[item.Ip] = item; - } - } - - // 初始化 thread - _thread = new Thread(WorkLoop) - { - IsBackground = true// 设置后台线程 - }; - _thread.Start(); - } - - #region Loop - - /// - /// 循环运行 - /// - private void WorkLoop() - { - while (true) - { - RefreshPtzInfoByApi(); - RefreshMarkSearcher(); - Thread.Sleep(options.LoopInterval); - } - } - - private void RefreshPtzInfoByApi() - { - foreach (TbPtzCamera item in _tbPtzCameraDict.Values) - { - PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId); - _cameraPtzInfoDict[item.Ip] = ptzInfo; - } - } - - private void RefreshMarkSearcher() - { - foreach (KeyValuePair pair in _markSearcherDict) - { - long cameraId = pair.Key; - MarkSearcherBase markSearcher = pair.Value; - bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp); - if (!ret) continue; - ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo); - if (!ret) continue; - markSearcher.UpdateCameraCalcInfo(ptzInfo); - List resultList = markSearcher.Calc(); - _markLabelCalcResultListDict[cameraId] = resultList; - } - } - - #endregion Loop - - #region external call - - /// - /// 激活 cbCamera 进入运算 - /// - /// - /// - public bool ActivateSearcher(long cameraId) - { - try - { - msDictLock.EnterWriteLock(); - if (_markSearcherDict.ContainsKey(cameraId)) - return false; - // 获取 cbCamera - CbCamera cbCamera = _cbCameraRep.GetById(cameraId); - if (cbCamera == null) return false; - // 获取 tbPtzCamera - string cameraIp = cbCamera.Ip; - bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera); - if (!ret) - { - tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); - if (tbPtzCamera == null) return false; - _tbPtzCameraDict[cameraIp] = tbPtzCamera; - } - // 存储 cbCamera id 对应 ip 关系 - _cbCameraId2IpDict[cbCamera.Id] = cameraIp; - // 创建 cameraCalcInfo - CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); - // 创建 markSeacher - HikMarkSeacher markSeacher = new(cameraCalcInfo); - // 获取 cmMarkLabel 列表 - List cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); - // 将 cmMarkLabel 一一添加到 markSeacher - foreach (CmMarkLabel item in cmMarkLabelList) - { - MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( - item.Id, - PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition), - item.VideoWidth, - item.VideoHeight, - item.CanvasLeftRatio, - item.CanvasTopRatio - ); - markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); - } - // 将 markSeacher 放入字典 - _markSearcherDict[cameraId] = markSeacher; - } - finally - { - msDictLock.ExitWriteLock(); - } - return true; - } - - /// - /// 解除 cbCamera 进入运算 - /// - /// - /// - public bool DeActivateSearcher(long cameraId) - { - try - { - msDictLock.EnterWriteLock(); - _markSearcherDict.Remove(cameraId); - _markLabelCalcResultListDict.Remove(cameraId); - } - finally - { - msDictLock.ExitWriteLock(); - } - return true; - } - - public bool IsExistSearcher(long cameraId) - { - return _markSearcherDict.ContainsKey(cameraId); - } - - public bool ActivateMarkLabel(long cameraId, long markLabelId) - { - bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); - if (!ret) - return false; - if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId)) - return false; - CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId); - if (label == null) - return false; - MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( - label.Id, - PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition), - label.VideoWidth, - label.VideoHeight, - label.CanvasLeftRatio, - label.CanvasTopRatio - ); - return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); - } - - public bool DectivateMarkLabel(long cameraId, long markLabelId) - { - bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); - return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false; - } - - public bool IsExistCameraMarkLabel(long cameraId, long markLabelId) - { - bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) && - markSearcher.ExistsMarkLabelCalcInfo(markLabelId); - return ret; - } - - public List GetMarkLabelCalcResultList(long cameraId) - { - bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List list); - return ret ? list : new(); - } - - public PtzInfo GetCameraPtzInfo(long cameraId) - { - PtzInfo ptzInfo = null; - bool ret = _cbCameraId2IpDict.TryGetValue(cameraId,out string cameraIp) && - _cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo); - return ret ? ptzInfo : null; - } - - public async Task ActivateSearcherAsync(long cameraId) - { - return await Task.Run(() => - { - return ActivateSearcher(cameraId); - }); - } - - public async Task DeActivateSearcherAsync(long cameraId) - { - return await Task.Run(() => - { - return DeActivateSearcher(cameraId); - }); - } - - public async Task IsExistSearcherAsync(long cameraId) - { - return await Task.Run(() => - { - return IsExistSearcher(cameraId); - }); - } - - public async Task ActivateMarkLabelAsync(long cameraId, long markLabelId) - { - return await Task.Run(() => - { - return ActivateMarkLabel(cameraId, markLabelId); - }); - } - - public async Task DeactivateMarkLabelAsync(long cameraId, long markLabelId) - { - return await Task.Run(() => - { - return DectivateMarkLabel(cameraId, markLabelId); - }); - } - - public async Task IsExistMarkLabelAysnc(long cameraId, long markLabelId) - { - return await Task.Run(() => - { - return IsExistCameraMarkLabel(cameraId, markLabelId); - }); - } - - public async Task> GetMarkLabelCalcResultListAsync(long cameraId) - { - return await Task.Run(() => - { - return GetMarkLabelCalcResultList(cameraId); - }); - } - - #endregion external call + #region Attr + + private readonly SqlSugarRepository _cbCameraRep; + private readonly SqlSugarRepository _cmMarkLableRep; + private readonly SqlSugarRepository _tbPtzCameraRep; + private readonly PtzServerApi _ptzServerApi; + private readonly CameraDataOptions options; + + private Thread _thread { get; set; } + + /// + /// (cbCameraId, cbCameraIp) + /// + private Dictionary _cbCameraId2IpDict { get; set; } = new(); + + /// + /// (cameraIp, TbPtzCamera) + /// + private ConcurrentDictionary _tbPtzCameraDict { get; set; } = new(); + + /// + /// (cameraIp, PtzInfo) + /// + private ConcurrentDictionary _cameraPtzInfoDict { get; set; } = new(); + + /// + /// _markSearcherDict 锁对象,写锁 + /// + private static ReaderWriterLockSlim msDictLock { get; } = new(); + + /// + /// (cbCameraId, MarkSearcherBase) + /// + private ConcurrentDictionary _markSearcherDict { get; set; } = new(); + + /// + /// (cameraId, List(MarkLabelCalcResult)) + /// + + private ConcurrentDictionary> _markLabelCalcResultListDict { get; set; } = new(); + + #endregion Attr + + private readonly ILogger _logger; + + public CameraDataCenter() + { + _cbCameraRep = App.GetService>(); + _cmMarkLableRep = App.GetService>(); + _tbPtzCameraRep = App.GetService>(); + _ptzServerApi = App.GetService(); + options = App.GetOptions(); + _logger = App.GetService>(); + Init(); + } + + private void Init() + { + if (!options.LazyInit) + { + List list = _tbPtzCameraRep.GetList(); + // 根据 Ip 去重 + foreach (TbPtzCamera item in list) + { + if (!_tbPtzCameraDict.ContainsKey(item.Ip)) + _tbPtzCameraDict[item.Ip] = item; + } + } + + // 初始化 thread + _thread = new Thread(WorkLoop) + { + IsBackground = true// 设置后台线程 + }; + _thread.Start(); + } + + #region Loop + + /// + /// 循环运行 + /// + private void WorkLoop() + { + while (true) + { + RefreshPtzInfoByApi(); + RefreshMarkSearcher(); + Thread.Sleep(options.LoopInterval); + } + } + + private void RefreshPtzInfoByApi() + { + foreach (TbPtzCamera item in _tbPtzCameraDict.Values) + { + PtzInfo ptzInfo = _ptzServerApi.GetPtzInfo(item.CameraId); + _cameraPtzInfoDict[item.Ip] = ptzInfo; + } + } + + private async void RefreshMarkSearcher() + { + foreach (KeyValuePair pair in _markSearcherDict) + { + long cameraId = pair.Key; + MarkSearcherBase markSearcher = pair.Value; + bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp); + if (!ret) continue; + ret = _cameraPtzInfoDict.TryGetValue(cameraIp, out PtzInfo ptzInfo); + if (!ret) continue; + markSearcher.UpdateCameraCalcInfo(ptzInfo); + List resultList = await markSearcher.CalcAsync(); + _markLabelCalcResultListDict[cameraId] = resultList; + } + } + + #endregion Loop + + #region external call + + /// + /// 激活 cbCamera 进入运算 + /// + /// + /// + public bool ActivateSearcher(long cameraId) + { + try + { + msDictLock.EnterWriteLock(); + if (_markSearcherDict.ContainsKey(cameraId)) + return false; + // 获取 cbCamera + CbCamera cbCamera = _cbCameraRep.GetById(cameraId); + if (cbCamera == null) return false; + // 获取 tbPtzCamera + string cameraIp = cbCamera.Ip; + bool ret = _tbPtzCameraDict.TryGetValue(cameraIp, out TbPtzCamera tbPtzCamera); + if (!ret) + { + tbPtzCamera = _tbPtzCameraRep.GetFirst(u => u.Ip == cameraIp); + if (tbPtzCamera == null) return false; + _tbPtzCameraDict[cameraIp] = tbPtzCamera; + } + // 存储 cbCamera id 对应 ip 关系 + _cbCameraId2IpDict[cbCamera.Id] = cameraIp; + // 创建 cameraCalcInfo + CameraCalcInfo cameraCalcInfo = CameraCalcInfo.New(cameraId, _ptzServerApi.GetPtzInfo(tbPtzCamera.Id)); + // 创建 markSeacher + HikMarkSeacher markSeacher = new(cameraCalcInfo); + // 获取 cmMarkLabel 列表 + List cmMarkLabelList = _cmMarkLableRep.GetList(u => u.CbCameraId == cameraId); + // 将 cmMarkLabel 一一添加到 markSeacher + foreach (CmMarkLabel item in cmMarkLabelList) + { + MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( + item.Id, + PtzInfo.New(item.PanPosition, item.TiltPosition, item.ZoomPosition), + item.VideoWidth, + item.VideoHeight, + item.CanvasLeftRatio, + item.CanvasTopRatio + ); + markSeacher.AddMarkLabelCalcInfo(markLabelCalcInfo); + } + // 将 markSeacher 放入字典 + _markSearcherDict[cameraId] = markSeacher; + } + finally + { + msDictLock.ExitWriteLock(); + } + return true; + } + + /// + /// 解除 cbCamera 进入运算 + /// + /// + /// + public bool DeActivateSearcher(long cameraId) + { + try + { + msDictLock.EnterWriteLock(); + _markSearcherDict.Remove(cameraId); + _markLabelCalcResultListDict.Remove(cameraId); + } + finally + { + msDictLock.ExitWriteLock(); + } + return true; + } + + public bool IsExistSearcher(long cameraId) + { + return _markSearcherDict.ContainsKey(cameraId); + } + + public bool ActivateMarkLabel(long cameraId, long markLabelId) + { + bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); + if (!ret) + return false; + if (markSearcher.ExistsMarkLabelCalcInfo(markLabelId)) + return false; + CmMarkLabel label = _cmMarkLableRep.GetById(markLabelId); + if (label == null) + return false; + MarkLabelCalcInfo markLabelCalcInfo = MarkLabelCalcInfo.New( + label.Id, + PtzInfo.New(label.PanPosition, label.TiltPosition, label.ZoomPosition), + label.VideoWidth, + label.VideoHeight, + label.CanvasLeftRatio, + label.CanvasTopRatio + ); + return markSearcher.AddMarkLabelCalcInfo(markLabelCalcInfo); + } + + public bool DectivateMarkLabel(long cameraId, long markLabelId) + { + bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher); + return ret ? markSearcher.DeleteMarkLabelCalcInfo(markLabelId) : false; + } + + public bool IsExistCameraMarkLabel(long cameraId, long markLabelId) + { + bool ret = _markSearcherDict.TryGetValue(cameraId, out MarkSearcherBase markSearcher) && + markSearcher.ExistsMarkLabelCalcInfo(markLabelId); + return ret; + } + + public List GetMarkLabelCalcResultList(long cameraId) + { + bool ret = _markLabelCalcResultListDict.TryGetValue(cameraId, out List list); + return ret ? list : new(); + } + + public PtzInfo GetCameraPtzInfo(long cameraId) + { + PtzInfo ptzInfo = null; + bool ret = _cbCameraId2IpDict.TryGetValue(cameraId, out string cameraIp) && + _cameraPtzInfoDict.TryGetValue(cameraIp, out ptzInfo); + return ret ? ptzInfo : null; + } + + public async Task ActivateSearcherAsync(long cameraId) + { + return await Task.Run(() => + { + return ActivateSearcher(cameraId); + }); + } + + public async Task DeActivateSearcherAsync(long cameraId) + { + return await Task.Run(() => + { + return DeActivateSearcher(cameraId); + }); + } + + public async Task IsExistSearcherAsync(long cameraId) + { + return await Task.Run(() => + { + return IsExistSearcher(cameraId); + }); + } + + public async Task ActivateMarkLabelAsync(long cameraId, long markLabelId) + { + return await Task.Run(() => + { + return ActivateMarkLabel(cameraId, markLabelId); + }); + } + + public async Task DeactivateMarkLabelAsync(long cameraId, long markLabelId) + { + return await Task.Run(() => + { + return DectivateMarkLabel(cameraId, markLabelId); + }); + } + + public async Task IsExistMarkLabelAysnc(long cameraId, long markLabelId) + { + return await Task.Run(() => + { + return IsExistCameraMarkLabel(cameraId, markLabelId); + }); + } + + public async Task> GetMarkLabelCalcResultListAsync(long cameraId) + { + return await Task.Run(() => + { + return GetMarkLabelCalcResultList(cameraId); + }); + } + + #endregion external call } \ No newline at end of file diff --git a/Cis.Application/GlobalUsings.cs b/Cis.Application/GlobalUsings.cs index 76b15eb..9320314 100644 --- a/Cis.Application/GlobalUsings.cs +++ b/Cis.Application/GlobalUsings.cs @@ -3,6 +3,7 @@ global using Furion; global using Furion.ConfigurableOptions; global using Furion.DependencyInjection; global using Furion.DynamicApiController; +global using Furion.FriendlyException; global using Microsoft.AspNetCore.Mvc; global using SqlSugar; global using System.ComponentModel.DataAnnotations; \ No newline at end of file diff --git a/Cis.Application/Startup.cs b/Cis.Application/Startup.cs index 167af63..bc134be 100644 --- a/Cis.Application/Startup.cs +++ b/Cis.Application/Startup.cs @@ -17,8 +17,8 @@ public class Startup : AppStartup services.AddConfigurableOptions(); services.AddConfigurableOptions(); - services.AddSingleton(new CameraDataCenter()); - } + services.AddSingleton(new CameraDataCenter()); + } /// /// 配置应用请求处理管道 diff --git a/Cis.Application/Sys/Common/SysInfo.cs b/Cis.Application/Sys/Common/SysInfo.cs index dbeea07..f68a522 100644 --- a/Cis.Application/Sys/Common/SysInfo.cs +++ b/Cis.Application/Sys/Common/SysInfo.cs @@ -10,7 +10,7 @@ public class SysInfo /// /// Api 分组名 /// - public const string GroupName = "Sys"; + public const string GroupName = "System"; /// /// Api 分组排序 diff --git a/Cis.Web.Entry/Program.cs b/Cis.Web.Entry/Program.cs index 611ed5a..d4212d2 100644 --- a/Cis.Web.Entry/Program.cs +++ b/Cis.Web.Entry/Program.cs @@ -1 +1,13 @@ -Serve.Run(RunOptions.Default.WithArgs(args)); \ No newline at end of file +Serve.Run(RunOptions.Default.AddWebComponent().WithArgs(args)); + +public class WebComponent : IWebComponent +{ + public void Load(WebApplicationBuilder builder, ComponentContext componentContext) + { + // ־ + builder.Logging.AddFilter((provider, category, logLevel) => + { + return !new[] { "Microsoft.Hosting", "Microsoft.AspNetCore" }.Any(u => category.StartsWith(u)) && logLevel >= LogLevel.Information; + }); + } +} \ No newline at end of file