Files
docs/ui-modernization/BACKOFFICE-ARCHITECTURE.md
T

16 KiB
Raw Blame History

🏗️ BackOffice — مرجع معماری و الگوها

تاریخ: ۱۴۰۴/۱۱/۲۴ (February 13, 2026)
پروژه: BackOffice Admin Panel (Blazor WebAssembly)


۱. معماری کلی

┌─────────────────────────────────────────────────┐
│                  BackOffice                      │
│              (Blazor WebAssembly)                │
│  ┌──────────┐  ┌──────────┐  ┌──────────────┐  │
│  │ MudBlazor│  │ Mapster  │  │ DateTimeCvt  │  │
│  │   v8     │  │ (mapping)│  │ (تاریخ شمسی) │  │
│  └──────────┘  └──────────┘  └──────────────┘  │
│        │              │              │           │
│  ┌─────────────────────────────────────────┐    │
│  │         Pages / Components / Shared      │    │
│  │   BasePageComponent, Hub Pages, Dialogs  │    │
│  └─────────────────────────────────────────┘    │
│        │                                         │
│  ┌──────────────┐    ┌──────────────────┐       │
│  │ gRPC Clients │    │ HTTP REST Services│       │
│  │ (Protobuf)   │    │ (DiscountShop)   │       │
│  └──────┬───────┘    └────────┬─────────┘       │
└─────────┼──────────────────────┼─────────────────┘
          │                      │
          ▼                      ▼
┌──────────────────────────────────────────┐
│          CMS Microservice                 │
│       (ASP.NET Core + gRPC)              │
│  Domain → Application (CQRS) → Infra     │
└──────────────────────────────────────────┘

۲. Technology Stack

لایه تکنولوژی نسخه
Frontend Framework Blazor WebAssembly .NET 9
UI Library MudBlazor v8
Backend Communication (عادی) gRPC / Protobuf
Backend Communication (تخفیفی) HTTP REST
Object Mapping Mapster
تاریخ شمسی DateTimeConverterCL
Client State Blazored.LocalStorage
Auth JWT Role-based Administrator, Admin, Author
Permission IAuthorizationService.HasPermissionAsync 18 permission

۳. ساختار پوشه‌ها

BackOffice/src/BackOffice/
├── Common/
│   ├── BaseComponents/         ← کامپوننت‌های پایه (BasePageComponent, DateRangePicker, Image)
│   ├── Utilities/              ← RouteConstance, Extensions, Helpers
│   └── ...
├── Pages/
│   ├── Category/               ← دسته‌بندی فروشگاه عادی
│   ├── Products/               ← محصولات فروشگاه عادی
│   ├── UserOrder/              ← سفارشات + گزارش فروش (Hub)
│   ├── DiscountShop/           ← فروشگاه تخفیفی (محصولات + دسته‌بندی + سفارشات)
│   │   └── Components/         ← دیالوگ‌ها و کامپوننت‌های اختصاصی
│   ├── Inventory/              ← انبارداری (4 صفحه)
│   ├── Package/                ← پکیج‌ها
│   ├── Commission/             ← کمیسیون (5 صفحه)
│   ├── Network/                ← شبکه (4 صفحه)
│   ├── Club/                   ← باشگاه مشتریان (Hub: اعضا + آمار + فیچرها)
│   ├── Blog/                   ← بلاگ (Hub: پست + دسته‌بندی + تگ)
│   ├── Content/                ← صفحات سایت
│   ├── Wallet/                 ← کیف‌پول (تب‌ها: لیست + تاریخچه)
│   ├── Contract/               ← قراردادها
│   ├── SystemManagement/       ← سیستم (Hub: تنظیمات + Worker + Health)
│   └── ...
├── Services/
│   ├── DiscountProduct/        ← IDiscountProductService + implementation
│   ├── DiscountCategory/       ← IDiscountCategoryService + implementation
│   ├── DiscountOrder/          ← IDiscountOrderService + implementation
│   └── Authorization/          ← IAuthorizationService
├── Shared/
│   ├── MainLayout.razor        ← لایوت اصلی (AppBar + NavMenu + MudContainer)
│   ├── NavMenu.razor           ← منوی ناوبری
│   ├── GlobalSearch.razor      ← جستجوی سراسری
│   └── AppBreadcrumb.razor     ← Breadcrumb فارسی
└── wwwroot/
    ├── js/main.js              ← jsSaveAsFile (Excel export)
    └── appsettings.json        ← تنظیمات endpoints

۴. الگوهای اصلی

۴.۱ BasePageComponent — پترن صفحات لیست

هر صفحه لیست از BasePageComponent استفاده می‌کند:

┌──────────────────────────────────────┐
│ BasePageComponent                     │
│  ┌────────────────────────────────┐  │
│  │ 📋 Filter Panel (collapsible)  │  │
│  │  [فیلد ۱]  [فیلد ۲]  [فیلد ۳] │  │
│  │  [پاک کردن فیلتر] [جستجو]     │  │
│  └────────────────────────────────┘  │
│  ┌────────────────────────────────┐  │
│  │ 📊 Content (DataGrid)          │  │
│  │  ToolBar: [عنوان] [Excel] [+]  │  │
│  │  Columns: ...                   │  │
│  │  Pager: 20/50/100              │  │
│  └────────────────────────────────┘  │
└──────────────────────────────────────┘

فایل: Common/BaseComponents/BasePageComponent.razor

پراپرتی‌ها:

  • RenderFragment Filters — محتوای فیلتر
  • RenderFragment Content — محتوای اصلی
  • EventCallback OnSubmitClick — کلیک جستجو
  • EventCallback OnClearFilterClick — کلیک پاک کردن
  • bool IsFiltered — آیا فیلتر فعال است (نشان‌دهنده badge «فعال»)

۴.۲ Hub Pages — پترن ادغام صفحات

صفحات مرتبط در یک Hub با MudTabs ادغام می‌شوند:

Hub Route‌ها تب‌ها
OrdersHub /OrdersPage/, /OrdersSalesReportsPage/ سفارشات + گزارش فروش
DiscountShopHub /discount-shop, /discount-orders, /discount-sales-reports سفارشات + گزارش فروش
ClubHub /club, /club/members, /club/statistics اعضا + آمار
BlogHub /blog, /blog/posts, /blog/categories, /tags پست + دسته‌بندی + تگ
SystemHub /system, /system/configuration, /system/worker-control, /system/health تنظیمات + Worker + Health

۴.۳ Code-Behind — پترن جداسازی markup/logic

MyPage.razor       →  فقط HTML/Razor markup
MyPage.razor.cs    →  partial class + [Inject] + methods

قوانین:

  1. فایل‌هایی که سرویس inject دارند باید code-behind داشته باشند (محدودیت Razor source generator)
  2. سرویس‌های global (_Imports.razor) نباید دوباره [Inject] شوند
  3. namespace باید با مسیر فایل match کند

سرویس‌های Global (از _Imports.razor):

سرویس نام متغیر توضیح
IDialogService DialogService دیالوگ MudBlazor
ISnackbar Snackbar نوتیفیکیشن MudBlazor
IJSRuntime jsRuntime ⚠️ حرف کوچک j
NavigationManager Navigation ناوبری
ILocalStorageService LocalStorageService ذخیره محلی
AuthenticationStateProvider AuthenticationStateProvider احراز هویت

۴.۴ Excel Export — پترن خروجی CSV

private async Task ExportToExcel()
{
    var sb = new StringBuilder();
    sb.AppendLine("ستون ۱,ستون ۲,ستون ۳");  // هدر فارسی
    foreach (var item in items)
    {
        sb.AppendLine($"{EscapeCsv(item.Col1)},{item.Col2},{item.Col3}");
    }
    var bytes = Encoding.UTF8.GetPreamble()  // UTF-8 BOM
        .Concat(Encoding.UTF8.GetBytes(sb.ToString())).ToArray();
    var base64 = Convert.ToBase64String(bytes);
    await jsRuntime.InvokeVoidAsync("jsSaveAsFile", "filename.csv", base64);
}

private string EscapeCsv(string? value)
{
    if (string.IsNullOrEmpty(value)) return "";
    if (value.Contains(',') || value.Contains('"') || value.Contains('\n'))
        return $"\"{value.Replace("\"", "\"\"")}\"";
    return value;
}

صفحات دارای Excel: Products, UserOrders, ClubMembers, WithdrawalRequests, WeeklyReports, StockMovements, Users, DiscountOrders, ManualPayments, Inventory, DiscountProducts


۴.۵ Server-Side DataGrid — پترن بارگذاری صفحه‌ای

<MudDataGrid T="MyDto"
             ServerData="LoadServerData"
             Height="calc(100vh - 240px)"
             FixedHeader="true"
             Hover="true" Dense="true">
private async Task<GridData<MyDto>> LoadServerData(GridState<MyDto> state)
{
    var filter = new MyFilter
    {
        PageNumber = state.Page + 1,  // MudDataGrid is 0-based
        PageSize = state.PageSize
    };
    var (items, totalCount, _) = await MyService.GetAsync(filter);
    return new GridData<MyDto> { Items = items, TotalItems = totalCount };
}

۴.۶ Permission System

NavMenu از IAuthorizationService.HasPermissionAsync() برای نمایش/مخفی کردن آیتم‌ها استفاده می‌کند:

Permission صفحه(ها)
dashboard.view داشبورد
packages.manage پکیج‌ها
products.manage محصولات + دسته‌بندی + ویرایش دسته‌جمعی
orders.view سفارشات
inventory.manage انبارداری (4 صفحه)
discountshop.manage فروشگاه تخفیفی
users.view کاربران
roles.manage نقش‌ها
manualpayments.create پرداخت دستی
blog.manage بلاگ
sitepages.manage صفحات سایت
publicmessages.view پیام‌های عمومی
settings.manage_configuration تنظیمات سیستم

۵. مسیرهای (Routing)

مسیرهای ثابت (RouteConstance.cs)

/                          → Dashboard
/PackagePage/              → Packages
/ProductsPage/             → Products
/CategoryPage/             → Categories
/OrdersPage/               → Orders Hub
/OrdersSalesReportsPage/   → Orders Sales Reports
/InventoryPage/            → Inventory
/InventoryLowStockPage/    → Low Stock
/InventoryWarehousesPage/  → Warehouses
/InventoryMovementsPage/   → Stock Movements
/UserPage/                 → Users
/RolePage/                 → Roles
/ProductsBulkEditPage/     → Bulk Edit
/ProductCategoriesPage/    → Product-Category DragDrop
/CategoryProductsPage/     → Category-Product DragDrop

مسیرهای hardcode (فروشگاه تخفیفی + سایر)

/discount-products         → Discount Products
/discount-categories       → Discount Categories
/discount-shop             → Discount Orders Hub
/discount-orders           → Discount Orders
/discount-sales-reports    → Discount Sales Reports
/commission/*              → Commission pages
/network/*                 → Network pages
/club/*                    → Club pages
/blog/*                    → Blog pages
/wallets                   → Wallets
/contracts                 → Contracts
/payment/manual-payments   → Manual Payments
/system/*                  → System pages
/settings                  → Settings
/content/pages             → Content Pages
/public-messages           → Public Messages

۶. ارتباط فروشگاه عادی vs تخفیفی

جنبه فروشگاه عادی فروشگاه تخفیفی
سرویس محصولات gRPC ProductsContractClient HTTP IDiscountProductService
سرویس دسته‌بندی gRPC CategoryContractClient HTTP IDiscountCategoryService
سرویس سفارشات gRPC UserOrderContractClient HTTP IDiscountOrderService
Entity بکند Product DiscountProduct
پرداخت فقط درگاه ترکیبی (کیف تخفیفی + درگاه)
فیلد اختصاصی MaxDiscountPercent
UI Pattern BasePageComponent BasePageComponent (یکسان)
ستون‌ها یکسان یکسان + ستون تخفیف

۷. نقشه NavMenu

داشبورد
─────────────────────
کمیسیون و شبکه
├── کمیسیون (NavGroup)
│   ├── داشبورد کمیسیون
│   ├── گزارش‌های هفتگی
│   ├── پرداخت کاربران
│   ├── درخواست‌های برداشت [Badge]
│   └── گزارش برداشت‌ها
├── شبکه (NavGroup)
│   ├── درخت شبکه
│   ├── گزارش موجودی‌ها
│   └── آمار شبکه
└── باشگاه مشتریان (NavGroup)
    ├── اعضا و آمار
    └── فیچرهای باشگاه
─────────────────────
فروشگاه [AuthorizeView: Administrator]
├── پکیج‌ها
├── فروشگاه عادی (NavGroup)
│   ├── محصولات
│   ├── دسته‌بندی‌ها
│   └── سفارشات و گزارش
├── انبارداری (NavGroup)
│   ├── موجودی انبار
│   ├── محصولات کم‌موجود
│   ├── مدیریت انبارها
│   └── تاریخچه تغییرات
└── فروشگاه تخفیفی (NavGroup)
    ├── محصولات
    ├── دسته‌بندی‌ها
    └── سفارشات و گزارش
─────────────────────
مدیریت [AuthorizeView: Administrator]
├── کاربران
├── نقش‌ها
├── پرداخت دستی
├── کیف‌پول
└── قراردادها
─────────────────────
مدیریت محتوا
├── بلاگ
├── صفحات سایت
└── پیام‌های عمومی
─────────────────────
سیستم [AuthorizeView: Administrator]
├── مدیریت سیستم
└── نسخه اپلیکیشن‌ها
─────────────────────
تنظیمات