初步完成邮件功能
This commit is contained in:
@@ -216,11 +216,16 @@ public partial class App : System.Windows.Application
|
||||
services.AddSingleton<INlogRepository, NlogRepository>();
|
||||
services.AddSingleton<IRepositoryManager, RepositoryManager>();
|
||||
services.AddSingleton<IAlarmHistoryRepository, AlarmHistoryRepository>(); // 添加这行
|
||||
services.AddSingleton<IEmailAccountRepository, EmailAccountRepository>();
|
||||
services.AddSingleton<IEmailMessageRepository, EmailMessageRepository>();
|
||||
services.AddSingleton<IEmailTemplateRepository, EmailTemplateRepository>();
|
||||
services.AddSingleton<IEmailLogRepository, EmailLogRepository>();
|
||||
services.AddSingleton<IExcelService, ExcelService>();
|
||||
|
||||
services.AddTransient<IOpcUaService, OpcUaService>();
|
||||
services.AddTransient<IMqttService, MqttService>();
|
||||
services.AddTransient<IMqttServiceFactory, MqttServiceFactory>();
|
||||
services.AddTransient<IEmailService, EmailService>();
|
||||
|
||||
// 注册App服务\r\n
|
||||
services.AddSingleton<IInitializeService, InitializeService>();
|
||||
@@ -267,6 +272,8 @@ public partial class App : System.Windows.Application
|
||||
|
||||
// 注册主数据服务
|
||||
services.AddSingleton<IWPFDataService, WPFDataService>();
|
||||
services.AddSingleton<IEmailAppService, EmailAppService>();
|
||||
services.AddSingleton<EmailFunctionalityTestService, EmailFunctionalityTestService>();
|
||||
|
||||
|
||||
// 注册视图模型
|
||||
@@ -283,6 +290,7 @@ public partial class App : System.Windows.Application
|
||||
services.AddSingleton<LogHistoryViewModel>();
|
||||
services.AddScoped<MqttServerDetailViewModel>();
|
||||
services.AddSingleton<VariableHistoryViewModel>();
|
||||
services.AddSingleton<EmailManagementViewModel>();
|
||||
|
||||
// 注册对话框视图模型
|
||||
services.AddTransient<DeviceDialogViewModel>();
|
||||
@@ -298,6 +306,8 @@ public partial class App : System.Windows.Application
|
||||
services.AddTransient<MqttAliasBatchEditDialogViewModel>();
|
||||
services.AddTransient<HistorySettingsDialogViewModel>();
|
||||
services.AddTransient<AlarmSettingsDialogViewModel>();
|
||||
services.AddTransient<EmailAccountDialogViewModel>();
|
||||
services.AddTransient<EmailTemplateDialogViewModel>();
|
||||
|
||||
// 注册View视图
|
||||
services.AddSingleton<SplashWindow>();
|
||||
@@ -310,6 +320,8 @@ public partial class App : System.Windows.Application
|
||||
services.AddSingleton<LogHistoryView>();
|
||||
services.AddScoped<DeviceDetailView>();
|
||||
services.AddScoped<MqttsView>();
|
||||
services.AddSingleton<EmailManagementView>();
|
||||
|
||||
}
|
||||
|
||||
private void ConfigureLogging(ILoggingBuilder loggingBuilder)
|
||||
|
||||
13
DMS.WPF/Interfaces/IDialogViewModel.cs
Normal file
13
DMS.WPF/Interfaces/IDialogViewModel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace DMS.WPF.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// 对话框视图模型接口
|
||||
/// </summary>
|
||||
public interface IDialogViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 关闭请求事件
|
||||
/// </summary>
|
||||
event Action<bool?> CloseRequested;
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,8 @@ namespace DMS.WPF.Services
|
||||
{ typeof(MqttSelectionDialogViewModel), typeof(MqttSelectionDialog) },
|
||||
{ typeof(MqttAliasBatchEditDialogViewModel), typeof(MqttAliasBatchEditDialog) },
|
||||
{ typeof(HistorySettingsDialogViewModel), typeof(HistorySettingsDialog) },
|
||||
{ typeof(AlarmSettingsDialogViewModel), typeof(AlarmSettingsDialog) }
|
||||
{ typeof(AlarmSettingsDialogViewModel), typeof(AlarmSettingsDialog) },
|
||||
{ typeof(EmailAccountDialogViewModel), typeof(EmailAccountDialog) }
|
||||
// Add other mappings here
|
||||
// ... other dialogs
|
||||
};
|
||||
|
||||
89
DMS.WPF/Services/EmailFunctionalityTestService.cs
Normal file
89
DMS.WPF/Services/EmailFunctionalityTestService.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.Core.Interfaces.Repositories;
|
||||
using DMS.Core.Interfaces.Services;
|
||||
using DMS.Core.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DMS.WPF.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件功能测试服务
|
||||
/// </summary>
|
||||
public class EmailFunctionalityTestService
|
||||
{
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly IEmailAccountRepository _emailAccountRepository;
|
||||
private readonly IEmailService _emailService;
|
||||
|
||||
public EmailFunctionalityTestService(
|
||||
IEmailAppService emailAppService,
|
||||
IEmailAccountRepository emailAccountRepository,
|
||||
IEmailService emailService)
|
||||
{
|
||||
_emailAppService = emailAppService;
|
||||
_emailAccountRepository = emailAccountRepository;
|
||||
_emailService = emailService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 运行邮件功能测试
|
||||
/// </summary>
|
||||
public async Task RunTestAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1. 创建测试邮件账户
|
||||
var createRequest = new CreateEmailAccountRequest
|
||||
{
|
||||
Name = "测试邮件账户",
|
||||
EmailAddress = "test@example.com",
|
||||
SmtpServer = "smtp.example.com",
|
||||
SmtpPort = 587,
|
||||
EnableSsl = true,
|
||||
Username = "test@example.com",
|
||||
Password = "password",
|
||||
ImapServer = "imap.example.com",
|
||||
ImapPort = 993,
|
||||
IsDefault = true,
|
||||
IsActive = true
|
||||
};
|
||||
|
||||
var createdAccount = await _emailAppService.CreateEmailAccountAsync(createRequest);
|
||||
Console.WriteLine($"创建邮件账户成功,ID: {createdAccount.Id}");
|
||||
|
||||
// 2. 获取所有邮件账户
|
||||
var accounts = await _emailAppService.GetAllEmailAccountsAsync();
|
||||
Console.WriteLine($"获取到 {accounts.Count} 个邮件账户");
|
||||
|
||||
// 3. 测试连接(这会失败,因为我们使用的是假的服务器地址)
|
||||
var connectionResult = await _emailAppService.TestEmailAccountAsync(createdAccount.Id);
|
||||
Console.WriteLine($"邮件账户连接测试结果: {connectionResult}");
|
||||
|
||||
// 4. 创建测试邮件模板
|
||||
var templateDto = new EmailTemplateDto
|
||||
{
|
||||
Name = "测试模板",
|
||||
Code = "TEST_TEMPLATE",
|
||||
Subject = "测试邮件主题",
|
||||
Body = "<h1>测试邮件内容</h1><p>这是一封测试邮件。</p>",
|
||||
IsHtml = true,
|
||||
IsActive = true
|
||||
};
|
||||
|
||||
var createdTemplate = await _emailAppService.CreateEmailTemplateAsync(templateDto);
|
||||
Console.WriteLine($"创建邮件模板成功,ID: {createdTemplate.Id}");
|
||||
|
||||
// 5. 获取所有邮件模板
|
||||
var templates = await _emailAppService.GetAllEmailTemplatesAsync();
|
||||
Console.WriteLine($"获取到 {templates.Count} 个邮件模板");
|
||||
|
||||
Console.WriteLine("邮件功能测试完成!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"邮件功能测试过程中发生错误: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,6 +94,8 @@ public class NavigationService : INavigationService
|
||||
return App.Current.Services.GetRequiredService<MqttServerDetailViewModel>();
|
||||
case "SettingView":
|
||||
return App.Current.Services.GetRequiredService<SettingViewModel>();
|
||||
case "EmailManagementView":
|
||||
return App.Current.Services.GetRequiredService<EmailManagementViewModel>();
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
161
DMS.WPF/ViewModels/Dialogs/EmailAccountDialogViewModel.cs
Normal file
161
DMS.WPF/ViewModels/Dialogs/EmailAccountDialogViewModel.cs
Normal file
@@ -0,0 +1,161 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.WPF.Interfaces;
|
||||
|
||||
namespace DMS.WPF.ViewModels.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件账户对话框视图模型
|
||||
/// </summary>
|
||||
public partial class EmailAccountDialogViewModel : DialogViewModelBase<CreateEmailAccountRequest>, IDialogViewModel
|
||||
{
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private bool _isEditMode;
|
||||
private int _accountId;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _emailAddress = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _smtpServer = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _smtpPort = 587;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _enableSsl = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _username = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _password = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _imapServer = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private int _imapPort = 993;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isDefault;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isActive = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _dialogTitle = "添加邮件账户";
|
||||
|
||||
public event Action<bool?>? CloseRequested;
|
||||
|
||||
public EmailAccountDialogViewModel(
|
||||
IEmailAppService emailAppService,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
_emailAppService = emailAppService;
|
||||
_notificationService = notificationService;
|
||||
PrimaryButText = "保存";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置要编辑的邮件账户
|
||||
/// </summary>
|
||||
public void SetEmailAccount(EmailAccountDto account)
|
||||
{
|
||||
_isEditMode = true;
|
||||
_accountId = account.Id;
|
||||
DialogTitle = "编辑邮件账户";
|
||||
|
||||
Name = account.Name;
|
||||
EmailAddress = account.EmailAddress;
|
||||
SmtpServer = account.SmtpServer;
|
||||
SmtpPort = account.SmtpPort;
|
||||
EnableSsl = account.EnableSsl;
|
||||
Username = account.Username;
|
||||
Password = ""; // 出于安全考虑,不显示密码
|
||||
ImapServer = account.ImapServer ?? "";
|
||||
ImapPort = account.ImapPort;
|
||||
IsDefault = account.IsDefault;
|
||||
IsActive = account.IsActive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task Save()
|
||||
{
|
||||
if (!ValidateInput())
|
||||
return;
|
||||
|
||||
var request = new CreateEmailAccountRequest
|
||||
{
|
||||
Name = Name,
|
||||
EmailAddress = EmailAddress,
|
||||
SmtpServer = SmtpServer,
|
||||
SmtpPort = SmtpPort,
|
||||
EnableSsl = EnableSsl,
|
||||
Username = Username,
|
||||
Password = Password,
|
||||
ImapServer = string.IsNullOrEmpty(ImapServer) ? null : ImapServer,
|
||||
ImapPort = ImapPort,
|
||||
IsDefault = IsDefault,
|
||||
IsActive = IsActive
|
||||
};
|
||||
Close(request);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task Cancel()
|
||||
{
|
||||
Close(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证输入
|
||||
/// </summary>
|
||||
private bool ValidateInput()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Name))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入账户名称");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(EmailAddress))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入邮箱地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(SmtpServer))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入SMTP服务器地址");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Username))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入用户名");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_isEditMode && string.IsNullOrWhiteSpace(Password))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入密码");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
151
DMS.WPF/ViewModels/Dialogs/EmailTemplateDialogViewModel.cs
Normal file
151
DMS.WPF/ViewModels/Dialogs/EmailTemplateDialogViewModel.cs
Normal file
@@ -0,0 +1,151 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.WPF.Interfaces;
|
||||
|
||||
namespace DMS.WPF.ViewModels.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件模板对话框视图模型
|
||||
/// </summary>
|
||||
public partial class EmailTemplateDialogViewModel : DialogViewModelBase<EmailTemplateDto>, IDialogViewModel
|
||||
{
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private bool _isEditMode;
|
||||
private int _templateId;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _name = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _code = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _subject = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _body = string.Empty;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isHtml = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isActive = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _dialogTitle = "添加邮件模板";
|
||||
|
||||
public event Action<bool?>? CloseRequested;
|
||||
|
||||
public EmailTemplateDialogViewModel(
|
||||
IEmailAppService emailAppService,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
_emailAppService = emailAppService;
|
||||
_notificationService = notificationService;
|
||||
PrimaryButText = "保存";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置要编辑的邮件模板
|
||||
/// </summary>
|
||||
public void SetEmailTemplate(EmailTemplateDto template)
|
||||
{
|
||||
_isEditMode = true;
|
||||
_templateId = template.Id;
|
||||
DialogTitle = "编辑邮件模板";
|
||||
|
||||
Name = template.Name;
|
||||
Code = template.Code;
|
||||
Subject = template.Subject;
|
||||
Body = template.Body;
|
||||
IsHtml = template.IsHtml;
|
||||
IsActive = template.IsActive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task Save()
|
||||
{
|
||||
if (!ValidateInput())
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
var template = new EmailTemplateDto
|
||||
{
|
||||
Name = Name,
|
||||
Code = Code,
|
||||
Subject = Subject,
|
||||
Body = Body,
|
||||
IsHtml = IsHtml,
|
||||
IsActive = IsActive
|
||||
};
|
||||
|
||||
if (_isEditMode)
|
||||
{
|
||||
await _emailAppService.UpdateEmailTemplateAsync(_templateId, template);
|
||||
_notificationService.ShowSuccess("邮件模板更新成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
await _emailAppService.CreateEmailTemplateAsync(template);
|
||||
_notificationService.ShowSuccess("邮件模板创建成功");
|
||||
}
|
||||
|
||||
CloseRequested?.Invoke(true);
|
||||
await Close(new EmailTemplateDto());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError(_isEditMode ? "更新失败" : "创建失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取消命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task Cancel()
|
||||
{
|
||||
CloseRequested?.Invoke(false);
|
||||
await Close(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证输入
|
||||
/// </summary>
|
||||
private bool ValidateInput()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Name))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入模板名称");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Code))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入模板代码");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Subject))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入邮件主题");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(Body))
|
||||
{
|
||||
_notificationService.ShowWarn("请输入邮件内容");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
237
DMS.WPF/ViewModels/EmailManagementViewModel.cs
Normal file
237
DMS.WPF/ViewModels/EmailManagementViewModel.cs
Normal file
@@ -0,0 +1,237 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.WPF.Interfaces;
|
||||
using DMS.WPF.ViewModels.Dialogs;
|
||||
using System.Collections.ObjectModel;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace DMS.WPF.ViewModels
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件管理视图模型
|
||||
/// </summary>
|
||||
public partial class EmailManagementViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly INotificationService _notificationService;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EmailAccountDto> _emailAccounts = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private EmailAccountDto? _selectedEmailAccount;
|
||||
|
||||
[ObservableProperty]
|
||||
private ObservableCollection<EmailTemplateDto> _emailTemplates = new();
|
||||
|
||||
[ObservableProperty]
|
||||
private EmailTemplateDto? _selectedEmailTemplate;
|
||||
|
||||
public EmailManagementViewModel(
|
||||
IEmailAppService emailAppService,
|
||||
IDialogService dialogService,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
_emailAppService = emailAppService;
|
||||
_dialogService = dialogService;
|
||||
_notificationService = notificationService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载数据命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task LoadDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 加载邮件账户
|
||||
var accounts = await _emailAppService.GetAllEmailAccountsAsync();
|
||||
EmailAccounts = new ObservableCollection<EmailAccountDto>(accounts);
|
||||
|
||||
// 加载邮件模板
|
||||
var templates = await _emailAppService.GetAllEmailTemplatesAsync();
|
||||
EmailTemplates = new ObservableCollection<EmailTemplateDto>(templates);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("加载数据失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件账户命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task AddEmailAccountAsync()
|
||||
{
|
||||
EmailAccountDialogViewModel viewModel = App.Current.Services.GetRequiredService<EmailAccountDialogViewModel>();
|
||||
var emailAccountDto = await _dialogService.ShowDialogAsync(viewModel);
|
||||
if (emailAccountDto==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑邮件账户命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task EditEmailAccountAsync()
|
||||
{
|
||||
if (SelectedEmailAccount == null)
|
||||
{
|
||||
_notificationService.ShowWarn("请选择要编辑的邮件账户");
|
||||
return;
|
||||
}
|
||||
EmailAccountDialogViewModel viewModel = App.Current.Services.GetRequiredService<EmailAccountDialogViewModel>();
|
||||
viewModel.SetEmailAccount(SelectedEmailAccount);
|
||||
var emailAccountDto = await _dialogService.ShowDialogAsync(viewModel);
|
||||
if (emailAccountDto==null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// var dialog = _dialogService.CreateDialog<EmailAccountDialogViewModel>();
|
||||
// dialog.SetEmailAccount(SelectedEmailAccount);
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件账户命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task DeleteEmailAccountAsync()
|
||||
{
|
||||
if (SelectedEmailAccount == null)
|
||||
{
|
||||
_notificationService.ShowWarn("请选择要删除的邮件账户");
|
||||
return;
|
||||
}
|
||||
|
||||
ConfirmDialogViewModel confirmDialogViewModel = new ConfirmDialogViewModel(
|
||||
"确认删除",
|
||||
$"确定要删除邮件账户 {SelectedEmailAccount.Name} 吗?", "删除");
|
||||
|
||||
var confirmResult = await _dialogService.ShowDialogAsync(confirmDialogViewModel);
|
||||
|
||||
if (confirmResult == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _emailAppService.DeleteEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
_notificationService.ShowSuccess("删除成功");
|
||||
await LoadDataAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("删除失败", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试邮件账户连接命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task TestEmailAccountAsync()
|
||||
{
|
||||
if (SelectedEmailAccount == null)
|
||||
{
|
||||
_notificationService.ShowWarn("请选择要测试的邮件账户");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _emailAppService.TestEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("连接测试成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationService.ShowWarn("连接测试失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("连接测试失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件模板命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task AddEmailTemplateAsync()
|
||||
{
|
||||
// var dialog = _dialogService.CreateDialog<EmailTemplateDialogViewModel>();
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 编辑邮件模板命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task EditEmailTemplateAsync()
|
||||
{
|
||||
if (SelectedEmailTemplate == null)
|
||||
{
|
||||
_notificationService.ShowWarn("请选择要编辑的邮件模板");
|
||||
return;
|
||||
}
|
||||
|
||||
// var dialog = _dialogService.CreateDialog<EmailTemplateDialogViewModel>();
|
||||
// dialog.SetEmailTemplate(SelectedEmailTemplate);
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件模板命令
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private async Task DeleteEmailTemplateAsync()
|
||||
{
|
||||
if (SelectedEmailTemplate == null)
|
||||
{
|
||||
_notificationService.ShowWarn("请选择要删除的邮件模板");
|
||||
return;
|
||||
}
|
||||
|
||||
// var confirmResult = await _dialogService.ShowConfirmDialogAsync(
|
||||
// "确认删除",
|
||||
// $"确定要删除邮件模板 {SelectedEmailTemplate.Name} 吗?");
|
||||
|
||||
// if (confirmResult == true)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// await _emailAppService.DeleteEmailTemplateAsync(SelectedEmailTemplate.Id);
|
||||
// _notificationService.ShowSuccess("删除成功");
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// _notificationService.ShowError("删除失败", ex);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
100
DMS.WPF/Views/Dialogs/EmailAccountDialog.xaml
Normal file
100
DMS.WPF/Views/Dialogs/EmailAccountDialog.xaml
Normal file
@@ -0,0 +1,100 @@
|
||||
<ui:ContentDialog
|
||||
x:Class="DMS.WPF.Views.Dialogs.EmailAccountDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:vm="clr-namespace:DMS.WPF.ViewModels.Dialogs"
|
||||
Title="{Binding DialogTitle}"
|
||||
d:DataContext="{d:DesignInstance Type=vm:EmailAccountDialogViewModel}"
|
||||
CloseButtonCommand="{Binding CancelCommand}"
|
||||
CloseButtonText="取消"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonCommand="{Binding SaveCommand}"
|
||||
PrimaryButtonText="保存"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ui:ContentDialog.Resources>
|
||||
<Style x:Key="LabelStyle" TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="Margin" Value="0,0,10,0" />
|
||||
</Style>
|
||||
</ui:ContentDialog.Resources>
|
||||
|
||||
<ScrollViewer Margin="16">
|
||||
<StackPanel>
|
||||
<!-- 账户名称 -->
|
||||
<hc:TextBox hc:InfoElement.Title="账户名称:"
|
||||
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 邮箱地址 -->
|
||||
<hc:TextBox hc:InfoElement.Title="邮箱地址:"
|
||||
Text="{Binding EmailAddress, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- SMTP服务器 -->
|
||||
<hc:TextBox hc:InfoElement.Title="SMTP服务器:"
|
||||
Text="{Binding SmtpServer, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- SMTP端口 -->
|
||||
<Grid Margin="0,0,0,15">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Style="{StaticResource LabelStyle}" Text="SMTP端口:" />
|
||||
<hc:TextBox Grid.Column="1" Text="{Binding SmtpPort, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
|
||||
<!-- 启用SSL -->
|
||||
<CheckBox Content="启用SSL"
|
||||
IsChecked="{Binding EnableSsl}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 用户名 -->
|
||||
<hc:TextBox hc:InfoElement.Title="用户名:"
|
||||
Text="{Binding Username, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 密码 -->
|
||||
<Grid Margin="0,0,0,15">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Style="{StaticResource LabelStyle}" Text="密码:" />
|
||||
<PasswordBox x:Name="PasswordBox" Grid.Column="1" />
|
||||
</Grid>
|
||||
|
||||
<!-- IMAP服务器 -->
|
||||
<hc:TextBox hc:InfoElement.Title="IMAP服务器 (可选):"
|
||||
Text="{Binding ImapServer, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- IMAP端口 -->
|
||||
<Grid Margin="0,0,0,15">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Style="{StaticResource LabelStyle}" Text="IMAP端口:" />
|
||||
<hc:TextBox Grid.Column="1" Text="{Binding ImapPort, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
|
||||
<!-- 默认账户 -->
|
||||
<CheckBox Content="默认账户"
|
||||
IsChecked="{Binding IsDefault}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 启用 -->
|
||||
<CheckBox Content="启用"
|
||||
IsChecked="{Binding IsActive}"
|
||||
Margin="0,0,0,15"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</ui:ContentDialog>
|
||||
48
DMS.WPF/Views/Dialogs/EmailAccountDialog.xaml.cs
Normal file
48
DMS.WPF/Views/Dialogs/EmailAccountDialog.xaml.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using DMS.WPF.ViewModels.Dialogs;
|
||||
using DMS.WPF.Helper;
|
||||
using iNKORE.UI.WPF.Modern.Controls;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace DMS.WPF.Views.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// EmailAccountDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class EmailAccountDialog : ContentDialog
|
||||
{
|
||||
private const int ContentAreaMaxWidth = 1000;
|
||||
private const int ContentAreaMaxHeight = 800;
|
||||
|
||||
public EmailAccountDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Opened += OnOpened;
|
||||
DataContextChanged += EmailAccountDialog_DataContextChanged;
|
||||
}
|
||||
|
||||
private void OnOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
|
||||
{
|
||||
// 修改对话框内容区域的最大宽度和高度
|
||||
var backgroundElementBorder = VisualTreeFinder.FindVisualChildByName<Border>(this, "BackgroundElement");
|
||||
if (backgroundElementBorder != null)
|
||||
{
|
||||
backgroundElementBorder.MaxWidth = ContentAreaMaxWidth;
|
||||
backgroundElementBorder.MaxHeight = ContentAreaMaxHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private void EmailAccountDialog_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is EmailAccountDialogViewModel viewModel)
|
||||
{
|
||||
// 处理密码框
|
||||
PasswordBox.Password = viewModel.Password;
|
||||
PasswordBox.PasswordChanged += (s, args) =>
|
||||
{
|
||||
viewModel.Password = PasswordBox.Password;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
DMS.WPF/Views/Dialogs/EmailTemplateDialog.xaml
Normal file
63
DMS.WPF/Views/Dialogs/EmailTemplateDialog.xaml
Normal file
@@ -0,0 +1,63 @@
|
||||
<ui:ContentDialog
|
||||
x:Class="DMS.WPF.Views.Dialogs.EmailTemplateDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
xmlns:vm="clr-namespace:DMS.WPF.ViewModels.Dialogs"
|
||||
Title="{Binding DialogTitle}"
|
||||
d:DataContext="{d:DesignInstance Type=vm:EmailTemplateDialogViewModel}"
|
||||
CloseButtonCommand="{Binding CancelCommand}"
|
||||
CloseButtonText="取消"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonCommand="{Binding SaveCommand}"
|
||||
PrimaryButtonText="保存"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<ui:ContentDialog.Resources>
|
||||
<Style x:Key="LabelStyle" TargetType="TextBlock">
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||
<Setter Property="Margin" Value="0,0,10,0" />
|
||||
</Style>
|
||||
</ui:ContentDialog.Resources>
|
||||
|
||||
<ScrollViewer Margin="16">
|
||||
<StackPanel>
|
||||
<!-- 模板名称 -->
|
||||
<hc:TextBox hc:InfoElement.Title="模板名称:"
|
||||
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 模板代码 -->
|
||||
<hc:TextBox hc:InfoElement.Title="模板代码:"
|
||||
Text="{Binding Code, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 邮件主题 -->
|
||||
<hc:TextBox hc:InfoElement.Title="邮件主题:"
|
||||
Text="{Binding Subject, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 邮件内容 -->
|
||||
<TextBlock Text="邮件内容:" Margin="0,0,0,5" />
|
||||
<hc:TextBox Text="{Binding Body, UpdateSourceTrigger=PropertyChanged}"
|
||||
AcceptsReturn="True"
|
||||
TextWrapping="Wrap"
|
||||
Height="150"
|
||||
Margin="0,0,0,15" />
|
||||
|
||||
<!-- HTML格式 -->
|
||||
<CheckBox Content="HTML格式"
|
||||
IsChecked="{Binding IsHtml}"
|
||||
Margin="0,0,0,15"/>
|
||||
|
||||
<!-- 启用 -->
|
||||
<CheckBox Content="启用"
|
||||
IsChecked="{Binding IsActive}"
|
||||
Margin="0,0,0,15"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</ui:ContentDialog>
|
||||
33
DMS.WPF/Views/Dialogs/EmailTemplateDialog.xaml.cs
Normal file
33
DMS.WPF/Views/Dialogs/EmailTemplateDialog.xaml.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
using DMS.WPF.Helper;
|
||||
using iNKORE.UI.WPF.Modern.Controls;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace DMS.WPF.Views.Dialogs
|
||||
{
|
||||
/// <summary>
|
||||
/// EmailTemplateDialog.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class EmailTemplateDialog : ContentDialog
|
||||
{
|
||||
private const int ContentAreaMaxWidth = 1000;
|
||||
private const int ContentAreaMaxHeight = 800;
|
||||
|
||||
public EmailTemplateDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.Opened += OnOpened;
|
||||
}
|
||||
|
||||
private void OnOpened(ContentDialog sender, ContentDialogOpenedEventArgs args)
|
||||
{
|
||||
// 修改对话框内容区域的最大宽度和高度
|
||||
var backgroundElementBorder = VisualTreeFinder.FindVisualChildByName<Border>(this, "BackgroundElement");
|
||||
if (backgroundElementBorder != null)
|
||||
{
|
||||
backgroundElementBorder.MaxWidth = ContentAreaMaxWidth;
|
||||
backgroundElementBorder.MaxHeight = ContentAreaMaxHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
DMS.WPF/Views/EmailManagementView.xaml
Normal file
68
DMS.WPF/Views/EmailManagementView.xaml
Normal file
@@ -0,0 +1,68 @@
|
||||
<UserControl x:Class="DMS.WPF.Views.EmailManagementView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:vm="clr-namespace:DMS.WPF.ViewModels"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=vm:EmailManagementViewModel}"
|
||||
d:DesignHeight="600" d:DesignWidth="800">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,10">
|
||||
<Button Content="刷新" Command="{Binding LoadDataCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="添加账户" Command="{Binding AddEmailAccountCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="编辑账户" Command="{Binding EditEmailAccountCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="删除账户" Command="{Binding DeleteEmailAccountCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="测试连接" Command="{Binding TestEmailAccountCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="添加模板" Command="{Binding AddEmailTemplateCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="编辑模板" Command="{Binding EditEmailTemplateCommand}" Margin="0,0,10,0"/>
|
||||
<Button Content="删除模板" Command="{Binding DeleteEmailTemplateCommand}"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<TabControl Grid.Row="1">
|
||||
<!-- 邮件账户标签页 -->
|
||||
<TabItem Header="邮件账户">
|
||||
<DataGrid ItemsSource="{Binding EmailAccounts}"
|
||||
SelectedItem="{Binding SelectedEmailAccount}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
Margin="0,10,0,0">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="50"/>
|
||||
<DataGridTextColumn Header="名称" Binding="{Binding Name}" Width="150"/>
|
||||
<DataGridTextColumn Header="邮箱地址" Binding="{Binding EmailAddress}" Width="200"/>
|
||||
<DataGridTextColumn Header="SMTP服务器" Binding="{Binding SmtpServer}" Width="150"/>
|
||||
<DataGridTextColumn Header="用户名" Binding="{Binding Username}" Width="150"/>
|
||||
<DataGridTextColumn Header="默认账户" Binding="{Binding IsDefault}" Width="80"/>
|
||||
<DataGridTextColumn Header="启用" Binding="{Binding IsActive}" Width="60"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
|
||||
<!-- 邮件模板标签页 -->
|
||||
<TabItem Header="邮件模板">
|
||||
<DataGrid ItemsSource="{Binding EmailTemplates}"
|
||||
SelectedItem="{Binding SelectedEmailTemplate}"
|
||||
AutoGenerateColumns="False"
|
||||
IsReadOnly="True"
|
||||
Margin="0,10,0,0">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="ID" Binding="{Binding Id}" Width="50"/>
|
||||
<DataGridTextColumn Header="名称" Binding="{Binding Name}" Width="150"/>
|
||||
<DataGridTextColumn Header="代码" Binding="{Binding Code}" Width="100"/>
|
||||
<DataGridTextColumn Header="主题" Binding="{Binding Subject}" Width="200"/>
|
||||
<DataGridTextColumn Header="HTML格式" Binding="{Binding IsHtml}" Width="80"/>
|
||||
<DataGridTextColumn Header="启用" Binding="{Binding IsActive}" Width="60"/>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
26
DMS.WPF/Views/EmailManagementView.xaml.cs
Normal file
26
DMS.WPF/Views/EmailManagementView.xaml.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using DMS.WPF.ViewModels;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace DMS.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// EmailManagementView.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class EmailManagementView : UserControl
|
||||
{
|
||||
public EmailManagementView()
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContextChanged += EmailManagementView_DataContextChanged;
|
||||
}
|
||||
|
||||
private void EmailManagementView_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (DataContext is EmailManagementViewModel viewModel)
|
||||
{
|
||||
// 加载数据
|
||||
viewModel.LoadDataCommand.Execute(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,10 @@
|
||||
<DataTemplate DataType="{x:Type vm:LogHistoryViewModel}">
|
||||
<local:LogHistoryView />
|
||||
</DataTemplate>
|
||||
<!-- 邮件管理页 -->
|
||||
<DataTemplate DataType="{x:Type vm:EmailManagementViewModel}">
|
||||
<local:EmailManagementView />
|
||||
</DataTemplate>
|
||||
<!-- 设备详情页 -->
|
||||
<DataTemplate DataType="{x:Type vm:DeviceDetailViewModel}">
|
||||
<local:DeviceDetailView />
|
||||
|
||||
Reference in New Issue
Block a user