继续完成邮件功能
This commit is contained in:
@@ -269,6 +269,7 @@ public partial class App : System.Windows.Application
|
||||
services.AddSingleton<ILogDataService, LogDataService>();
|
||||
services.AddSingleton<IDataEventService, DataEventService>();
|
||||
services.AddSingleton<IDataStorageService, DataStorageService>();
|
||||
services.AddSingleton<IEmailDataService, EmailDataService>();
|
||||
|
||||
// 注册主数据服务
|
||||
services.AddSingleton<IWPFDataService, WPFDataService>();
|
||||
|
||||
60
DMS.WPF/Interfaces/IEmailDataService.cs
Normal file
60
DMS.WPF/Interfaces/IEmailDataService.cs
Normal file
@@ -0,0 +1,60 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using DMS.Application.DTOs;
|
||||
|
||||
namespace DMS.WPF.Interfaces;
|
||||
|
||||
/// <summary>
|
||||
/// 邮件数据服务接口。
|
||||
/// </summary>
|
||||
public interface IEmailDataService
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件账户列表。
|
||||
/// </summary>
|
||||
ObservableCollection<EmailAccountDto> EmailAccounts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮件模板列表。
|
||||
/// </summary>
|
||||
ObservableCollection<EmailTemplateDto> EmailTemplates { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加载所有邮件数据。
|
||||
/// </summary>
|
||||
void LoadAllEmailData();
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件账户。
|
||||
/// </summary>
|
||||
Task<EmailAccountDto> AddEmailAccountAsync(CreateEmailAccountRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 更新邮件账户。
|
||||
/// </summary>
|
||||
Task<bool> UpdateEmailAccountAsync(int id, CreateEmailAccountRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件账户。
|
||||
/// </summary>
|
||||
Task<bool> DeleteEmailAccountAsync(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 测试邮件账户连接。
|
||||
/// </summary>
|
||||
Task<bool> TestEmailAccountAsync(int id);
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件模板。
|
||||
/// </summary>
|
||||
Task<EmailTemplateDto> AddEmailTemplateAsync(EmailTemplateDto template);
|
||||
|
||||
/// <summary>
|
||||
/// 更新邮件模板。
|
||||
/// </summary>
|
||||
Task<bool> UpdateEmailTemplateAsync(int id, EmailTemplateDto template);
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件模板。
|
||||
/// </summary>
|
||||
Task<bool> DeleteEmailTemplateAsync(int id);
|
||||
}
|
||||
@@ -28,7 +28,8 @@ namespace DMS.WPF.Services
|
||||
{ typeof(MqttAliasBatchEditDialogViewModel), typeof(MqttAliasBatchEditDialog) },
|
||||
{ typeof(HistorySettingsDialogViewModel), typeof(HistorySettingsDialog) },
|
||||
{ typeof(AlarmSettingsDialogViewModel), typeof(AlarmSettingsDialog) },
|
||||
{ typeof(EmailAccountDialogViewModel), typeof(EmailAccountDialog) }
|
||||
{ typeof(EmailAccountDialogViewModel), typeof(EmailAccountDialog) },
|
||||
{ typeof(EmailTemplateDialogViewModel), typeof(EmailTemplateDialog) }
|
||||
// Add other mappings here
|
||||
// ... other dialogs
|
||||
};
|
||||
|
||||
241
DMS.WPF/Services/EmailDataService.cs
Normal file
241
DMS.WPF/Services/EmailDataService.cs
Normal file
@@ -0,0 +1,241 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows.Threading;
|
||||
using AutoMapper;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using DMS.Application.DTOs;
|
||||
using DMS.Application.Interfaces;
|
||||
using DMS.WPF.Interfaces;
|
||||
|
||||
namespace DMS.WPF.Services;
|
||||
|
||||
/// <summary>
|
||||
/// 邮件数据服务类,负责管理邮件相关的数据和操作。
|
||||
/// </summary>
|
||||
public class EmailDataService : IEmailDataService
|
||||
{
|
||||
private readonly IMapper _mapper;
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly INotificationService _notificationService;
|
||||
private readonly Dispatcher _uiDispatcher;
|
||||
|
||||
/// <summary>
|
||||
/// 邮件账户列表。
|
||||
/// </summary>
|
||||
public ObservableCollection<EmailAccountDto> EmailAccounts { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// 邮件模板列表。
|
||||
/// </summary>
|
||||
public ObservableCollection<EmailTemplateDto> EmailTemplates { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// EmailDataService类的构造函数。
|
||||
/// </summary>
|
||||
/// <param name="mapper">AutoMapper 实例。</param>
|
||||
/// <param name="emailAppService">邮件应用服务实例。</param>
|
||||
/// <param name="notificationService">通知服务实例。</param>
|
||||
public EmailDataService(IMapper mapper, IEmailAppService emailAppService, INotificationService notificationService)
|
||||
{
|
||||
_mapper = mapper;
|
||||
_emailAppService = emailAppService;
|
||||
_notificationService = notificationService;
|
||||
_uiDispatcher = Dispatcher.CurrentDispatcher;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载所有邮件数据。
|
||||
/// </summary>
|
||||
public void LoadAllEmailData()
|
||||
{
|
||||
_ = LoadAllEmailDataAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步加载所有邮件数据。
|
||||
/// </summary>
|
||||
private async Task LoadAllEmailDataAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// 加载邮件账户
|
||||
var accounts = await _emailAppService.GetAllEmailAccountsAsync();
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
EmailAccounts.Clear();
|
||||
foreach (var account in accounts)
|
||||
{
|
||||
EmailAccounts.Add(account);
|
||||
}
|
||||
});
|
||||
|
||||
// 加载邮件模板
|
||||
var templates = await _emailAppService.GetAllEmailTemplatesAsync();
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
EmailTemplates.Clear();
|
||||
foreach (var template in templates)
|
||||
{
|
||||
EmailTemplates.Add(template);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("加载邮件数据失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件账户。
|
||||
/// </summary>
|
||||
public async Task<EmailAccountDto> AddEmailAccountAsync(CreateEmailAccountRequest request)
|
||||
{
|
||||
var emailAccount = await _emailAppService.CreateEmailAccountAsync(request);
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
EmailAccounts.Add(emailAccount);
|
||||
});
|
||||
return emailAccount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新邮件账户。
|
||||
/// </summary>
|
||||
public async Task<bool> UpdateEmailAccountAsync(int id, CreateEmailAccountRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var emailAccount = await _emailAppService.UpdateEmailAccountAsync(id, request);
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
var existingAccount = EmailAccounts.FirstOrDefault(a => a.Id == id);
|
||||
if (existingAccount != null)
|
||||
{
|
||||
// 更新现有账户的信息
|
||||
var index = EmailAccounts.IndexOf(existingAccount);
|
||||
EmailAccounts[index] = emailAccount;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("更新邮件账户失败", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件账户。
|
||||
/// </summary>
|
||||
public async Task<bool> DeleteEmailAccountAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _emailAppService.DeleteEmailAccountAsync(id);
|
||||
if (result)
|
||||
{
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
var accountToRemove = EmailAccounts.FirstOrDefault(a => a.Id == id);
|
||||
if (accountToRemove != null)
|
||||
{
|
||||
EmailAccounts.Remove(accountToRemove);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("删除邮件账户失败", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 测试邮件账户连接。
|
||||
/// </summary>
|
||||
public async Task<bool> TestEmailAccountAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _emailAppService.TestEmailAccountAsync(id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("测试邮件账户连接失败", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件模板。
|
||||
/// </summary>
|
||||
public async Task<EmailTemplateDto> AddEmailTemplateAsync(EmailTemplateDto template)
|
||||
{
|
||||
var emailTemplate = await _emailAppService.CreateEmailTemplateAsync(template);
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
EmailTemplates.Add(emailTemplate);
|
||||
});
|
||||
return emailTemplate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新邮件模板。
|
||||
/// </summary>
|
||||
public async Task<bool> UpdateEmailTemplateAsync(int id, EmailTemplateDto template)
|
||||
{
|
||||
try
|
||||
{
|
||||
var emailTemplate = await _emailAppService.UpdateEmailTemplateAsync(id, template);
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
var existingTemplate = EmailTemplates.FirstOrDefault(t => t.Id == id);
|
||||
if (existingTemplate != null)
|
||||
{
|
||||
// 更新现有模板的信息
|
||||
var index = EmailTemplates.IndexOf(existingTemplate);
|
||||
EmailTemplates[index] = emailTemplate;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("更新邮件模板失败", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件模板。
|
||||
/// </summary>
|
||||
public async Task<bool> DeleteEmailTemplateAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _emailAppService.DeleteEmailTemplateAsync(id);
|
||||
if (result)
|
||||
{
|
||||
_uiDispatcher.Invoke(() =>
|
||||
{
|
||||
var templateToRemove = EmailTemplates.FirstOrDefault(t => t.Id == id);
|
||||
if (templateToRemove != null)
|
||||
{
|
||||
EmailTemplates.Remove(templateToRemove);
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("删除邮件模板失败", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,19 +86,20 @@ namespace DMS.WPF.ViewModels.Dialogs
|
||||
IsActive = IsActive
|
||||
};
|
||||
|
||||
EmailTemplateDto resultTemplate;
|
||||
if (_isEditMode)
|
||||
{
|
||||
await _emailAppService.UpdateEmailTemplateAsync(_templateId, template);
|
||||
resultTemplate = await _emailAppService.UpdateEmailTemplateAsync(_templateId, template);
|
||||
_notificationService.ShowSuccess("邮件模板更新成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
await _emailAppService.CreateEmailTemplateAsync(template);
|
||||
resultTemplate = await _emailAppService.CreateEmailTemplateAsync(template);
|
||||
_notificationService.ShowSuccess("邮件模板创建成功");
|
||||
}
|
||||
|
||||
CloseRequested?.Invoke(true);
|
||||
await Close(new EmailTemplateDto());
|
||||
await Close(resultTemplate);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace DMS.WPF.ViewModels
|
||||
public partial class EmailManagementViewModel : ViewModelBase
|
||||
{
|
||||
private readonly IEmailAppService _emailAppService;
|
||||
private readonly IEmailDataService _emailDataService;
|
||||
private readonly IDialogService _dialogService;
|
||||
private readonly INotificationService _notificationService;
|
||||
|
||||
@@ -32,12 +33,18 @@ namespace DMS.WPF.ViewModels
|
||||
|
||||
public EmailManagementViewModel(
|
||||
IEmailAppService emailAppService,
|
||||
IEmailDataService emailDataService,
|
||||
IDialogService dialogService,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
_emailAppService = emailAppService;
|
||||
_emailDataService = emailDataService;
|
||||
_dialogService = dialogService;
|
||||
_notificationService = notificationService;
|
||||
|
||||
// 绑定数据集合
|
||||
_emailAccounts = _emailDataService.EmailAccounts;
|
||||
_emailTemplates = _emailDataService.EmailTemplates;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -48,13 +55,11 @@ namespace DMS.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
// 加载邮件账户
|
||||
var accounts = await _emailAppService.GetAllEmailAccountsAsync();
|
||||
EmailAccounts = new ObservableCollection<EmailAccountDto>(accounts);
|
||||
// 使用EmailDataService加载所有邮件数据
|
||||
_emailDataService.LoadAllEmailData();
|
||||
|
||||
// 加载邮件模板
|
||||
var templates = await _emailAppService.GetAllEmailTemplatesAsync();
|
||||
EmailTemplates = new ObservableCollection<EmailTemplateDto>(templates);
|
||||
// 等待一段时间确保数据加载完成
|
||||
await Task.Delay(100);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -75,6 +80,30 @@ namespace DMS.WPF.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var request = new CreateEmailAccountRequest
|
||||
{
|
||||
Name = emailAccountDto.Name,
|
||||
EmailAddress = emailAccountDto.EmailAddress,
|
||||
SmtpServer = emailAccountDto.SmtpServer,
|
||||
SmtpPort = emailAccountDto.SmtpPort,
|
||||
EnableSsl = emailAccountDto.EnableSsl,
|
||||
Username = emailAccountDto.Username,
|
||||
Password = emailAccountDto.Password,
|
||||
ImapServer = emailAccountDto.ImapServer,
|
||||
ImapPort = emailAccountDto.ImapPort,
|
||||
IsDefault = emailAccountDto.IsDefault,
|
||||
IsActive = emailAccountDto.IsActive
|
||||
};
|
||||
|
||||
await _emailDataService.AddEmailAccountAsync(request);
|
||||
_notificationService.ShowSuccess("添加邮件账户成功");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("添加邮件账户失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -96,13 +125,37 @@ namespace DMS.WPF.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
// var dialog = _dialogService.CreateDialog<EmailAccountDialogViewModel>();
|
||||
// dialog.SetEmailAccount(SelectedEmailAccount);
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
try
|
||||
{
|
||||
var request = new CreateEmailAccountRequest
|
||||
{
|
||||
Name = emailAccountDto.Name,
|
||||
EmailAddress = emailAccountDto.EmailAddress,
|
||||
SmtpServer = emailAccountDto.SmtpServer,
|
||||
SmtpPort = emailAccountDto.SmtpPort,
|
||||
EnableSsl = emailAccountDto.EnableSsl,
|
||||
Username = emailAccountDto.Username,
|
||||
Password = emailAccountDto.Password,
|
||||
ImapServer = emailAccountDto.ImapServer,
|
||||
ImapPort = emailAccountDto.ImapPort,
|
||||
IsDefault = emailAccountDto.IsDefault,
|
||||
IsActive = emailAccountDto.IsActive
|
||||
};
|
||||
|
||||
var result = await _emailDataService.UpdateEmailAccountAsync(SelectedEmailAccount.Id, request);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("更新邮件账户成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationService.ShowError("更新邮件账户失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("更新邮件账户失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -127,9 +180,15 @@ namespace DMS.WPF.ViewModels
|
||||
{
|
||||
try
|
||||
{
|
||||
await _emailAppService.DeleteEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
var result = await _emailDataService.DeleteEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("删除成功");
|
||||
await LoadDataAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationService.ShowError("删除失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -152,7 +211,7 @@ namespace DMS.WPF.ViewModels
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _emailAppService.TestEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
var result = await _emailDataService.TestEmailAccountAsync(SelectedEmailAccount.Id);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("连接测试成功");
|
||||
@@ -174,12 +233,22 @@ namespace DMS.WPF.ViewModels
|
||||
[RelayCommand]
|
||||
private async Task AddEmailTemplateAsync()
|
||||
{
|
||||
// var dialog = _dialogService.CreateDialog<EmailTemplateDialogViewModel>();
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
var viewModel = App.Current.Services.GetRequiredService<EmailTemplateDialogViewModel>();
|
||||
var emailTemplateDto = await _dialogService.ShowDialogAsync(viewModel);
|
||||
if (emailTemplateDto == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _emailDataService.AddEmailTemplateAsync(emailTemplateDto);
|
||||
_notificationService.ShowSuccess("添加邮件模板成功");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("添加邮件模板失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -194,13 +263,30 @@ namespace DMS.WPF.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
// var dialog = _dialogService.CreateDialog<EmailTemplateDialogViewModel>();
|
||||
// dialog.SetEmailTemplate(SelectedEmailTemplate);
|
||||
// var result = await dialog.ShowAsync();
|
||||
// if (result == true)
|
||||
// {
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
var viewModel = App.Current.Services.GetRequiredService<EmailTemplateDialogViewModel>();
|
||||
viewModel.SetEmailTemplate(SelectedEmailTemplate);
|
||||
var emailTemplateDto = await _dialogService.ShowDialogAsync(viewModel);
|
||||
if (emailTemplateDto == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var result = await _emailDataService.UpdateEmailTemplateAsync(SelectedEmailTemplate.Id, emailTemplateDto);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("更新邮件模板成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationService.ShowError("更新邮件模板失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("更新邮件模板失败", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -215,23 +301,31 @@ namespace DMS.WPF.ViewModels
|
||||
return;
|
||||
}
|
||||
|
||||
// var confirmResult = await _dialogService.ShowConfirmDialogAsync(
|
||||
// "确认删除",
|
||||
// $"确定要删除邮件模板 {SelectedEmailTemplate.Name} 吗?");
|
||||
var confirmDialogViewModel = new ConfirmDialogViewModel(
|
||||
"确认删除",
|
||||
$"确定要删除邮件模板 {SelectedEmailTemplate.Name} 吗?", "删除");
|
||||
|
||||
// if (confirmResult == true)
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// await _emailAppService.DeleteEmailTemplateAsync(SelectedEmailTemplate.Id);
|
||||
// _notificationService.ShowSuccess("删除成功");
|
||||
// await LoadDataAsync();
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// _notificationService.ShowError("删除失败", ex);
|
||||
// }
|
||||
// }
|
||||
var confirmResult = await _dialogService.ShowDialogAsync(confirmDialogViewModel);
|
||||
|
||||
if (confirmResult == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _emailDataService.DeleteEmailTemplateAsync(SelectedEmailTemplate.Id);
|
||||
if (result)
|
||||
{
|
||||
_notificationService.ShowSuccess("删除成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
_notificationService.ShowError("删除失败");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_notificationService.ShowError("删除失败", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user