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/Club/ClubMembers.razor b/src/BackOffice/Pages/Club/ClubMembers.razor index da3e8f6..df466a1 100644 --- a/src/BackOffice/Pages/Club/ClubMembers.razor +++ b/src/BackOffice/Pages/Club/ClubMembers.razor @@ -33,12 +33,6 @@ StartIcon="@Icons.Material.Filled.Refresh"> بارگذاری - - فعال‌سازی عضو جدید - ("فعال‌سازی عضویت باشگاه", new DialogOptions - { - CloseButton = true, - MaxWidth = MaxWidth.Small, - FullWidth = true - }); - - var result = await dialog.Result; - if (!result.Canceled) - { - Snackbar.Add("عضویت با موفقیت فعال شد", Severity.Success); - await ApplyFilter(); - } - } - private async Task ViewDetails(ClubMembershipModel member) { var parameters = new DialogParameters diff --git a/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor b/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor deleted file mode 100644 index cc9d66e..0000000 --- a/src/BackOffice/Pages/Club/Components/ActivateClubDialog.razor +++ /dev/null @@ -1,156 +0,0 @@ -@using CMSMicroservice.Protobuf.Protos.ClubMembership -@using CMSMicroservice.Protobuf.Protos.Package -@using BackOffice.Pages.AutoComplete - - - - - - - - @if (_isLoadingPackages) - { - - } - else - { - - @foreach (var pkg in _packages) - { - - @pkg.Title — @($"{pkg.Price:N0}") ریال - - } - - } - - - - با تایید، عضویت باشگاه برای کاربر فعال می‌شود. -
- عضویت باشگاه بدون محدودیت زمانی است. -
-
-
-
-
- - لغو - - @if (_isSubmitting) - { - - در حال پردازش... - } - else - { - تایید و فعال‌سازی - } - - -
- -@code { - [CascadingParameter] IMudDialogInstance MudDialog { get; set; } - [Inject] public ClubMembershipContract.ClubMembershipContractClient ClubContract { get; set; } - [Inject] public PackageContract.PackageContractClient PackageClient { get; set; } - - private MudForm _form; - private bool _formValid; - private bool _isSubmitting; - private bool _isLoadingPackages = true; - private List _packages = new(); - private ActivateModel _model = new(); - - protected override async Task OnInitializedAsync() - { - await LoadPackages(); - } - - private async Task LoadPackages() - { - _isLoadingPackages = true; - try - { - var request = new GetAllPackageByFilterRequest - { - PaginationState = new CMSMicroservice.Protobuf.Protos.PaginationState - { - PageNumber = 1, - PageSize = 50 - } - }; - var result = await PackageClient.GetAllPackageByFilterAsync(request); - if (result?.Models != null) - { - _packages = result.Models.ToList(); - } - } - catch (Exception ex) - { - Snackbar.Add($"خطا در بارگذاری پکیج‌ها: {ex.Message}", Severity.Error); - } - finally - { - _isLoadingPackages = false; - } - } - - private void Cancel() => MudDialog.Cancel(); - - private async Task Submit() - { - await _form.Validate(); - if (!_formValid) return; - - if (!_model.UserId.HasValue || _model.UserId.Value <= 0) - { - Snackbar.Add("لطفاً کاربر را انتخاب کنید.", Severity.Warning); - return; - } - - if (_model.PackageId <= 0) - { - Snackbar.Add("لطفاً پکیج را انتخاب کنید.", Severity.Warning); - return; - } - - _isSubmitting = true; - try - { - var request = new ActivateClubMembershipRequest - { - UserId = _model.UserId.Value, - PackageId = _model.PackageId, - ForceActivation = true - }; - - var response = await ClubContract.ActivateClubMembershipAsync(request); - - Snackbar.Add("عضویت با موفقیت فعال شد.", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - catch (Exception ex) - { - Snackbar.Add($"خطا: {ex.Message}", Severity.Error); - } - finally - { - _isSubmitting = false; - } - } - - private class ActivateModel - { - public long? UserId { get; set; } - public long PackageId { get; set; } - } -} 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; - } }