2025-07-21 14:35:17 +08:00
|
|
|
|
# 软件开发文档 - DMS.Core 领域模型与接口
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
本文档详细阐述了 `DMS.Core` 项目的设计,它是整个系统的基石,包含所有业务实体和核心接口的定义。`DMS.Core` 不包含任何具体实现,确保了业务规则的独立性和可移植性。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
## 1. 目录结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
DMS.Core/
|
|
|
|
|
|
├── Enums/
|
|
|
|
|
|
│ ├── PollLevelType.cs
|
|
|
|
|
|
│ ├── ProtocolType.cs
|
|
|
|
|
|
│ └── SignalType.cs
|
|
|
|
|
|
├── Models/
|
|
|
|
|
|
│ ├── Device.cs
|
|
|
|
|
|
│ ├── MqttServer.cs
|
|
|
|
|
|
│ ├── Variable.cs
|
2025-07-21 14:35:17 +08:00
|
|
|
|
│ ├── VariableHistory.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
│ ├── VariableMqttAlias.cs
|
2025-07-21 14:35:17 +08:00
|
|
|
|
│ ├── VariableTable.cs
|
|
|
|
|
|
│ ├── MenuBean.cs
|
|
|
|
|
|
│ └── User.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
├── Interfaces/
|
|
|
|
|
|
│ ├── IRepositoryManager.cs
|
|
|
|
|
|
│ ├── IBaseRepository.cs
|
|
|
|
|
|
│ ├── IDeviceRepository.cs
|
|
|
|
|
|
│ ├── IMqttServerRepository.cs
|
2025-07-21 14:35:17 +08:00
|
|
|
|
│ ├── IVariableHistoryRepository.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
│ ├── IVariableMqttAliasRepository.cs
|
|
|
|
|
|
│ ├── IVariableRepository.cs
|
2025-07-21 14:35:17 +08:00
|
|
|
|
│ ├── IVariableTableRepository.cs
|
|
|
|
|
|
│ ├── IMenuRepository.cs
|
|
|
|
|
|
│ └── IUserRepository.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
└── DMS.Core.csproj
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
## 2. 核心枚举 (`Enums/`)
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
使用C#枚举来表示业务中固定的、有限的分类,如协议类型、信号类型、轮询级别。这提供了类型安全和代码可读性。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `PollLevelType.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
```csharp
|
2025-07-21 14:35:17 +08:00
|
|
|
|
// 文件: DMS.Core/Enums/PollLevelType.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 定义了变量的轮询级别,决定了其读取频率。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public enum PollLevelType
|
2025-07-20 23:28:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 不进行轮询。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Off,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 高频轮询(例如:200ms)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
High,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 中频轮询(例如:1000ms)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Medium,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 低频轮询(例如:5000ms)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Low
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `ProtocolType.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Enums/ProtocolType.cs
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 定义了设备支持的通信协议类型。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public enum ProtocolType
|
|
|
|
|
|
{
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// Siemens S7 通信协议。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
S7,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// OPC UA (Unified Architecture) 协议。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
OpcUa,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// Modbus TCP 协议。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
ModbusTcp
|
2025-07-20 23:28:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `SignalType.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
```csharp
|
2025-07-21 14:35:17 +08:00
|
|
|
|
// 文件: DMS.Core/Enums/SignalType.cs
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 定义了变量支持的数据类型。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public enum SignalType
|
2025-07-20 23:28:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 布尔值 (true/false)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Boolean,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 字节 (8-bit 无符号整数)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Byte,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 16位有符号整数。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Int16,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 32位有符号整数。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Int32,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 单精度浮点数。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
Float,
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 字符串。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
String
|
2025-07-20 23:28:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
## 3. 领域模型 (`Models/`)
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
领域模型是业务核心的C#类表示。它们是贫血模型,主要包含数据属性,行为逻辑则由应用服务和领域服务处理。模型之间通过导航属性建立关系,反映业务实体间的关联。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
### `Device.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/Device.cs
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 代表一个可管理的物理或逻辑设备。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class Device
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 唯一标识符。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设备名称,用于UI显示和识别。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设备使用的通信协议。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public ProtocolType Protocol { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设备的IP地址。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string IpAddress { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设备的通信端口号。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Port { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// S7 PLC的机架号。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Rack { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// S7 PLC的槽号。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Slot { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 指示此设备是否处于激活状态。只有激活的设备才会被轮询。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsActive { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 此设备包含的变量表集合。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<VariableTable> VariableTables { get; set; } = new();
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `VariableTable.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/VariableTable.cs
|
|
|
|
|
|
namespace DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 组织和管理一组相关的变量。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class VariableTable
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
public string Description { get; set; }
|
|
|
|
|
|
public bool IsActive { get; set; } // 是否启用
|
|
|
|
|
|
public int DeviceId { get; set; }
|
|
|
|
|
|
public Device Device { get; set; }
|
|
|
|
|
|
public List<Variable> Variables { get; set; } = new();
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-20 23:28:45 +08:00
|
|
|
|
### `Variable.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/Variable.cs
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 核心数据点,代表从设备读取的单个值。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class Variable
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 唯一标识符。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 变量名。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Name { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 在设备中的地址 (例如: DB1.DBD0, M100.0)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Address { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 变量的数据类型。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public SignalType DataType { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 变量的轮询级别,决定了其读取频率。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public PollLevelType PollLevel { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 指示此变量是否处于激活状态。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public bool IsActive { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 所属变量表的ID。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int VariableTableId { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 所属变量表的导航属性。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public VariableTable VariableTable { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 此变量的所有MQTT发布别名关联。一个变量可以关联多个MQTT服务器,每个关联可以有独立的别名。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<VariableMqttAlias> MqttAliases { get; set; } = new();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 存储从设备读取到的最新值。此属性不应持久化到数据库,仅用于运行时。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
[System.ComponentModel.DataAnnotations.Schema.NotMapped] // 标记此属性不映射到数据库
|
|
|
|
|
|
public object DataValue { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `MqttServer.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/MqttServer.cs
|
|
|
|
|
|
namespace DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 代表一个MQTT Broker的配置。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class MqttServer
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
public string ServerName { get; set; }
|
|
|
|
|
|
public string BrokerAddress { get; set; } // Broker地址
|
|
|
|
|
|
public int Port { get; set; } // 端口
|
|
|
|
|
|
public string Username { get; set; }
|
|
|
|
|
|
public string Password { get; set; }
|
|
|
|
|
|
public bool IsActive { get; set; } // 是否启用
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 与此服务器关联的所有变量别名。通过此集合可以反向查找关联的变量。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public List<VariableMqttAlias> VariableAliases { get; set; } = new();
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### `VariableHistory.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/VariableHistory.cs
|
|
|
|
|
|
namespace DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 用于存储变量值的变化记录。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class VariableHistory
|
|
|
|
|
|
{
|
|
|
|
|
|
public long Id { get; set; }
|
|
|
|
|
|
public int VariableId { get; set; }
|
|
|
|
|
|
public string Value { get; set; } // 以字符串形式存储,便于通用性
|
|
|
|
|
|
public DateTime Timestamp { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-20 23:28:45 +08:00
|
|
|
|
### `VariableMqttAlias.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/VariableMqttAlias.cs
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 领域模型:代表一个变量到一个MQTT服务器的特定关联,包含专属别名。
|
|
|
|
|
|
/// 这是一个关联实体,用于解决多对多关系中需要额外属性(别名)的问题。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class VariableMqttAlias
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 唯一标识符。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关联的变量ID。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int VariableId { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关联的MQTT服务器ID。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public int MqttServerId { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 针对此特定[变量-服务器]连接的发布别名。此别名将用于构建MQTT Topic。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public string Alias { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关联的变量导航属性。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Variable Variable { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 关联的MQTT服务器导航属性。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public MqttServer MqttServer { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### `MenuBean.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Models/MenuBean.cs
|
|
|
|
|
|
namespace DMS.Core.Models;
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 领域模型:代表一个菜单项。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public class MenuBean
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
public int? ParentId { get; set; }
|
|
|
|
|
|
public string Header { get; set; }
|
|
|
|
|
|
public string Icon { get; set; }
|
|
|
|
|
|
public string TargetViewKey { get; set; }
|
|
|
|
|
|
public string NavigationParameter { get; set; }
|
|
|
|
|
|
public int DisplayOrder { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### `User.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
```csharp
|
2025-07-21 14:35:17 +08:00
|
|
|
|
// 文件: DMS.Core/Models/User.cs
|
|
|
|
|
|
namespace DMS.Core.Models;
|
|
|
|
|
|
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 领域模型:代表一个用户。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public class User
|
|
|
|
|
|
{
|
|
|
|
|
|
public int Id { get; set; }
|
|
|
|
|
|
public string Username { get; set; }
|
|
|
|
|
|
public string PasswordHash { get; set; } // 存储密码哈希值
|
|
|
|
|
|
public string Role { get; set; } // 用户角色,例如 "Admin", "Operator"
|
|
|
|
|
|
public bool IsActive { get; set; }
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 核心接口 (`Interfaces/`)
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1. `IRepositoryManager.cs` (工作单元模式)
|
|
|
|
|
|
|
|
|
|
|
|
定义了一个仓储管理器,它使用工作单元模式来组合多个仓储操作,以确保事务的原子性。它作为所有仓储的统一入口,并管理数据库事务。
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IRepositoryManager.cs
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 定义了一个仓储管理器,它使用工作单元模式来组合多个仓储操作,以确保事务的原子性。
|
|
|
|
|
|
/// 实现了IDisposable,以确保数据库连接等资源能被正确释放。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public interface IRepositoryManager : IDisposable
|
2025-07-20 23:28:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 获取设备仓储的实例。
|
|
|
|
|
|
/// 所有通过此管理器获取的仓储都共享同一个数据库上下文和事务。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
IDeviceRepository Devices { get; }
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 获取变量表仓储的实例。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
IVariableTableRepository VariableTables { get; }
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 获取变量仓储的实例。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
IVariableRepository Variables { get; }
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 获取MQTT服务器仓储的实例。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
IMqttServerRepository MqttServers { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取变量MQTT别名仓储的实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
IVariableMqttAliasRepository VariableMqttAliases { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取菜单仓储的实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
IMenuRepository Menus { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取变量历史仓储的实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
IVariableHistoryRepository VariableHistories { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取用户仓储的实例。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
IUserRepository Users { get; }
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 开始一个新的数据库事务。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
void BeginTransaction();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步提交当前事务中的所有变更。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>一个表示异步操作的任务。</returns>
|
|
|
|
|
|
Task CommitAsync();
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步回滚当前事务中的所有变更。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns>一个表示异步操作的任务。</returns>
|
|
|
|
|
|
Task RollbackAsync();
|
2025-07-20 23:28:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
### 4.2. 仓储接口 (`IBaseRepository.cs`, `IDeviceRepository.cs` 等)
|
|
|
|
|
|
|
|
|
|
|
|
采用仓储(Repository)模式,为每个聚合根(或主要实体)定义一个数据访问接口。这些接口定义了对领域对象集合的操作,隐藏了底层数据存储的细节。
|
|
|
|
|
|
|
|
|
|
|
|
#### `IBaseRepository.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
```csharp
|
2025-07-21 14:35:17 +08:00
|
|
|
|
// 文件: DMS.Core/Interfaces/IBaseRepository.cs
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 提供泛型数据访问操作的基础仓储接口。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <typeparam name="T">领域模型的类型。</typeparam>
|
|
|
|
|
|
public interface IBaseRepository<T> where T : class
|
2025-07-20 23:28:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步根据ID获取单个实体。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="id">实体的主键ID。</param>
|
|
|
|
|
|
/// <returns>找到的实体,如果不存在则返回null。</returns>
|
|
|
|
|
|
Task<T> GetByIdAsync(int id);
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步获取所有实体。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <returns>所有实体的列表。</returns>
|
|
|
|
|
|
Task<List<T>> GetAllAsync();
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步添加一个新实体。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="entity">要添加的实体。</param>
|
|
|
|
|
|
Task AddAsync(T entity);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步更新一个已存在的实体。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="entity">要更新的实体。</param>
|
|
|
|
|
|
Task UpdateAsync(T entity);
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步根据ID删除一个实体。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="id">要删除的实体的主键ID。</param>
|
|
|
|
|
|
Task DeleteAsync(int id);
|
2025-07-20 23:28:45 +08:00
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
#### `IDeviceRepository.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
```csharp
|
2025-07-21 14:35:17 +08:00
|
|
|
|
// 文件: DMS.Core/Interfaces/IDeviceRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 继承自IBaseRepository,提供设备相关的特定数据查询功能。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public interface IDeviceRepository : IBaseRepository<Device>
|
2025-07-20 23:28:45 +08:00
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步获取所有激活的设备,并级联加载其下的变量表和变量。
|
|
|
|
|
|
/// 这是后台轮询服务需要的主要数据。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <returns>包含完整层级结构的激活设备列表。</returns>
|
|
|
|
|
|
Task<List<Device>> GetActiveDevicesWithDetailsAsync(ProtocolType protocol);
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步根据设备ID获取设备及其所有详细信息(变量表、变量、MQTT别名等)。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="deviceId">设备ID。</param>
|
|
|
|
|
|
/// <returns>包含详细信息的设备对象。</returns>
|
|
|
|
|
|
Task<Device> GetDeviceWithDetailsAsync(int deviceId);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IVariableRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IVariableRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public interface IVariableRepository : IBaseRepository<Variable>
|
|
|
|
|
|
{
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步获取一个变量及其关联的所有MQTT别名和对应的MQTT服务器信息。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="variableId">变量ID。</param>
|
|
|
|
|
|
/// <returns>包含别名和服务器信息的变量对象。</returns>
|
|
|
|
|
|
Task<Variable> GetVariableWithMqttAliasesAsync(int variableId);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IMqttServerRepository.cs`
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IMqttServerRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
public interface IMqttServerRepository : IBaseRepository<MqttServer>
|
|
|
|
|
|
{
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步获取一个MQTT服务器及其关联的所有变量别名。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="serverId">MQTT服务器ID。</param>
|
|
|
|
|
|
/// <returns>包含变量别名信息的MQTT服务器对象。</returns>
|
|
|
|
|
|
Task<MqttServer> GetMqttServerWithVariableAliasesAsync(int serverId);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IVariableTableRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IVariableTableRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
public interface IVariableTableRepository : IBaseRepository<VariableTable>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 可以添加特定于VariableTable的查询方法
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IVariableHistoryRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IVariableHistoryRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
public interface IVariableHistoryRepository : IBaseRepository<VariableHistory>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 可以添加特定于VariableHistory的查询方法
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IVariableMqttAliasRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IVariableMqttAliasRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
2025-07-21 14:35:17 +08:00
|
|
|
|
public interface IVariableMqttAliasRepository : IBaseRepository<VariableMqttAlias>
|
|
|
|
|
|
{
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步获取指定变量的所有MQTT别名关联,并加载关联的MQTT服务器信息。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="variableId">变量ID。</param>
|
|
|
|
|
|
/// <returns>指定变量的所有MQTT别名关联列表。</returns>
|
|
|
|
|
|
Task<List<VariableMqttAlias>> GetAliasesForVariableAsync(int variableId);
|
2025-07-20 23:28:45 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// 异步根据变量ID和MQTT服务器ID获取特定的MQTT别名关联。
|
2025-07-20 23:28:45 +08:00
|
|
|
|
/// </summary>
|
2025-07-21 14:35:17 +08:00
|
|
|
|
/// <param name="variableId">变量ID。</param>
|
|
|
|
|
|
/// <param name="mqttServerId">MQTT服务器ID。</param>
|
|
|
|
|
|
/// <returns>匹配的VariableMqttAlias对象,如果不存在则为null。</returns>
|
|
|
|
|
|
Task<VariableMqttAlias> GetByVariableAndServerAsync(int variableId, int mqttServerId);
|
2025-07-20 23:28:45 +08:00
|
|
|
|
}
|
2025-07-21 14:35:17 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IMenuRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IMenuRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
public interface IMenuRepository : IBaseRepository<MenuBean>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 可以添加特定于菜单的查询方法,例如获取所有菜单项
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### `IUserRepository.cs`
|
|
|
|
|
|
|
|
|
|
|
|
```csharp
|
|
|
|
|
|
// 文件: DMS.Core/Interfaces/IUserRepository.cs
|
|
|
|
|
|
using DMS.Core.Models;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Core.Interfaces;
|
|
|
|
|
|
|
|
|
|
|
|
public interface IUserRepository : IBaseRepository<User>
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 异步根据用户名获取用户。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="username">用户名。</param>
|
|
|
|
|
|
/// <returns>用户对象,如果不存在则为null。</returns>
|
|
|
|
|
|
Task<User> GetByUsernameAsync(string username);
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|