diff --git a/Data/Repositories/MqttRepository.cs b/Data/Repositories/MqttRepository.cs
new file mode 100644
index 0000000..2d516bb
--- /dev/null
+++ b/Data/Repositories/MqttRepository.cs
@@ -0,0 +1,75 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using PMSWPF.Data.Entities;
+
+namespace PMSWPF.Data.Repositories;
+
+///
+/// Mqtt仓储类,用于操作DbMqtt实体
+///
+public class MqttRepository
+{
+ ///
+ /// 根据ID获取Mqtt配置
+ ///
+ /// 主键ID
+ ///
+ public async Task GetByIdAsync(int id)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Queryable().In(id).SingleAsync();
+ }
+ }
+
+ ///
+ /// 获取所有Mqtt配置
+ ///
+ ///
+ public async Task> GetAllAsync()
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Queryable().ToListAsync();
+ }
+ }
+
+ ///
+ /// 新增Mqtt配置
+ ///
+ /// Mqtt实体
+ ///
+ public async Task AddAsync(DbMqtt mqtt)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Insertable(mqtt).ExecuteReturnIdentityAsync();
+ }
+ }
+
+ ///
+ /// 更新Mqtt配置
+ ///
+ /// Mqtt实体
+ ///
+ public async Task UpdateAsync(DbMqtt mqtt)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Updateable(mqtt).ExecuteCommandAsync();
+ }
+ }
+
+ ///
+ /// 根据ID删除Mqtt配置
+ ///
+ /// 主键ID
+ ///
+ public async Task DeleteAsync(int id)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Deleteable().In(id).ExecuteCommandAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Data/Repositories/UserRepository.cs b/Data/Repositories/UserRepository.cs
new file mode 100644
index 0000000..90181ba
--- /dev/null
+++ b/Data/Repositories/UserRepository.cs
@@ -0,0 +1,75 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using PMSWPF.Data.Entities;
+
+namespace PMSWPF.Data.Repositories;
+
+///
+/// 用户仓储类,用于操作DbUser实体
+///
+public class UserRepository
+{
+ ///
+ /// 根据ID获取用户
+ ///
+ /// 主键ID
+ ///
+ public async Task GetByIdAsync(int id)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Queryable().In(id).SingleAsync();
+ }
+ }
+
+ ///
+ /// 获取所有用户
+ ///
+ ///
+ public async Task> GetAllAsync()
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Queryable().ToListAsync();
+ }
+ }
+
+ ///
+ /// 新增用户
+ ///
+ /// 用户实体
+ ///
+ public async Task AddAsync(DbUser user)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Insertable(user).ExecuteReturnIdentityAsync();
+ }
+ }
+
+ ///
+ /// 更新用户
+ ///
+ /// 用户实体
+ ///
+ public async Task UpdateAsync(DbUser user)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Updateable(user).ExecuteCommandAsync();
+ }
+ }
+
+ ///
+ /// 根据ID删除用户
+ ///
+ /// 主键ID
+ ///
+ public async Task DeleteAsync(int id)
+ {
+ using (var _db = DbContext.GetInstance())
+ {
+ return await _db.Deleteable().In(id).ExecuteCommandAsync();
+ }
+ }
+}
\ No newline at end of file
diff --git a/Extensions/TaskExtensions.cs b/Extensions/TaskExtensions.cs
index 261bbba..54f6e28 100644
--- a/Extensions/TaskExtensions.cs
+++ b/Extensions/TaskExtensions.cs
@@ -1,7 +1,16 @@
-namespace PMSWPF.Extensions;
+namespace PMSWPF.Extensions;
+///
+/// 任务扩展类,提供异步任务的扩展方法。
+///
public static class TaskExtensions
{
+ ///
+ /// 等待一个没有返回值的 Task 完成,并提供错误处理和完成时的回调。
+ ///
+ /// 要等待的 Task。
+ /// 发生异常时的回调函数。
+ /// 任务成功完成时的回调函数。
public static async Task Await(this Task task, Action onError = null, Action onComplete = null)
{
try
@@ -14,6 +23,14 @@ public static class TaskExtensions
onError?.Invoke(e);
}
}
+
+ ///
+ /// 等待一个有返回值的 Task 完成,并提供错误处理和完成时的回调。
+ ///
+ /// Task 的返回结果类型。
+ /// 要等待的 Task。
+ /// 发生异常时的回调函数。
+ /// 任务成功完成时的回调函数,接收任务的返回结果。
public static async Task Await(this Task task, Action onError = null, Action onComplete = null)
{
try
diff --git a/PMSWPF.Tests/ExcelHelperTests.cs b/PMSWPF.Tests/ExcelHelperTests.cs
new file mode 100644
index 0000000..01da699
--- /dev/null
+++ b/PMSWPF.Tests/ExcelHelperTests.cs
@@ -0,0 +1,113 @@
+
+using NUnit.Framework;
+using PMSWPF.Helper;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+
+namespace PMSWPF.Tests
+{
+ [TestFixture]
+ public class ExcelHelperTests
+ {
+ private string _testFilePath;
+
+ [SetUp]
+ public void Setup()
+ {
+ // Create a temporary file for testing
+ // _testFilePath = Path.Combine(Path.GetTempPath(), "test.xlsx");
+ _testFilePath = "e:/test.xlsx";
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ // Clean up the temporary file
+ if (File.Exists(_testFilePath))
+ {
+ File.Delete(_testFilePath);
+ }
+ }
+
+ [Test]
+ public void ExportToExcel_WithListOfObjects_CreatesFile()
+ {
+ // Arrange
+ var data = new List
+ {
+ new TestData { Id = 1, Name = "Test1" },
+ new TestData { Id = 2, Name = "Test2" }
+ };
+
+ // Act
+ ExcelHelper.ExportToExcel(data, _testFilePath);
+
+ // Assert
+ Assert.IsTrue(File.Exists(_testFilePath));
+ }
+
+ [Test]
+ public void ExportToExcel_WithDataTable_CreatesFile()
+ {
+ // Arrange
+ var dataTable = new DataTable();
+ dataTable.Columns.Add("Id", typeof(int));
+ dataTable.Columns.Add("Name", typeof(string));
+ dataTable.Rows.Add(1, "Test1");
+ dataTable.Rows.Add(2, "Test2");
+
+ // Act
+ ExcelHelper.ExportToExcel(dataTable, _testFilePath);
+
+ // Assert
+ Assert.IsTrue(File.Exists(_testFilePath));
+ }
+
+ [Test]
+ public void ImportFromExcel_ToDataTable_ReturnsCorrectData()
+ {
+ // Arrange
+ var dataTable = new DataTable();
+ dataTable.Columns.Add("Id", typeof(int));
+ dataTable.Columns.Add("Name", typeof(string));
+ dataTable.Rows.Add(1, "Test1");
+ dataTable.Rows.Add(2, "Test2");
+ ExcelHelper.ExportToExcel(dataTable, _testFilePath);
+
+ // Act
+ var result = ExcelHelper.ImportFromExcel(_testFilePath);
+
+ // Assert
+ Assert.AreEqual(2, result.Rows.Count);
+ Assert.AreEqual("1", result.Rows[0]["Id"]);
+ Assert.AreEqual("Test1", result.Rows[0]["Name"]);
+ }
+
+ [Test]
+ public void ImportFromExcel_ToListOfObjects_ReturnsCorrectData()
+ {
+ // Arrange
+ var data = new List
+ {
+ new TestData { Id = 1, Name = "Test1" },
+ new TestData { Id = 2, Name = "Test2" }
+ };
+ ExcelHelper.ExportToExcel(data, _testFilePath);
+
+ // Act
+ var result = ExcelHelper.ImportFromExcel(_testFilePath);
+
+ // Assert
+ Assert.AreEqual(2, result.Count);
+ Assert.AreEqual(1, result[0].Id);
+ Assert.AreEqual("Test1", result[0].Name);
+ }
+
+ private class TestData
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/PMSWPF.Tests/PMSWPF.Tests.csproj b/PMSWPF.Tests/PMSWPF.Tests.csproj
new file mode 100644
index 0000000..31dc0fb
--- /dev/null
+++ b/PMSWPF.Tests/PMSWPF.Tests.csproj
@@ -0,0 +1,28 @@
+
+
+
+ net8.0-windows
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PMSWPF.csproj b/PMSWPF.csproj
index 539810a..700607c 100644
--- a/PMSWPF.csproj
+++ b/PMSWPF.csproj
@@ -1,6 +1,7 @@
+ false
WinExe
net8.0-windows
enable
@@ -9,17 +10,21 @@
AppIcon2.ico
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PMSWPF.sln b/PMSWPF.sln
index 680f307..deffc39 100644
--- a/PMSWPF.sln
+++ b/PMSWPF.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.12.35728.132 d17.12
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PMSWPF", "PMSWPF.csproj", "{CD3529C9-218C-41EE-B64B-A884DC56E21E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PMSWPF.Tests", "PMSWPF.Tests\PMSWPF.Tests.csproj", "{5EEE2682-FB7B-4E77-AB22-1B7C4E47F53A}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{CD3529C9-218C-41EE-B64B-A884DC56E21E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD3529C9-218C-41EE-B64B-A884DC56E21E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD3529C9-218C-41EE-B64B-A884DC56E21E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5EEE2682-FB7B-4E77-AB22-1B7C4E47F53A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5EEE2682-FB7B-4E77-AB22-1B7C4E47F53A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5EEE2682-FB7B-4E77-AB22-1B7C4E47F53A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5EEE2682-FB7B-4E77-AB22-1B7C4E47F53A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE