Files
BackOffice/src/BackOffice/Pages/UserOrder/UserOrderMainPage.razor.cs
T
masoodafar-web e9f8328404 feat(export): enhance CSV and Excel export functionality across multiple pages
- Updated CsvExportHelper to support Excel XML format for exporting data, improving compatibility with Excel.
- Refactored export logic in DiscountOrdersMainPage, SalesReports, OrderSalesReports, and UserOrderMainPage to utilize the new Excel export method.
- Changed file extensions from .csv to .xls for better clarity in exported files.
- Improved header and row data handling for consistency in exported reports.
2026-08-08 21:43:54 +03:30

360 lines
11 KiB
C#

using System.Text;
using System.Text.Json;
using BackOffice.Common.BaseComponents;
using BackOffice.Common.Utilities;
using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.UserOrder;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using MudBlazor;
using DateTimeConverterCL;
using DataModel = CMSMicroservice.Protobuf.Protos.UserOrder.GetAllUserOrderByFilterResponseModel;
using Google.Protobuf.WellKnownTypes;
namespace BackOffice.Pages.UserOrder;
public partial class UserOrderMainPage
{
[Parameter] public long? UserId { get; set; }
[Inject] public UserOrderContract.UserOrderContractClient UserOrderContract { get; set; }
[Inject] public IJSRuntime JsRuntime { get; set; }
private bool _isLoading = true;
private MudDataGrid<DataModel> _gridData;
BasePageComponent _basePage;
private long? _orderIdFilter;
private long? _userIdFilter;
private long? _transactionIdFilter;
private int? _paymentStatusFilter;
private int? _deliveryStatusFilter;
private int? _paymentMethodFilter;
private DateTime? _paymentDateFrom;
private DateTime? _paymentDateTo;
private GetAllUserOrderByFilterRequest _request = new() { Filter = new() };
private async Task<GridData<DataModel>> ServerReload(GridState<DataModel> state)
{
try
{
_request.Filter ??= new();
_request.PaginationState ??= new();
_request.PaginationState.PageNumber = state.Page + 1;
_request.PaginationState.PageSize = state.PageSize;
if (_orderIdFilter.HasValue && _orderIdFilter.Value > 0)
{
_request.Filter.Id = _orderIdFilter.Value;
}
else
{
_request.Filter.Id = null;
}
if (UserId.HasValue && UserId.Value > 0)
{
_request.Filter.UserId = UserId.Value;
}
else
{
_request.Filter.UserId = _userIdFilter.HasValue && _userIdFilter.Value > 0
? _userIdFilter.Value
: null;
}
if (_paymentDateFrom.HasValue)
{
_request.Filter.FromDate =
Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateFrom.Value.Date, DateTimeKind.Utc));
}
else
{
_request.Filter.FromDate = null;
}
if (_paymentDateTo.HasValue)
{
_request.Filter.ToDate =
Timestamp.FromDateTime(DateTime.SpecifyKind(_paymentDateTo.Value.Date.AddDays(1).AddTicks(-1), DateTimeKind.Utc));
}
else
{
_request.Filter.ToDate = null;
}
if (_paymentStatusFilter.HasValue)
{
_request.Filter.PaymentStatus = (PaymentStatus)_paymentStatusFilter.Value;
}
else
{
_request.Filter.ClearPaymentStatusItem();
}
if (_deliveryStatusFilter.HasValue)
{
_request.Filter.DeliveryStatus = (DeliveryStatus)_deliveryStatusFilter.Value;
}
else
{
_request.Filter.ClearDeliveryStatusItem();
}
if (_paymentMethodFilter.HasValue)
{
_request.Filter.PaymentMethod = (PaymentMethod)_paymentMethodFilter.Value;
}
else
{
_request.Filter.ClearPaymentMethodItem();
}
if (_transactionIdFilter.HasValue && _transactionIdFilter.Value > 0)
{
_request.Filter.TransactionId = _transactionIdFilter.Value;
}
else
{
_request.Filter.TransactionId = null;
}
var result = await UserOrderContract.GetAllUserOrderByFilterAsync(_request);
if (result != null && result.Models != null && result.Models.Any())
{
return new GridData<DataModel>
{
Items = result.Models.ToList(),
TotalItems = (int)result.MetaData.TotalCount
};
}
return new GridData<DataModel>();
}
catch (Exception ex)
{
Snackbar.Add($"خطا در بارگذاری سفارشات: {ex.Message}", MudBlazor.Severity.Error);
return new GridData<DataModel>();
}
}
private async Task OpenDetails(DataModel model)
{
var parameters = new DialogParameters
{
{ nameof(BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog.OrderId), model.Id }
};
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Large, FullWidth = true };
var dialog =
await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.UserOrderDetailsDialog>("جزئیات سفارش",
parameters, options);
var result = await dialog.Result;
if (!result.Canceled)
{
ReLoadData();
}
}
private async Task OnDelete(DataModel model)
{
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small };
bool? result = await DialogService.ShowMessageBox(
"اخطار",
$"آیا از حذف سفارش شماره «{model.Id}» مطمئن هستید؟",
yesText: "حذف", cancelText: "لغو",
options: options);
if (result != null && result.Value)
{
await UserOrderContract.DeleteUserOrderAsync(new()
{
Id = model.Id
});
ReLoadData();
}
StateHasChanged();
}
public async void ReLoadData()
{
if (_gridData != null)
await _gridData.ReloadServerData();
}
public async Task OnFilterSubmit()
{
_basePage.IsFiltered = true;
StateHasChanged();
ReLoadData();
}
public async Task OnFilterCleared()
{
_basePage.IsFiltered = false;
StateHasChanged();
_request = new() { Filter = new() { } };
_orderIdFilter = null;
_userIdFilter = null;
_transactionIdFilter = null;
_paymentStatusFilter = null;
_deliveryStatusFilter = null;
_paymentDateFrom = null;
_paymentDateTo = null;
_paymentMethodFilter = null;
ReLoadData();
}
private Color GetDeliveryStatusColor(int status)
{
return status switch
{
1 => Color.Warning, // Pending
2 => Color.Info, // InTransit
3 => Color.Success, // Delivered
4 => Color.Error, // Returned
5 => Color.Dark, // Cancelled
6 => Color.Primary, // ReadyForOfficePickup
_ => Color.Default // None / Unknown
};
}
private string GetDeliveryStatusText(int status)
{
return status switch
{
1 => "در انتظار ارسال",
2 => "تحویل پست",
3 => "تحویل به مشتری",
4 => "مرجوع شده",
5 => "لغو شده",
6 => "آماده تحویل در دفتر",
_ => "بدون ارسال / نامشخص"
};
}
private string GetPaymentMethodText(int method)
{
return method switch
{
1 => "کیف پول",
_ => "درگاه پرداخت"
};
}
// Domain PaymentStatus: Success=0, Reject=1, Pending=2
private static string GetPaymentStatusText(int status) => status switch
{
0 => "پرداخت شده",
1 => "پرداخت ناموفق",
2 => "در انتظار پرداخت",
_ => "نامشخص"
};
private async Task OpenChangeStatus(DataModel model)
{
var parameters = new DialogParameters
{
{ nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.OrderId), model.Id },
{ nameof(BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog.CurrentStatus), model.DeliveryStatus.GetHashCode() }
};
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ChangeOrderStatusDialog>(
"تغییر وضعیت ارسال سفارش", parameters, options);
var result = await dialog.Result;
if (!result.Canceled)
{
ReLoadData();
}
}
private async Task OpenApplyDiscount(DataModel model)
{
var parameters = new DialogParameters
{
{ nameof(BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog.OrderId), model.Id }
};
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.ApplyDiscountDialog>(
"اعمال تخفیف روی سفارش", parameters, options);
var result = await dialog.Result;
if (!result.Canceled)
{
ReLoadData();
}
}
private async Task OpenCancelOrder(DataModel model)
{
var parameters = new DialogParameters
{
{ nameof(BackOffice.Pages.UserOrder.Components.CancelOrderDialog.OrderId), model.Id }
};
var options = new DialogOptions { CloseOnEscapeKey = true, MaxWidth = MaxWidth.Small, FullWidth = true };
var dialog = await DialogService.ShowAsync<BackOffice.Pages.UserOrder.Components.CancelOrderDialog>(
"لغو سفارش", parameters, options);
var result = await dialog.Result;
if (!result.Canceled)
{
ReLoadData();
}
}
private async Task ExportToExcel()
{
try
{
var exportRequest = new GetAllUserOrderByFilterRequest
{
Filter = _request.Filter ?? new(),
PaginationState = new PaginationState
{
PageNumber = 1,
PageSize = 1000
}
};
var result = await UserOrderContract.GetAllUserOrderByFilterAsync(exportRequest);
if (result?.Models == null || !result.Models.Any())
{
Snackbar.Add("داده‌ای برای خروجی وجود ندارد.", Severity.Info);
return;
}
var headers = new[]
{
"شناسه", "کاربر", "نام مشتری", "مبلغ", "وضعیت پرداخت", "وضعیت ارسال", "روش پرداخت", "تاریخ پرداخت"
};
var rows = result.Models.Select(o => new object?[]
{
o.Id,
o.UserId,
CsvExportHelper.CustomerName(o.UserFullName, userId: o.UserId),
o.Amount,
GetPaymentStatusText(o.PaymentStatus.GetHashCode()),
GetDeliveryStatusText(o.DeliveryStatus.GetHashCode()),
GetPaymentMethodText(o.PaymentMethod.GetHashCode()),
o.PaymentDate?.ToDateTime().ToLocalTime().MiladiToJalaliWithTime() ?? "-"
});
var filename = $"user-orders-{DateTime.Now:yyyyMMddHHmmss}.xls";
await JsRuntime.InvokeVoidAsync("jsSaveAsFile", filename,
CsvExportHelper.ToExcelXmlBase64("سفارش‌ها", headers, rows));
Snackbar.Add("خروجی Excel آماده شد.", Severity.Success);
}
catch (Exception ex)
{
Snackbar.Add($"خطا در خروجی Excel: {ex.Message}", Severity.Error);
}
}
}