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;
- }
}