diff --git a/.gitignore b/.gitignore index 0260adb..3508f6e 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,7 @@ *.userosscache *.sln.docstates -# User-specific files (MonoDevelop/Xamarin Studio) +# User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Mono auto generated files diff --git a/src/BackOffice/BackOffice.csproj b/src/BackOffice/BackOffice.csproj index 605345f..29ae5c3 100644 --- a/src/BackOffice/BackOffice.csproj +++ b/src/BackOffice/BackOffice.csproj @@ -143,7 +143,7 @@ - + diff --git a/src/BackOffice/Pages/User/UserMainPage.razor b/src/BackOffice/Pages/User/UserMainPage.razor index 6d2418e..872b9e0 100644 --- a/src/BackOffice/Pages/User/UserMainPage.razor +++ b/src/BackOffice/Pages/User/UserMainPage.razor @@ -28,6 +28,8 @@ + + @@ -46,8 +48,21 @@ - - + + + + @(string.IsNullOrWhiteSpace(context.Item.DefaultAddress) ? "-" : context.Item.DefaultAddress) + + + + + + + @(string.IsNullOrWhiteSpace(context.Item.DefaultPostalCode) ? "-" : context.Item.DefaultPostalCode) + + + diff --git a/src/BackOffice/Pages/User/UserMainPage.razor.cs b/src/BackOffice/Pages/User/UserMainPage.razor.cs index 50d8436..bb612b2 100644 --- a/src/BackOffice/Pages/User/UserMainPage.razor.cs +++ b/src/BackOffice/Pages/User/UserMainPage.razor.cs @@ -1,11 +1,10 @@ using CMSMicroservice.Protobuf.Protos.User; using BackOffice.Common.BaseComponents; +using BackOffice.Common.Utilities; using BackOffice.Pages.User.Components; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MudBlazor; -using System.Text; -using DateTimeConverterCL; using DataModel = CMSMicroservice.Protobuf.Protos.User.GetAllUserByFilterResponseModel; namespace BackOffice.Pages.User; @@ -84,51 +83,63 @@ public partial class UserMainPage { try { - var exportRequest = new GetAllUserByFilterRequest + var filter = _request.Filter?.Clone() ?? new(); + var all = new List(); + const int pageSize = 200; + var page = 1; + + while (page <= 500) { - Filter = _request.Filter?.Clone() ?? new(), - PaginationState = new() { PageNumber = 1, PageSize = 1000 } - }; + var result = await UserContract.GetAllUserByFilterAsync(new GetAllUserByFilterRequest + { + Filter = filter, + PaginationState = new() { PageNumber = page, PageSize = pageSize } + }); - var result = await UserContract.GetAllUserByFilterAsync(exportRequest); + var batch = result?.Models?.ToList() ?? new(); + if (batch.Count == 0) + break; - if (result?.Models == null || !result.Models.Any()) + all.AddRange(batch); + + var hasNext = result?.MetaData?.HasNext == true; + if (!hasNext || batch.Count < pageSize) + break; + + page++; + } + + if (all.Count == 0) { Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info); return; } - var sb = new StringBuilder(); - sb.AppendLine("شناسه,موبایل,نام,نام خانوادگی,کدملی"); - - foreach (var u in result.Models) + var headers = new[] { - sb.AppendLine(string.Join(",", - u.Id, - EscapeCsv(u.Mobile), - EscapeCsv(u.FirstName), - EscapeCsv(u.LastName), - EscapeCsv(u.NationalCode))); - } + "شناسه", "موبایل", "نام", "نام خانوادگی", "کدملی", + "آدرس پیش‌فرض", "کدپستی پیش‌فرض" + }; - var bytes = Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(sb.ToString())).ToArray(); - var base64 = Convert.ToBase64String(bytes); - var filename = $"users-{DateTime.Now:yyyyMMddHHmmss}.csv"; + var rows = all.Select(u => new object?[] + { + u.Id, + u.Mobile, + u.FirstName, + u.LastName, + u.NationalCode, + u.DefaultAddress, + u.DefaultPostalCode + }); - await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, base64); - Snackbar.Add("خروجی Excel (CSV) آماده شد.", Severity.Success); + var filename = $"users-{DateTime.Now:yyyyMMddHHmmss}.xls"; + await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename, + CsvExportHelper.ToExcelXmlBase64("کاربران", headers, rows)); + Snackbar.Add($"خروجی Excel آماده شد ({all.Count} کاربر).", Severity.Success); } catch (Exception ex) { Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error); } } - - private static string EscapeCsv(string value) - { - if (string.IsNullOrEmpty(value)) return ""; - if (value.Contains(',') || value.Contains('"') || value.Contains('\n')) - return $"\"{value.Replace("\"", "\"\"")}\""; - return value; - } }