141 lines
5.1 KiB
C#
141 lines
5.1 KiB
C#
using Microsoft.Extensions.DependencyInjection;
|
|
using VolPro.Entity.DomainModels;
|
|
using Warehouse.IRepositories;
|
|
using System.Text.Json;
|
|
|
|
namespace VolPro.Warehouse.Services;
|
|
|
|
/// <summary>MC4.0 同步引擎:对象树 → 区域匹配 + 设备 Upsert</summary>
|
|
public class SyncEngine
|
|
{
|
|
private readonly IServiceProvider _sp;
|
|
|
|
public SyncEngine(IServiceProvider sp) => _sp = sp;
|
|
|
|
private Iwarehouse_regionsRepository GetRegionRepo() =>
|
|
_sp.GetService<Iwarehouse_regionsRepository>()!;
|
|
private Iwarehouse_devicepointRepository GetPointRepo() =>
|
|
_sp.GetService<Iwarehouse_devicepointRepository>()!;
|
|
private Ibase_deviceRepository GetDeviceRepo() =>
|
|
_sp.GetService<Ibase_deviceRepository>()!;
|
|
|
|
public async Task<SyncStats> ProcessMc4TreeAsync(int gatewayNodeId, string adapterCode, List<Mc4TreeNode> tree)
|
|
{
|
|
var stats = new SyncStats();
|
|
foreach (var node in tree)
|
|
await ProcessNodeAsync(gatewayNodeId, adapterCode, node, null, stats);
|
|
return stats;
|
|
}
|
|
|
|
private async Task ProcessNodeAsync(int gatewayNodeId, string adapterCode,
|
|
Mc4TreeNode node, int? parentDeviceId, SyncStats stats)
|
|
{
|
|
if (node.Type == 1)
|
|
{
|
|
int pointId = await MatchOrCreatePoint(node);
|
|
foreach (var child in node.Children)
|
|
await ProcessNodeAsync(gatewayNodeId, adapterCode, child, null, stats);
|
|
}
|
|
else if (node.Type == 2)
|
|
{
|
|
int deviceId = await UpsertDevice(gatewayNodeId, adapterCode, node, parentDeviceId);
|
|
if (stats.DeviceIds.TryGetValue(node.Id, out _))
|
|
stats.Updated++;
|
|
else
|
|
stats.Added++;
|
|
stats.DeviceIds[node.Id] = deviceId;
|
|
|
|
foreach (var child in node.Children)
|
|
await ProcessNodeAsync(gatewayNodeId, adapterCode, child, deviceId, stats);
|
|
}
|
|
}
|
|
|
|
private async Task<int> MatchOrCreatePoint(Mc4TreeNode node)
|
|
{
|
|
var regionRepo = GetRegionRepo();
|
|
var regionDb = regionRepo.DbContext;
|
|
|
|
var region = regionDb.Queryable<warehouse_regions>()
|
|
.First(x => x.RegionName == node.Name);
|
|
if (region == null)
|
|
{
|
|
region = new warehouse_regions { RegionName = node.Name ?? $"MC4_{node.Id}" };
|
|
regionDb.Insertable(region).ExecuteCommand();
|
|
}
|
|
|
|
var pointRepo = GetPointRepo();
|
|
var pointDb = pointRepo.DbContext;
|
|
var point = pointDb.Queryable<warehouse_devicepoint>()
|
|
.First(x => x.RegionId == region.Id);
|
|
if (point == null)
|
|
{
|
|
point = new warehouse_devicepoint { PointName = node.Name ?? $"MC4_PT_{node.Id}", RegionId = region.Id };
|
|
pointDb.Insertable(point).ExecuteCommand();
|
|
}
|
|
return point.PointID;
|
|
}
|
|
|
|
private async Task<int> UpsertDevice(int gatewayNodeId, string adapterCode,
|
|
Mc4TreeNode node, int? parentDeviceId)
|
|
{
|
|
var deviceRepo = GetDeviceRepo();
|
|
var db = deviceRepo.DbContext;
|
|
var sourceId = node.Id.ToString();
|
|
|
|
var existing = db.Queryable<base_device>()
|
|
.First(x => x.AdapterCode == adapterCode && x.SourceId == sourceId);
|
|
|
|
if (existing != null)
|
|
{
|
|
existing.IsOnline = "在线";
|
|
existing.LastSyncTime = DateTime.Now;
|
|
existing.ParentDeviceId = parentDeviceId ?? existing.ParentDeviceId;
|
|
if (node.Option != null)
|
|
existing.ExtraData = JsonSerializer.Serialize(node.Option);
|
|
db.Updateable(existing).ExecuteCommand();
|
|
return existing.DeviceId;
|
|
}
|
|
|
|
var device = new base_device
|
|
{
|
|
DeviceName = node.Name ?? $"MC4_DEV_{node.Id}",
|
|
AdapterCode = adapterCode,
|
|
SourceId = sourceId,
|
|
DeviceCategory = MapCategory(node.ObjectType, node.Tag),
|
|
DeviceGroup = "IoT设备",
|
|
GatewayNodeId = gatewayNodeId,
|
|
ParentDeviceId = parentDeviceId,
|
|
IsParent = node.Children?.Count > 0 ? "是" : "否",
|
|
IsOnline = "在线",
|
|
Enable = "启用",
|
|
LastSyncTime = DateTime.Now,
|
|
CreateDate = DateTime.Now,
|
|
ExtraData = node.Option != null ? JsonSerializer.Serialize(node.Option) : null
|
|
};
|
|
db.Insertable(device).ExecuteCommand();
|
|
return device.DeviceId;
|
|
}
|
|
|
|
private static string MapCategory(int objectType, string? tag) =>
|
|
(objectType, tag) switch
|
|
{
|
|
(_, "温湿度") => "温湿度变送器",
|
|
(_, "烟雾") => "烟雾报警器",
|
|
(_, "气体") => "气体报警器",
|
|
(_, "门磁") => "门磁",
|
|
_ => "动环采集器"
|
|
};
|
|
}
|
|
|
|
public class SyncStats { public int Added; public int Updated; public Dictionary<int, int> DeviceIds = new(); }
|
|
public class Mc4TreeNode
|
|
{
|
|
public int Id { get; set; }
|
|
public string? Name { get; set; }
|
|
public int Type { get; set; }
|
|
public int ObjectType { get; set; }
|
|
public string? Tag { get; set; }
|
|
public Dictionary<string, object?>? Option { get; set; }
|
|
public List<Mc4TreeNode> Children { get; set; } = new();
|
|
}
|