fix all via Repository.DbContext

This commit is contained in:
2026-05-17 01:07:00 +08:00
parent 52bef2b92a
commit 21c9565146
4 changed files with 122 additions and 164 deletions

View File

@@ -1,7 +1,6 @@
/*
*接口编写处...
*如果接口需要做Action的权限验证请在Action上使用属性
*如: [ApiActionPermission("gateway_nodes",Enums.ActionPermissionOptions.Search)]
*网关节点管理 — A1注册/A2心跳/A3设备同步/A4告警同步
*通过 Repository.DbContext 直接操作 SqlSugar
*/
using Microsoft.AspNetCore.Mvc;
using System;
@@ -11,47 +10,27 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;
using VolPro.Entity.DomainModels;
using Warehouse.IServices;
using Warehouse.IRepositories;
using System.Linq;
using Microsoft.EntityFrameworkCore;
namespace Warehouse.Controllers
{
public partial class gateway_nodesController
{
private readonly Igateway_nodesService _service;//访问业务代码
private readonly Igateway_nodesRepository _repo;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly Ibase_deviceService _deviceService;
private readonly Iiot_alarmService _alarmService;
[ActivatorUtilitiesConstructor]
public gateway_nodesController(
Igateway_nodesService service,
IHttpContextAccessor httpContextAccessor,
Ibase_deviceService deviceService,
Iiot_alarmService alarmService
Igateway_nodesRepository repository,
IHttpContextAccessor httpContextAccessor
)
: base(service)
{
_service = service;
_repo = repository;
_httpContextAccessor = httpContextAccessor;
_deviceService = deviceService;
_alarmService = alarmService;
}
private readonly Ibase_deviceService _deviceService;
private readonly Iiot_alarmService _alarmService;
[ActivatorUtilitiesConstructor]
public gateway_nodesController(
Igateway_nodesService service,
IHttpContextAccessor httpContextAccessor,
Ibase_deviceService deviceService,
Iiot_alarmService alarmService
)
: base(service)
{
_service = service;
_httpContextAccessor = httpContextAccessor;
_deviceService = deviceService;
_alarmService = alarmService;
}
/// <summary>A1: 网关注册 (Upsert)</summary>
@@ -62,22 +41,21 @@ namespace Warehouse.Controllers
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;
var existing = _repo.DbContext.Queryable<gateway_nodes>()
.First(x => x.NodeCode == req.NodeCode);
gateway_nodes entity;
if (existing != null)
{
// 验证 Token
if (existing.NodeToken != req.Token)
return StatusCode(401, new { message = "认证失败" });
existing.AdapterTypes = req.AdapterTypes;
existing.BaseUrl = req.BaseUrl;
existing.IsOnline = "在线";
existing.LastHeartbeat = DateTime.Now;
_repo.DbContext.Updateable(existing).ExecuteCommand();
entity = existing;
entity.AdapterTypes = req.AdapterTypes;
entity.BaseUrl = req.BaseUrl;
entity.IsOnline = "在线";
entity.LastHeartbeat = DateTime.Now;
_service.Add<object>(entity);
}
else
{
@@ -93,11 +71,15 @@ namespace Warehouse.Controllers
Enable = "启用",
CreateDate = DateTime.Now
};
_service.Add<object>(entity);
_repo.DbContext.Insertable(entity).ExecuteCommand();
}
var devices = await _service.ServiceProvider.GetService<VolPro.WebApi.Controllers.Warehouse.base_deviceController>()
?.GetDevicesForGateway(entity.NodeId) ?? new List<object>();
// 返回当前网关的顶层设备
var deviceRepo = _repo.DbContext;
var devices = deviceRepo.Queryable<base_device>()
.Where(x => x.GatewayNodeId == entity.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 })
.ToList();
return Ok(new { nodeId = entity.NodeId, devices });
}
@@ -107,14 +89,14 @@ namespace Warehouse.Controllers
[Route("/api/gateway/heartbeat")]
public async Task<IActionResult> GatewayHeartbeat([FromBody] GatewayHeartbeatRequest req)
{
var entity = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token)
.FirstOrDefaultAsync();
var entity = _repo.DbContext.Queryable<gateway_nodes>()
.First(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token);
if (entity == null)
return StatusCode(401, new { message = "认证失败" });
entity.IsOnline = "在线";
entity.LastHeartbeat = DateTime.Now;
_service.Add<object>(entity);
_repo.DbContext.Updateable(entity).ExecuteCommand();
return Ok(new { status = "ok", serverTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") });
}
@@ -124,32 +106,28 @@ namespace Warehouse.Controllers
[Route("/api/gateway/sync/devices")]
public async Task<IActionResult> SyncDevices([FromBody] SyncDevicesRequest req)
{
var node = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token)
.FirstOrDefaultAsync();
var node = _repo.DbContext.Queryable<gateway_nodes>()
.First(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token);
if (node == null) return StatusCode(401, new { message = "认证失败" });
// 批量查询已有设备映射表(用于 parentSourceId 解析)
var db = _repo.DbContext;
// 批量查询已有设备映射表
var codes = req.Devices.Select(d => d.AdapterCode).Distinct().ToList();
var existingIds = await _deviceService
.FindAsIQueryable(x => codes.Contains(x.AdapterCode) && x.GatewayNodeId == node.NodeId)
.ToDictionaryAsync(x => (x.AdapterCode, x.SourceId), x => x.DeviceId);
var existingIds = db.Queryable<base_device>()
.Where(x => x.GatewayNodeId == node.NodeId && codes.Contains(x.AdapterCode!))
.ToDictionary(x => (x.AdapterCode!, x.SourceId!), x => x.DeviceId);
int added = 0, updated = 0;
foreach (var d in req.Devices)
{
var key = (d.AdapterCode, d.SourceId);
existingIds.TryGetValue(key, out var existingId);
bool isNew = existingId == 0;
bool isNew = !existingIds.ContainsKey((d.AdapterCode, d.SourceId));
// 解析 parentSourceId → ParentDeviceId
int? parentDeviceId = null;
if (!string.IsNullOrEmpty(d.ParentSourceId))
{
existingIds.TryGetValue((d.AdapterCode, d.ParentSourceId), out var pid);
if (pid > 0) parentDeviceId = pid;
}
if (!string.IsNullOrEmpty(d.ParentSourceId) && existingIds.TryGetValue((d.AdapterCode, d.ParentSourceId), out var pid))
parentDeviceId = pid;
// 首次入库写全量,已有记录仅更新网关字段
if (isNew)
{
var entity = new base_device
@@ -172,12 +150,13 @@ namespace Warehouse.Controllers
LastSyncTime = DateTime.Now,
CreateDate = DateTime.Now
};
_deviceService.Add<object>(entity);
db.Insertable(entity).ExecuteCommand();
added++;
}
else
{
var entity = await _deviceService.FindAsIQueryable(x => x.DeviceId == existingId).FirstOrDefaultAsync();
var existingId = existingIds[(d.AdapterCode, d.SourceId)];
var entity = db.Queryable<base_device>().InSingle(existingId);
if (entity != null)
{
entity.IsOnline = d.IsOnline ? "在线" : "离线";
@@ -189,7 +168,7 @@ namespace Warehouse.Controllers
? System.Text.Json.JsonSerializer.Serialize(d.ExtraData)
: entity.ExtraData;
entity.LastSyncTime = DateTime.Now;
_deviceService.Add<object>(entity);
db.Updateable(entity).ExecuteCommand();
updated++;
}
}
@@ -197,32 +176,30 @@ namespace Warehouse.Controllers
return Ok(new { added, updated, removed = 0 });
}
/// <summary>A4: 告警同步</summary>
/// <summary>A4: 告警同步DeviceSourceId→DeviceId映射 + 去重)</summary>
[HttpPost]
[Route("/api/gateway/sync/alarms")]
public async Task<IActionResult> SyncAlarms([FromBody] SyncAlarmsRequest req)
{
var node = await _service.FindAsIQueryable(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token)
.FirstOrDefaultAsync();
var node = _repo.DbContext.Queryable<gateway_nodes>()
.First(x => x.NodeCode == req.NodeCode && x.NodeToken == req.Token);
if (node == null) return StatusCode(401, new { message = "认证失败" });
// 批量查出 DeviceSourceId → DeviceId 映射
var codes = req.Alarms.Select(a => a.AdapterCode).Distinct().ToList();
var db = _repo.DbContext;
// 批量查 DeviceSourceId → DeviceId
var srcIds = req.Alarms.Select(a => a.DeviceSourceId).ToList();
var deviceMap = await _deviceService
.FindAsIQueryable(x => codes.Contains(x.AdapterCode) && srcIds.Contains(x.SourceId))
.ToDictionaryAsync(x => (x.AdapterCode, x.SourceId), x => x.DeviceId);
var deviceMap = db.Queryable<base_device>()
.Where(x => x.GatewayNodeId == node.NodeId && srcIds.Contains(x.SourceId!))
.ToDictionary(x => x.SourceId!, x => x.DeviceId);
int added = 0;
foreach (var a in req.Alarms)
{
// 跳过已存在的告警SourceAlarmId 去重)
var exists = await _alarmService
.FindAsIQueryable(x => x.SourceAlarmId == a.SourceAlarmId)
.AnyAsync();
if (exists) continue;
if (db.Queryable<iot_alarm>().Any(x => x.SourceAlarmId == a.SourceAlarmId))
continue;
deviceMap.TryGetValue((a.AdapterCode, a.DeviceSourceId), out var deviceId);
deviceMap.TryGetValue(a.DeviceSourceId, out var deviceId);
var alarm = new iot_alarm
{
SourceAlarmId = a.SourceAlarmId,
@@ -235,7 +212,7 @@ namespace Warehouse.Controllers
State = "未确认",
CreateDate = DateTime.Now
};
_alarmService.Add<object>(alarm);
db.Insertable(alarm).ExecuteCommand();
added++;
}
return Ok(new { added });