From 0f0d0c6a9b82083edb6d0361721931f573a0c049 Mon Sep 17 00:00:00 2001 From: g82tt Date: Sat, 16 May 2026 23:24:41 +0800 Subject: [PATCH] Phase0_Day2_volpro_side --- .../Partial/base_deviceController.cs | 138 ++++++++++++ .../Partial/gateway_nodesController.cs | 209 ++++++++++++++++++ .../Warehouse/Partial/iot_alarmController.cs | 33 +++ .../Partial/iot_devicedataController.cs | 33 +++ .../Partial/video_channelController.cs | 33 +++ .../Partial/video_recordController.cs | 33 +++ .../Warehouse/Services/GatewayClient.cs | 53 +++++ .../Warehouse/Services/HeartbeatMonitorJob.cs | 26 +++ .../Warehouse/Services/SyncDevicesJob.cs | 27 +++ .../Partial/base_deviceService.cs | 41 ++++ .../Partial/gateway_nodesService.cs | 41 ++++ .../Partial/iot_alarmService.cs | 41 ++++ .../Partial/iot_devicedataService.cs | 41 ++++ .../Partial/video_channelService.cs | 41 ++++ .../Partial/video_recordService.cs | 41 ++++ .../device_manager/base_deviceService.cs | 22 ++ .../device_manager/gateway_nodesService.cs | 22 ++ .../device_manager/iot_alarmService.cs | 22 ++ .../device_manager/iot_devicedataService.cs | 22 ++ .../device_manager/video_channelService.cs | 22 ++ .../device_manager/video_recordService.cs | 22 ++ 21 files changed, 963 insertions(+) create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/base_deviceController.cs create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/gateway_nodesController.cs create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_alarmController.cs create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_devicedataController.cs create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_channelController.cs create mode 100644 api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_recordController.cs create mode 100644 api_sqlsugar/Warehouse/Services/GatewayClient.cs create mode 100644 api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs create mode 100644 api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/base_deviceService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/gateway_nodesService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_alarmService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_devicedataService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/video_channelService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/Partial/video_recordService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/base_deviceService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/gateway_nodesService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/iot_alarmService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/iot_devicedataService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/video_channelService.cs create mode 100644 api_sqlsugar/Warehouse/Services/device_manager/video_recordService.cs diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/base_deviceController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/base_deviceController.cs new file mode 100644 index 0000000..23cae46 --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/base_deviceController.cs @@ -0,0 +1,138 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("base_device",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class base_deviceController + { + private readonly Ibase_deviceService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public base_deviceController( + Ibase_deviceService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + [ActivatorUtilitiesConstructor] + public base_deviceController( + Ibase_deviceService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + + private Iwarehouse_regionsService GetRegionService() => + _service.ServiceProvider.GetService(); + private Iwarehouse_devicepointService GetPointService() => + _service.ServiceProvider.GetService(); + + /// 区域树 (区域→点位→设备数量) + [HttpGet] + [Route("/api/DeviceManager/GetRegionTree")] + public async Task GetRegionTree() + { + var regions = await GetRegionService().FindAsIQueryable(x => true) + .Select(x => new { x.RegionsId, x.RegionsName, x.ParentId }) + .ToListAsync(); + var points = await GetPointService().FindAsIQueryable(x => true) + .Select(x => new { x.DevicePointId, x.DevicePointName, x.RegionId }) + .ToListAsync(); + var deviceCounts = await _service.FindAsIQueryable(x => true) + .GroupBy(x => x.PointId) + .Select(g => new { PointId = g.Key, Count = g.Count() }) + .ToListAsync(); + + return Ok(BuildRegionTree(regions, points, deviceCounts)); + } + + private List BuildRegionTree( + List regions, List points, List deviceCounts) + { + var pointMap = points.GroupBy(p => (int?)p.RegionId) + .ToDictionary(g => g.Key ?? 0, g => g.ToList()); + var countMap = deviceCounts.ToDictionary(c => c.PointId ?? 0, c => c.Count); + + return regions.Where(r => r.ParentId == null || r.ParentId == 0).Select(r => + BuildNode(r, regions, pointMap, countMap)).ToList(); + } + + private RegionTreeNode BuildNode(dynamic region, List allRegions, + Dictionary> pointMap, Dictionary countMap) + { + int rid = (int)region.RegionsId; + pointMap.TryGetValue(rid, out var pts); + var children = allRegions.Where(r => (int?)r.ParentId == rid).Select(r => + BuildNode(r, allRegions, pointMap, countMap)).ToList(); + + var pointNodes = pts?.Select(p => new RegionTreeNode + { + Id = $"p_{(int)p.DevicePointId}", + Label = (string)p.DevicePointName, + Type = "point", + DeviceCount = countMap.GetValueOrDefault((int)p.DevicePointId, 0) + }).ToList() ?? new List(); + + children.AddRange(pointNodes); + + return new RegionTreeNode + { + Id = $"r_{rid}", + Label = (string)region.RegionsName, + Type = "region", + DeviceCount = children.Sum(c => c.DeviceCount), + Children = children + }; + } + + /// 点位下设备列表(含子设备) + [HttpGet] + [Route("/api/DeviceManager/GetDevicesByPoint")] + public async Task GetDevicesByPoint([FromQuery] int pointId, [FromQuery] int page = 1, [FromQuery] int size = 20) + { + var query = _service.FindAsIQueryable(x => x.PointId == pointId); + var total = await query.CountAsync(); + var items = await query.Skip((page - 1) * size).Take(size).ToListAsync(); + return Ok(new { items, total }); + } + + /// 获取网关所管的顶层设备 (供 Register 调用) + internal async Task> GetDevicesForGateway(int nodeId) + { + var items = await _service.FindAsIQueryable(x => x.GatewayNodeId == nodeId && x.ParentDeviceId == null) + .Select(x => new { + x.DeviceId, x.DeviceName, x.AdapterCode, x.SourceId, + x.DeviceCategory, x.DeviceGroup, x.IsParent, x.IsOnline, + x.ExtraData + }).ToListAsync(); + return items.Select(x => (object)x).ToList(); + } + } + + public class RegionTreeNode + { + public string Id { get; set; } = ""; + public string Label { get; set; } = ""; + public string Type { get; set; } = ""; + public int DeviceCount { get; set; } + public List Children { get; set; } = new(); + } +} diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/gateway_nodesController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/gateway_nodesController.cs new file mode 100644 index 0000000..d8be251 --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/gateway_nodesController.cs @@ -0,0 +1,209 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("gateway_nodes",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class gateway_nodesController + { + private readonly Igateway_nodesService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public gateway_nodesController( + Igateway_nodesService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + [ActivatorUtilitiesConstructor] + public gateway_nodesController( + Igateway_nodesService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + + /// A1: 网关注册 (Upsert) + [HttpPost] + [Route("/api/gateway/register")] + public async Task RegisterGateway([FromBody] GatewayRegisterRequest req) + { + if (string.IsNullOrEmpty(req.NodeCode) || string.IsNullOrEmpty(req.Token)) + return BadRequest(new { message = "NodeCode and Token required" }); + + var existing = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode) + .FirstOrDefaultAsync(); + gateway_nodes entity; + + if (existing != null) + { + // 验证 Token + if (existing.NodeToken != req.Token) + return StatusCode(401, new { message = "认证失败" }); + + entity = existing; + entity.AdapterTypes = req.AdapterTypes; + entity.BaseUrl = req.BaseUrl; + entity.IsOnline = "在线"; + entity.LastHeartbeat = DateTime.Now; + await _service.UpdateAsync(entity); + } + else + { + entity = new gateway_nodes + { + NodeCode = req.NodeCode, + NodeName = req.NodeCode, + NodeToken = req.Token, + AdapterTypes = req.AdapterTypes, + BaseUrl = req.BaseUrl, + IsOnline = "在线", + LastHeartbeat = DateTime.Now, + Enable = "启用", + CreateDate = DateTime.Now + }; + await _service.AddAsync(entity); + } + + var devices = await _service.ServiceProvider.GetService() + ?.GetDevicesForGateway(entity.NodeId) ?? new List(); + + return Ok(new { nodeId = entity.NodeId, devices }); + } + + /// A2: 心跳 + [HttpPost] + [Route("/api/gateway/heartbeat")] + public async Task GatewayHeartbeat([FromBody] GatewayHeartbeatRequest req) + { + var entity = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token) + .FirstOrDefaultAsync(); + if (entity == null) + return StatusCode(401, new { message = "认证失败" }); + + entity.IsOnline = "在线"; + entity.LastHeartbeat = DateTime.Now; + await _service.UpdateAsync(entity); + + return Ok(new { status = "ok", serverTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") }); + } + + /// A3: 设备数据同步 + [HttpPost] + [Route("/api/gateway/sync/devices")] + public async Task SyncDevices([FromBody] SyncDevicesRequest req) + { + var node = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token) + .FirstOrDefaultAsync(); + if (node == null) return StatusCode(401, new { message = "认证失败" }); + + int added = 0, updated = 0; + foreach (var d in req.Devices) + { + // delegate to base_device service + } + return Ok(new { added, updated, removed = 0 }); + } + + /// A4: 告警同步 + [HttpPost] + [Route("/api/gateway/sync/alarms")] + public async Task SyncAlarms([FromBody] SyncAlarmsRequest req) + { + var node = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token) + .FirstOrDefaultAsync(); + if (node == null) return StatusCode(401, new { message = "认证失败" }); + + int added = 0; + foreach (var a in req.Alarms) + { + var alarm = new iot_alarm + { + SourceAlarmId = a.SourceAlarmId, + DeviceId = null, // resolved later + AdapterCode = a.AdapterCode, + AlarmLevel = a.Level, + AlarmDesc = a.Desc, + AlarmValue = a.Value, + StartTime = DateTime.Parse(a.StartTime), + State = "未确认", + CreateDate = DateTime.Now + }; + await _service.ServiceProvider.GetService()?.AddAsync(alarm); + added++; + } + return Ok(new { added }); + } + } + + public class GatewayRegisterRequest + { + public string NodeCode { get; set; } = ""; + public string Token { get; set; } = ""; + public string AdapterTypes { get; set; } = ""; + public string BaseUrl { get; set; } = ""; + } + + public class GatewayHeartbeatRequest + { + public string NodeCode { get; set; } = ""; + public string Token { get; set; } = ""; + } + + public class SyncDevicesRequest + { + public string NodeCode { get; set; } = ""; + public string Token { get; set; } = ""; + public List Devices { get; set; } = new(); + } + + public class SyncDeviceItem + { + public string AdapterCode { get; set; } = ""; + public string SourceId { get; set; } = ""; + public string Name { get; set; } = ""; + public string Category { get; set; } = ""; + public string Group { get; set; } = ""; + public bool IsParent { get; set; } + public string? ParentSourceId { get; set; } + public bool IsOnline { get; set; } + public string? IpAddress { get; set; } + public int? Port { get; set; } + public Dictionary? ExtraData { get; set; } + } + + public class SyncAlarmsRequest + { + public string NodeCode { get; set; } = ""; + public string Token { get; set; } = ""; + public List Alarms { get; set; } = new(); + } + + public class SyncAlarmItem + { + public string SourceAlarmId { get; set; } = ""; + public string DeviceSourceId { get; set; } = ""; + public string AdapterCode { get; set; } = ""; + public string Level { get; set; } = ""; + public string Desc { get; set; } = ""; + public double? Value { get; set; } + public string StartTime { get; set; } = ""; + } +} diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_alarmController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_alarmController.cs new file mode 100644 index 0000000..829aba1 --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_alarmController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("iot_alarm",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class iot_alarmController + { + private readonly Iiot_alarmService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public iot_alarmController( + Iiot_alarmService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_devicedataController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_devicedataController.cs new file mode 100644 index 0000000..6d35d9f --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/iot_devicedataController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("iot_devicedata",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class iot_devicedataController + { + private readonly Iiot_devicedataService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public iot_devicedataController( + Iiot_devicedataService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_channelController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_channelController.cs new file mode 100644 index 0000000..37cb662 --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_channelController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("video_channel",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class video_channelController + { + private readonly Ivideo_channelService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public video_channelController( + Ivideo_channelService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_recordController.cs b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_recordController.cs new file mode 100644 index 0000000..5e4d0fd --- /dev/null +++ b/api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/Partial/video_recordController.cs @@ -0,0 +1,33 @@ +/* + *接口编写处... +*如果接口需要做Action的权限验证,请在Action上使用属性 +*如: [ApiActionPermission("video_record",Enums.ActionPermissionOptions.Search)] + */ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using VolPro.Entity.DomainModels; +using Warehouse.IServices; + +namespace Warehouse.Controllers +{ + public partial class video_recordController + { + private readonly Ivideo_recordService _service;//访问业务代码 + private readonly IHttpContextAccessor _httpContextAccessor; + + [ActivatorUtilitiesConstructor] + public video_recordController( + Ivideo_recordService service, + IHttpContextAccessor httpContextAccessor + ) + : base(service) + { + _service = service; + _httpContextAccessor = httpContextAccessor; + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/GatewayClient.cs b/api_sqlsugar/Warehouse/Services/GatewayClient.cs new file mode 100644 index 0000000..d161744 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/GatewayClient.cs @@ -0,0 +1,53 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System.Text; +using System.Text.Json; + +namespace VolPro.Warehouse.Services; + +public class GatewayClient +{ + private readonly HttpClient _http; + private readonly IConfiguration _config; + + public GatewayClient(IHttpClientFactory factory, IConfiguration config) + { + _http = factory.CreateClient("IntegrationGateway"); + _config = config; + } + + /// 检查网关健康状态 + public async Task?> HealthCheckAsync(string gatewayBaseUrl) + { + var resp = await _http.GetAsync($"{gatewayBaseUrl}/api/gateway/health"); + resp.EnsureSuccessStatusCode(); + var json = await resp.Content.ReadAsStringAsync(); + return JsonSerializer.Deserialize(json)?.Adapters; + } + + /// 获取实时数据 + public async Task GetRealtimeAsync(string gatewayBaseUrl, string adapter, string deviceId) + { + var resp = await _http.GetAsync($"{gatewayBaseUrl}/api/gateway/realtime/{adapter}/{deviceId}"); + resp.EnsureSuccessStatusCode(); + return await resp.Content.ReadAsStringAsync(); + } + + /// 设备控制 + public async Task ControlDeviceAsync(string gatewayBaseUrl, string adapter, string deviceId, int pointIndex, double value) + { + var resp = await _http.PostAsJsonAsync($"{gatewayBaseUrl}/api/gateway/realtime/{adapter}/control", new + { + deviceSourceId = deviceId, + pointIndex, + value + }); + resp.EnsureSuccessStatusCode(); + } + + private class GatewayHealth + { + public string Gateway { get; set; } = ""; + public Dictionary Adapters { get; set; } = new(); + } +} diff --git a/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs b/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs new file mode 100644 index 0000000..6f53ef2 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/HeartbeatMonitorJob.cs @@ -0,0 +1,26 @@ +using Quartz; +using Microsoft.Extensions.DependencyInjection; + +namespace VolPro.Warehouse.Services; + +public class HeartbeatMonitorJob : IJob +{ + public async Task Execute(IJobExecutionContext context) + { + var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"]; + var gwSvc = sp.GetService(); + var devSvc = sp.GetService(); + + var timeout = DateTime.Now.AddSeconds(-30); + var offlineNodes = await gwSvc.FindAsIQueryable(x => x.IsOnline == "在线" && x.LastHeartbeat < timeout) + .ToListAsync(); + + foreach (var node in offlineNodes) + { + node.IsOnline = "离线"; + await gwSvc.UpdateAsync(node); + await devSvc.UpdateAsync(x => x.GatewayNodeId == node.NodeId, + x => new base_device { IsOnline = "离线" }); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs b/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs new file mode 100644 index 0000000..18b4043 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/SyncDevicesJob.cs @@ -0,0 +1,27 @@ +using Quartz; +using Microsoft.Extensions.DependencyInjection; + +namespace VolPro.Warehouse.Services; + +public class SyncDevicesJob : IJob +{ + public async Task Execute(IJobExecutionContext context) + { + var sp = (IServiceProvider)context.JobDetail.JobDataMap["ServiceProvider"]; + var gwSvc = sp.GetService(); + var httpFactory = sp.GetService(); + + var onlineNodes = await gwSvc.FindAsIQueryable(x => x.IsOnline == "在线" && x.Enable == "启用" && x.BaseUrl != null) + .ToListAsync(); + + foreach (var node in onlineNodes) + { + try + { + var http = httpFactory.CreateClient(); + await http.PostAsync($"{node.BaseUrl}/api/gateway/devices/sync?adapter={node.AdapterTypes}", null); + } + catch { } + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/base_deviceService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/base_deviceService.cs new file mode 100644 index 0000000..65367d0 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/base_deviceService.cs @@ -0,0 +1,41 @@ +/* + *所有关于base_device类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*base_deviceService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class base_deviceService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Ibase_deviceRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public base_deviceService( + Ibase_deviceRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/gateway_nodesService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/gateway_nodesService.cs new file mode 100644 index 0000000..24e8533 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/gateway_nodesService.cs @@ -0,0 +1,41 @@ +/* + *所有关于gateway_nodes类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*gateway_nodesService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class gateway_nodesService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Igateway_nodesRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public gateway_nodesService( + Igateway_nodesRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_alarmService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_alarmService.cs new file mode 100644 index 0000000..c21b297 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_alarmService.cs @@ -0,0 +1,41 @@ +/* + *所有关于iot_alarm类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*iot_alarmService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class iot_alarmService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Iiot_alarmRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public iot_alarmService( + Iiot_alarmRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_devicedataService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_devicedataService.cs new file mode 100644 index 0000000..7b04c99 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/iot_devicedataService.cs @@ -0,0 +1,41 @@ +/* + *所有关于iot_devicedata类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*iot_devicedataService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class iot_devicedataService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Iiot_devicedataRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public iot_devicedataService( + Iiot_devicedataRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_channelService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_channelService.cs new file mode 100644 index 0000000..e940e1d --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_channelService.cs @@ -0,0 +1,41 @@ +/* + *所有关于video_channel类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*video_channelService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class video_channelService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Ivideo_channelRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public video_channelService( + Ivideo_channelRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_recordService.cs b/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_recordService.cs new file mode 100644 index 0000000..2e32ad3 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/Partial/video_recordService.cs @@ -0,0 +1,41 @@ +/* + *所有关于video_record类的业务代码应在此处编写 +*可使用repository.调用常用方法,获取EF/Dapper等信息 +*如果需要事务请使用repository.DbContextBeginTransaction +*也可使用DBServerProvider.手动获取数据库相关信息 +*用户信息、权限、角色等使用UserContext.Current操作 +*video_recordService对增、删、改查、导入、导出、审核业务代码扩展参照ServiceFunFilter +*/ +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; +using System.Linq; +using VolPro.Core.Utilities; +using System.Linq.Expressions; +using VolPro.Core.Extensions; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.AspNetCore.Http; +using Warehouse.IRepositories; + +namespace Warehouse.Services +{ + public partial class video_recordService + { + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly Ivideo_recordRepository _repository;//访问数据库 + + [ActivatorUtilitiesConstructor] + public video_recordService( + Ivideo_recordRepository dbRepository, + IHttpContextAccessor httpContextAccessor + ) + : base(dbRepository) + { + _httpContextAccessor = httpContextAccessor; + _repository = dbRepository; + //多租户会用到这init代码,其他情况可以不用 + //base.Init(dbRepository); + } + } +} diff --git a/api_sqlsugar/Warehouse/Services/device_manager/base_deviceService.cs b/api_sqlsugar/Warehouse/Services/device_manager/base_deviceService.cs new file mode 100644 index 0000000..f818e04 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/base_deviceService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下base_deviceService与Ibase_deviceService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class base_deviceService : ServiceBase + , Ibase_deviceService, IDependency + { + public static Ibase_deviceService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/api_sqlsugar/Warehouse/Services/device_manager/gateway_nodesService.cs b/api_sqlsugar/Warehouse/Services/device_manager/gateway_nodesService.cs new file mode 100644 index 0000000..1bf60a2 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/gateway_nodesService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下gateway_nodesService与Igateway_nodesService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class gateway_nodesService : ServiceBase + , Igateway_nodesService, IDependency + { + public static Igateway_nodesService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/api_sqlsugar/Warehouse/Services/device_manager/iot_alarmService.cs b/api_sqlsugar/Warehouse/Services/device_manager/iot_alarmService.cs new file mode 100644 index 0000000..1ef4c40 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/iot_alarmService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下iot_alarmService与Iiot_alarmService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class iot_alarmService : ServiceBase + , Iiot_alarmService, IDependency + { + public static Iiot_alarmService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/api_sqlsugar/Warehouse/Services/device_manager/iot_devicedataService.cs b/api_sqlsugar/Warehouse/Services/device_manager/iot_devicedataService.cs new file mode 100644 index 0000000..33ccfd7 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/iot_devicedataService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下iot_devicedataService与Iiot_devicedataService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class iot_devicedataService : ServiceBase + , Iiot_devicedataService, IDependency + { + public static Iiot_devicedataService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/api_sqlsugar/Warehouse/Services/device_manager/video_channelService.cs b/api_sqlsugar/Warehouse/Services/device_manager/video_channelService.cs new file mode 100644 index 0000000..c74ea06 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/video_channelService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下video_channelService与Ivideo_channelService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class video_channelService : ServiceBase + , Ivideo_channelService, IDependency + { + public static Ivideo_channelService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + } diff --git a/api_sqlsugar/Warehouse/Services/device_manager/video_recordService.cs b/api_sqlsugar/Warehouse/Services/device_manager/video_recordService.cs new file mode 100644 index 0000000..2b0f769 --- /dev/null +++ b/api_sqlsugar/Warehouse/Services/device_manager/video_recordService.cs @@ -0,0 +1,22 @@ +/* + *Author:jxx + *Contact:283591387@qq.com + *代码由框架生成,此处任何更改都可能导致被代码生成器覆盖 + *所有业务编写全部应在Partial文件夹下video_recordService与Ivideo_recordService中编写 + */ +using Warehouse.IRepositories; +using Warehouse.IServices; +using VolPro.Core.BaseProvider; +using VolPro.Core.Extensions.AutofacManager; +using VolPro.Entity.DomainModels; + +namespace Warehouse.Services +{ + public partial class video_recordService : ServiceBase + , Ivideo_recordService, IDependency + { + public static Ivideo_recordService Instance + { + get { return AutofacContainerModule.GetService(); } } + } + }