Prac2026_Email/ListmonkIntegration/Pages/Subscribers/Upload.cshtml.cs
2026-07-15 17:17:03 +03:00

215 lines
8.1 KiB
C#

using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using ListmonkIntegration.Services;
using ListmonkIntegration.Models;
using ClosedXML.Excel;
namespace ListmonkIntegration.Pages.Subscribers
{
public class UploadModel : PageModel
{
private readonly IListmonkService _listmonkService;
private readonly ILogger<UploadModel> _logger;
[BindProperty]
public IFormFile? excelFile { get; set; }
public List<Subscriber> Subscribers { get; set; } = new List<Subscriber>();
public List<string> ColumnHeaders { get; set; } = new List<string>();
public string Message { get; set; } = string.Empty;
public bool IsSuccess { get; set; }
public UploadModel(IListmonkService listmonkService, ILogger<UploadModel> logger)
{
_listmonkService = listmonkService;
_logger = logger;
}
public void OnGet()
{
}
public async Task<IActionResult> OnPostAsync(string listName)
{
try
{
_logger.LogInformation("=== Upload started ===");
if (excelFile == null || excelFile.Length == 0)
{
Message = "Ôàéë íå âûáðàí";
IsSuccess = false;
return Page();
}
_logger.LogInformation($"File received: {excelFile.FileName}, Size: {excelFile.Length} bytes");
// Îãðàíè÷åíèå ðàçìåðà ôàéëà (10 MB)
if (excelFile.Length > 10 * 1024 * 1024)
{
Message = "Ôàéë ñëèøêîì áîëüøîé (ìàêñèìóì 10 MB)";
IsSuccess = false;
return Page();
}
// ×òåíèå Excel ôàéëà
_logger.LogInformation("Reading Excel file...");
Subscribers = ReadExcelFile(excelFile);
_logger.LogInformation($"Read {Subscribers.Count} subscribers");
if (!Subscribers.Any())
{
Message = "Íå íàéäåíî ïîäïèñ÷èêîâ â ôàéëå";
IsSuccess = false;
return Page();
}
// Ïðîâåðÿåì ïîäêëþ÷åíèå
_logger.LogInformation("Testing Listmonk connection...");
if (!await _listmonkService.TestConnectionAsync())
{
Message = "Íåò ïîäêëþ÷åíèÿ ê Listmonk";
IsSuccess = false;
return Page();
}
// Ñîçäàåì ñïèñîê
_logger.LogInformation($"Creating list: {listName}");
int listId = await _listmonkService.CreateListAsync(listName);
// Èìïîðòèðóåì
_logger.LogInformation($"Importing to list {listId}...");
await _listmonkService.ImportSubscribersAsync(new List<int> { listId }, Subscribers);
Message = $"Óñïåøíî çàãðóæåíî {Subscribers.Count} ïîäïèñ÷èêîâ â ñïèñîê \"{listName}\"";
IsSuccess = true;
_logger.LogInformation("=== Upload completed successfully ===");
}
catch (Exception ex)
{
Message = $"Îøèáêà: {ex.Message}";
IsSuccess = false;
_logger.LogError(ex, "=== Upload failed ===");
}
return Page();
}
private List<Subscriber> ReadExcelFile(IFormFile file)
{
var subscribers = new List<Subscriber>();
try
{
// Ñîçäà¸ì âðåìåííûé ôàéë ñ ïðàâèëüíûì ðàñøèðåíèåì .xlsx
var tempFilePath = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.xlsx");
_logger.LogInformation($"Temp file: {tempFilePath}");
try
{
// Ñîõðàíÿåì çàãðóæåííûé ôàéë âî âðåìåííûé ôàéë
using (var stream = new FileStream(tempFilePath, FileMode.Create))
{
file.CopyTo(stream);
}
_logger.LogInformation("Opening workbook...");
using (var workbook = new XLWorkbook(tempFilePath))
{
var worksheet = workbook.Worksheet(1);
var firstRow = worksheet.FirstRowUsed();
if (firstRow == null)
{
_logger.LogWarning("Empty file");
return subscribers;
}
// Çàãîëîâêè
var headers = new List<string>();
foreach (var cell in firstRow.Cells())
{
var header = cell.Value.ToString().Trim();
headers.Add(header);
_logger.LogInformation($"Header: {header}");
}
ColumnHeaders = headers;
_logger.LogInformation($"Total headers: {headers.Count}");
if (headers.Count < 2)
{
_logger.LogError("Need at least 2 columns");
return subscribers;
}
// Äàííûå
var lastRow = worksheet.LastRowUsed();
_logger.LogInformation($"Last row: {lastRow?.RowNumber() ?? 0}");
for (int row = 2; row <= lastRow.RowNumber(); row++)
{
try
{
var email = worksheet.Cell(row, 1).GetValue<string>().Trim();
if (string.IsNullOrWhiteSpace(email))
{
_logger.LogWarning($"Row {row}: empty email, skipping");
continue;
}
var name = worksheet.Cell(row, 2).GetValue<string>().Trim();
var attributes = new Dictionary<string, string>();
for (int col = 3; col <= headers.Count; col++)
{
var value = worksheet.Cell(row, col).GetValue<string>().Trim();
if (!string.IsNullOrWhiteSpace(value))
{
attributes[headers[col - 1]] = value;
}
}
subscribers.Add(new Subscriber
{
Email = email,
FullName = name,
Attributes = attributes
});
_logger.LogInformation($"Row {row}: Added {email}");
}
catch (Exception rowEx)
{
_logger.LogWarning(rowEx, $"Skipping row {row}");
}
}
}
}
finally
{
// Óäàëÿåì âðåìåííûé ôàéë
if (System.IO.File.Exists(tempFilePath))
{
try
{
System.IO.File.Delete(tempFilePath);
_logger.LogInformation($"Deleted temp file: {tempFilePath}");
}
catch (Exception ex)
{
_logger.LogWarning(ex, $"Failed to delete temp file: {tempFilePath}");
}
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error reading Excel");
throw;
}
return subscribers;
}
}
}