Files
docs/ui-modernization/BACKOFFICE-STORE-UNIFICATION.md
T

9.5 KiB
Raw Blame History

🏪 یکسان‌سازی فروشگاه عادی و تخفیفی — BackOffice

تاریخ: ۱۴۰۴/۱۱/۲۴ (February 13, 2026)
وضعیت: کامل
Build: 0 Error


۱. هدف

فروشگاه عادی و فروشگاه تخفیفی در پنل مدیریت باید از نظر ظاهری و UX کاملاً یکسان باشند. قبل از این تغییرات، صفحات فروشگاه تخفیفی ظاهر و ساختار متفاوتی داشتند. هدف این فاز:

  1. NavMenu — جداسازی دو فروشگاه در گروه‌بندی‌های مجزا
  2. دسته‌بندی‌ها — ظاهر یکسان با فروشگاه عادی (ستون‌ها، درخت، اکشن‌ها)
  3. محصولات — ظاهر یکسان (گالری، فیلترها، ستون‌های گرید، اکسپورت)
  4. سفارشات — حذف گزارش‌های کوچک اضافی، فقط لیست خالص + رفع باگ لیست خالی

۲. خلاصه تغییرات

۲.۱ بازسازی NavMenu

قبل بعد
یک بخش «فروشگاه» با زیرگروه‌های محصولات + دسته‌بندی + سفارش + ویرایش دسته‌جمعی دو گروه مجزا: «فروشگاه عادی» و «فروشگاه تخفیفی»
ویرایش دسته‌جمعی در منو حذف شد از منو
انبارداری داخل فروشگاه انبارداری گروه مجزا
پکیج‌ها داخل فروشگاه پکیج‌ها آیتم مستقل

ساختار جدید:

فروشگاه (بخش)
├── پکیج‌ها (مستقل)
├── فروشگاه عادی (NavGroup)
│   ├── محصولات → /ProductsPage/
│   ├── دسته‌بندی‌ها → /CategoryPage/
│   └── سفارشات و گزارش → /OrdersPage/
├── انبارداری (NavGroup مستقل)
│   ├── موجودی انبار
│   ├── محصولات کم‌موجود
│   ├── مدیریت انبارها
│   └── تاریخچه تغییرات
└── فروشگاه تخفیفی (NavGroup)
    ├── محصولات → /discount-products
    ├── دسته‌بندی‌ها → /discount-categories
    └── سفارشات و گزارش → /discount-orders

فایل: Shared/NavMenu.razor


۲.۲ رفع لیست خالی سفارشات + حذف گزارش‌های کوچک

مشکل ۱ — لیست خالی:

  • PaymentDate.ToDateTime() بدون null check باعث exception در WASM می‌شد
  • Exception در Blazor WASM silent است و grid خالی نشان می‌دهد
  • رفع: اضافه کردن @if (context.Item.PaymentDate != null) با fallback "-"

مشکل ۲ — گزارش‌های اضافی:

  • کارت‌های آماری (تعداد سفارشات + مجموع مبلغ) و نمودار Bar وضعیت ارسال بالای گرید بودند
  • این آمار اضافی بود چون تب جداگانه «گزارش فروش» وجود دارد
  • رفع: حذف کامل MudGrid (کارت‌ها)، MudChart (نمودار)، فیلدهای _stats/_statusChartLabels/_statusChartSeries، متد UpdateStats()، کلاس OrderStatsViewModel
  • عنوان تولبار از «سفارش‌های کاربر» به «لیست سفارشات» تغییر کرد

فایل‌ها:

  • Pages/UserOrder/UserOrderMainPage.razor
  • Pages/UserOrder/UserOrderMainPage.razor.cs

۲.۳ بازنویسی صفحه محصولات تخفیفی

قبل: markup سفارشی بدون BasePageComponent، ستون‌های ساده، بدون image preview بعد: کاملاً مطابق با ProductsMainPage فروشگاه عادی

ویژگی قبل بعد
Wrapper markup دستی BasePageComponent
فیلترها جستجو + دسته‌بندی جستجو + دسته‌بندی + وضعیت + موجودی
ستون عنوان متن ساده تصویر inline (MudAvatar) + متن truncate + tooltip
ستون موجودی عدد ساده چیپ رنگی (قرمز/نارنجی/سبز)
ستون وضعیت متن چیپ Error/Success
خروجی Excel (داشت) (حفظ شد)
گالری تصاویر (داشت) (حفظ شد)
Server-side paging

فایل‌ها:

  • Pages/DiscountShop/DiscountProductsMainPage.razor — بازنویسی کامل
  • Pages/DiscountShop/DiscountProductsMainPage.razor.cs — بازنویسی کامل (code-behind)

۲.۴ بازنویسی صفحه دسته‌بندی‌های تخفیفی

قبل: markup دستی بدون BasePageComponent، ستون‌های متفاوت بعد: کاملاً مطابق با CategoryMainPage فروشگاه عادی

ویژگی قبل بعد
Wrapper markup دستی BasePageComponent
لایوت درخت + گرید درخت (3 col) + گرید (9 col) — بدون تغییر
ستون‌ها شناسه، عنوان، توضیحات، وضعیت شناسه، نام لاتین، عنوان، دسته‌بندی والد، تعداد محصولات، ترتیب، فعال؟
ستون والد نداشت resolve نام والد از لیست
ستون محصولات نداشت چیپ Info
ستون ترتیب نداشت PropertyColumn
فیلتر داخل page داخل BasePageComponent
حذف با فرزند disabled disabled (حفظ شد)

فایل‌ها:

  • Pages/DiscountShop/DiscountCategoriesMainPage.razor — بازنویسی کامل
  • Pages/DiscountShop/DiscountCategoriesMainPage.razor.cs — ایجاد (code-behind جدید)

۳. فایل‌های تغییر یافته

فایل نوع تغییر توضیح
Shared/NavMenu.razor ✏️ ویرایش بازسازی ساختار فروشگاه
Pages/UserOrder/UserOrderMainPage.razor ✏️ ویرایش حذف آمار، رفع PaymentDate
Pages/UserOrder/UserOrderMainPage.razor.cs ✏️ ویرایش حذف فیلدها/متدهای آمار
Pages/DiscountShop/DiscountProductsMainPage.razor 🔄 بازنویسی BasePageComponent + ستون‌های جدید
Pages/DiscountShop/DiscountProductsMainPage.razor.cs 🔄 بازنویسی code-behind کامل
Pages/DiscountShop/DiscountCategoriesMainPage.razor 🔄 بازنویسی BasePageComponent + ستون‌های جدید
Pages/DiscountShop/DiscountCategoriesMainPage.razor.cs 🆕 ایجاد code-behind جدید (از @code درون‌خطی)

۴. الگوی پیاده‌سازی — BasePageComponent

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

<BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit">
    <Filters>
        <!-- فیلدهای فیلتر در MudItem -->
    </Filters>
    <Content>
        <!-- MudDataGrid اصلی -->
    </Content>
</BasePageComponent>

در code-behind:

private BasePageComponent _basePage = default!;

private async Task OnFilterSubmit()
{
    _basePage.IsFiltered = true;
    // اعمال فیلتر
}

private async Task OnFilterCleared()
{
    _basePage.IsFiltered = false;
    // ریست فیلترها
}

۵. الگوی Code-Behind

به دلیل محدودیت Razor source generator در پروژه، همه فایل‌هایی که سرویس inject دارند باید code-behind داشته باشند:

Page.razor         → فقط markup (بدون @code)
Page.razor.cs      → partial class با [Inject] و منطق

نکته مهم: سرویس‌های global از _Imports.razor نباید دوباره با [Inject] تعریف شوند:

  • [Inject] public IDialogService DialogService { get; set; } — از قبل global
  • [Inject] public ISnackbar Snackbar { get; set; } — از قبل global
  • [Inject] public IJSRuntime jsRuntime { get; set; } — از قبل global (حرف کوچک!)
  • [Inject] public IDiscountProductService DiscountProductService { get; set; } — باید inject شود

۶. مقایسه نهایی فروشگاه عادی و تخفیفی

جنبه فروشگاه عادی فروشگاه تخفیفی وضعیت
ارتباط با بکند gRPC/Protobuf HTTP REST (IDiscountXxxService) تفاوت ذاتی
BasePageComponent 🟢 یکسان
فیلترهای محصول جستجو+دسته‌بندی+وضعیت جستجو+دسته‌بندی+وضعیت+موجودی 🟢 یکسان+
ستون‌های محصول تصویر+عنوان، قیمت، موجودی (چیپ)، وضعیت (چیپ) تصویر+عنوان، قیمت، تخفیف، موجودی (چیپ)، وضعیت (چیپ) 🟢 یکسان+
گالری تصاویر GalleryDialog ProductImageGallery 🟢 هر دو دارند
خروجی Excel 🟢 یکسان
درخت دسته‌بندی 🟢 یکسان
ستون‌های دسته‌بندی شناسه+نام+عنوان+والد+محصولات+ترتیب+فعال شناسه+نام+عنوان+والد+محصولات+ترتیب+فعال 🟢 یکسان
سفارشات Hub MudTabs (سفارشات + گزارش فروش) MudTabs (سفارشات + گزارش فروش) 🟢 یکسان