Files
DMS/DMS.WPF/Services/DataServices.cs
2025-09-03 15:31:03 +08:00

323 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.ObjectModel;
using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using DMS.Application.DTOs;
using DMS.Application.Interfaces;
using DMS.Core.Enums;
using DMS.Core.Models;
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.Services;
/// <summary>
/// 数据服务类,负责从数据库加载和管理各种数据,并提供数据变更通知。
/// 继承自ObservableRecipient可以接收消息实现IRecipient<LoadMessage>,处理加载消息。
/// </summary>
public partial class DataServices : ObservableObject
{
private readonly IMapper _mapper;
private readonly IDataCenterService _dataCenterService;
// 设备列表使用ObservableProperty特性当值改变时会自动触发属性变更通知。
[ObservableProperty]
private ObservableCollection<DeviceItemViewModel> _devices;
// 变量表列表。
[ObservableProperty]
private ObservableCollection<VariableTableItemViewModel> _variableTables;
// 变量数据列表。
[ObservableProperty]
private ObservableCollection<VariableItemViewModel> _variables;
// 菜单树列表。
[ObservableProperty]
private ObservableCollection<MenuItemViewModel> _menus;
// 菜单树列表。
[ObservableProperty]
private ObservableCollection<MenuItemViewModel> _menuTrees;
// MQTT配置列表。
// [ObservableProperty]
// private List<Mqtt> _mqtts;
// 设备列表变更事件,当设备列表数据更新时触发。
public event Action<List<Device>> OnDeviceListChanged;
// 菜单树列表变更事件,当菜单树数据更新时触发。
public event Action<List<MenuBean>> OnMenuTreeListChanged;
// MQTT列表变更事件当MQTT配置数据更新时触发。
// public event Action<List<Mqtt>> OnMqttListChanged;
// 设备IsActive状态变更事件当单个设备的IsActive状态改变时触发。
public event Action<Device, bool> OnDeviceIsActiveChanged;
/// <summary>
/// DataServices类的构造函数。
/// 注入ILogger<DataServices>,并初始化各个数据仓库。
/// </summary>
/// <param name="mapper">AutoMapper 实例。</param>
/// <param name="varDataRepository"></param>
public DataServices(IMapper mapper, IDataCenterService dataCenterService)
{
_mapper = mapper;
_dataCenterService = dataCenterService;
Devices = new ObservableCollection<DeviceItemViewModel>();
VariableTables = new ObservableCollection<VariableTableItemViewModel>();
Variables = new ObservableCollection<VariableItemViewModel>();
Menus = new ObservableCollection<MenuItemViewModel>();
MenuTrees = new ObservableCollection<MenuItemViewModel>();
// AllVariables = new ConcurrentDictionary<int, Variable>();
}
/// <summary>
/// 异步加载设备数据并以高效的方式更新UI集合。
/// 此方法会比较新旧数据只对有变化的设备进行更新、添加或删除避免不必要的UI刷新。
/// </summary>
public async Task LoadAllDatas()
{
Devices = _mapper.Map<ObservableCollection<DeviceItemViewModel>>(_dataCenterService.Devices.Values);
foreach (var device in Devices)
{
foreach (var variableTable in device.VariableTables)
{
VariableTables.Add(variableTable);
foreach (var variable in variableTable.Variables)
{
Variables.Add(variable);
}
}
}
Menus = _mapper.Map<ObservableCollection<MenuItemViewModel>>(_dataCenterService.Menus.Values);
BuildMenuTrees();
}
public async Task<CreateDeviceWithDetailsDto> AddDevice(CreateDeviceWithDetailsDto dto)
{
var addDto = await _dataCenterService.CreateDeviceWithDetailsAsync(dto);
//更新当前界面
Devices.Add(_mapper.Map<DeviceItemViewModel>(addDto.Device));
AddMenuItem(_mapper.Map<MenuItemViewModel>(addDto.DeviceMenu));
AddVariableTable(_mapper.Map<VariableTableItemViewModel>(addDto.VariableTable));
AddMenuItem(_mapper.Map<MenuItemViewModel>(addDto.VariableTableMenu));
//更新数据中心
_dataCenterService.AddDeviceToMemory(addDto.Device);
_dataCenterService.AddVariableTableToMemory(addDto.VariableTable);
_dataCenterService.AddMenuToMemory(addDto.DeviceMenu);
_dataCenterService.AddMenuToMemory(addDto.VariableTableMenu);
BuildMenuTrees();
return addDto;
}
public async Task<bool> DeleteDevice(DeviceItemViewModel device)
{
if (!await _dataCenterService.DeleteDeviceByIdAsync(device.Id))
{
return false;
}
_dataCenterService.RemoveDeviceFromMemory(device.Id);
// 1. 删除与设备关联的所有变量表及其变量
foreach (var variableTable in device.VariableTables)
{
// 删除与当前变量表关联的所有变量
foreach (var variable in variableTable.Variables)
{
Variables.Remove(variable);
}
var variableTableMenu
= Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu && m.TargetId == variableTable.Id);
DeleteMenuItem(variableTableMenu);
// 删除变量表
VariableTables.Remove(variableTable);
}
// 2. 删除设备
Devices.Remove(device);
// 3. 删除与设备关联的菜单项
var deviceMenu = Menus.FirstOrDefault(m => m.MenuType == MenuType.DeviceMenu && m.TargetId == device.Id);
DeleteMenuItem(deviceMenu);
return true;
}
public async Task<bool> UpdateDevice(DeviceItemViewModel device)
{
if (!_dataCenterService.Devices.TryGetValue(device.Id, out var deviceDto))
{
return false;
}
_mapper.Map(device, deviceDto);
if ( await _dataCenterService.UpdateDeviceAsync(deviceDto)> 0)
{
var menu = Menus.FirstOrDefault(m =>
m.MenuType == MenuType.DeviceMenu &&
m.TargetId == device.Id);
if (menu != null)
{
menu.Header = device.Name;
}
}
return true;
}
public void DeleteVariableTableById(int id)
{
var variableTable = VariableTables.FirstOrDefault(vt => vt.Id == id);
if (variableTable != null)
{
// 删除与当前变量表关联的所有变量
var variablesToDelete = Variables.Where(v => v.VariableTableId == variableTable.Id)
.ToList();
foreach (var variable in variablesToDelete)
{
Variables.Remove(variable);
}
var device = Devices.FirstOrDefault(d => d.Id == variableTable.DeviceId);
if (device != null)
device.VariableTables.Remove(variableTable);
// 删除变量表
VariableTables.Remove(variableTable);
// 删除与变量表关联的菜单项
var variableTableMenu
= Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu && m.TargetId == variableTable.Id);
if (variableTableMenu != null)
{
DeleteMenuItem(variableTableMenu);
}
}
}
private void BuildMenuTrees()
{
MenuTrees.Clear();
// 遍历所有菜单项,构建树形结构
foreach (var menu in Menus)
{
var parentMenu = Menus.FirstOrDefault(m => m.Id == menu.ParentId);
// 检查是否有父ID并且父ID不为0通常0或null表示根节点
if (parentMenu != null && menu.ParentId != 0)
{
// 将当前菜单添加到父菜单的Children列表中
if (!parentMenu.Children.Contains(menu))
{
parentMenu.Children.Add(menu);
}
}
else
{
// 如果没有父ID则这是一个根菜单
MenuTrees.Add(menu);
}
}
}
public void AddMenuItem(MenuItemViewModel menuItemViewModel)
{
if (menuItemViewModel == null)
{
return;
}
var deviceMenu = Menus.FirstOrDefault(m => m.Id == menuItemViewModel.ParentId);
if (deviceMenu != null)
{
deviceMenu.Children.Add(menuItemViewModel);
Menus.Add(menuItemViewModel);
}
}
public void AddVariableTable(VariableTableItemViewModel variableTableItemViewModel)
{
if (variableTableItemViewModel == null)
return;
var device = Devices.FirstOrDefault(d => d.Id == variableTableItemViewModel.DeviceId);
if (device != null)
{
device.VariableTables.Add(variableTableItemViewModel);
VariableTables.Add(variableTableItemViewModel);
}
}
public void AddVariable(VariableItemViewModel variableItem)
{
if (variableItem == null)
{
return;
}
var variableTable = VariableTables.FirstOrDefault(d => d.Id == variableItem.VariableTableId);
if (variableTable != null)
{
variableTable.Variables.Add(variableItem);
Variables.Add(variableItem);
}
}
public void DeleteMenuItem(MenuItemViewModel? menuItemViewModel)
{
if (menuItemViewModel == null)
{
return;
}
// 从扁平菜单列表中移除
Menus.Remove(menuItemViewModel);
// 从树形结构中移除
if (menuItemViewModel.ParentId.HasValue && menuItemViewModel.ParentId.Value != 0)
{
// 如果有父菜单从父菜单的Children中移除
var parentMenu = Menus.FirstOrDefault(m => m.Id == menuItemViewModel.ParentId.Value);
parentMenu?.Children.Remove(menuItemViewModel);
}
else
{
// 如果是根菜单从MenuTrees中移除
MenuTrees.Remove(menuItemViewModel);
}
}
public void DeleteVariableById(int id)
{
var variableItem = Variables.FirstOrDefault(v => v.Id == id);
if (variableItem == null)
{
return;
}
var variableTable = VariableTables.FirstOrDefault(vt => vt.Id == variableItem.VariableTableId);
variableTable.Variables.Remove(variableItem);
Variables.Remove(variableItem);
}
}