28 KiB
یکسانسازی فروشگاه عادی و فروشگاه تخفیفی (BackOffice)
تاریخ: ۱۳۹۴/۱۱/۲۴ (2026-02-13)
وضعیت: ✅ فاز ۱ تا ۶ — تکمیل شده (CMS + BackOffice Build Succeeded — 0 Error)
هدف
هر دو فروشگاه (عادی و تخفیفی) از نظر UI/UX، ساختار صفحات، اکشنها و قابلیتها عینبهعین یکسان باشند.
تنها تفاوت مجاز: منطق پرداخت — فروشگاه تخفیفی از کیفپول تخفیفی + درگاه، فروشگاه عادی فقط از کیفپول عادی.
معیار یکسانسازی
- مبنا: فروشگاه عادی (Products, Category, UserOrder)
- استثنا: مزایای بدیهی فروشگاه تخفیفی به فروشگاه عادی هم اضافه شد
- Bulk Operations: بیخیال شد (طبق درخواست کاربر)
تفاوتهای زیرساختی (تغییر نکرده — بیتأثیر روی UX)
| موضوع | فروشگاه عادی | فروشگاه تخفیفی |
|---|---|---|
| ارتباط با سرور | gRPC مستقیم (ProductsContractClient) |
سرویس اینترفیس (IDiscountProductService) که داخلاً gRPC صدا میزنه |
| مدل داده | Protobuf models | C# DTOs |
نکته: هر دو در نهایت از همان gRPC backend استفاده میکنند. تفاوت فقط در لایه abstraction است و تأثیری روی UX ندارد.
تغییرات انجامشده
۱. صفحه محصولات (DiscountProductsMainPage)
| تغییر | قبل | بعد |
|---|---|---|
| نمایش تصویر | MudAvatar |
کامپوننت Image (مطابق فروشگاه عادی) |
| برش عنوان | Substring(0, 20) + "…" |
Truncate(20, true) (extension method مشترک) |
| گالری تصاویر | ProductFormDialog (کلاینتساید) |
GalleryDialog سرور-محور (مطابق فروشگاه عادی) |
| پیشنمایش تصویر | HTML inline در ShowMessageBox |
ImagePreviewDialog (مطابق فروشگاه عادی) |
| عنوان تولبار | «مدیریت محصولات تخفیفی» | «مدیریت محصولات» |
اکشنهای جدید اضافهشده:
- ✅ دکمه «مدیریت دستهبندی (درگ و دراپ)» → ناوبری به
ProductCategoriesDragDropPage
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountProductsMainPage.razorPages/DiscountShop/DiscountProductsMainPage.razor.cs
۲. صفحه دستهبندیها (DiscountCategoriesMainPage)
اکشنهای جدید اضافهشده:
- ✅ دکمه «مدیریت محصولات این دسته (درگ و دراپ)» → ناوبری به
CategoryProductsDragDropPage
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountCategoriesMainPage.razorPages/DiscountShop/DiscountCategoriesMainPage.razor.cs
۳. صفحه سفارشات (DiscountOrdersMainPage) — بازنویسی کامل
| تغییر | قبل | بعد |
|---|---|---|
| الگوی فیلتر | فیلترهای inline با دکمه جستجو | BasePageComponent با OnSubmit/OnClear (مطابق فروشگاه عادی) |
| لایهبندی | MudPaper تو در تو |
BasePageComponent > Filters + Content |
| اکشنها | فقط مشاهده جزئیات + تغییر وضعیت | جزئیات + تغییر وضعیت + حذف (مطابق فروشگاه عادی) |
| آیکونهای اکشن | Visibility + Edit |
Info + LocalShipping + DeleteOutline (مطابق فروشگاه عادی) |
| ساختار تولبار | بدون تولبار | تولبار با عنوان + دکمه Excel (مطابق فروشگاه عادی) |
ستونها (حفظ شده — خاص فروشگاه تخفیفی):
- شماره سفارش، تاریخ ثبت، مبلغ کل، تخفیف کیفپول، پرداخت درگاه، تعداد آیتم، وضعیت، پرداخت
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountOrdersMainPage.razor← بازنویسی کاملPages/DiscountShop/DiscountOrdersMainPage.razor.cs← بازنویسی کامل
۴. گزارش فروش (SalesReports)
| تغییر | قبل | بعد |
|---|---|---|
| نمودارها | روند فروش + محصولات پرفروش | روند فروش + محصولات پرفروش + وضعیت سفارشها |
| عنوان | «گزارش فروش فروشگاه تخفیفی» | «گزارش فروش فروشگاه» |
| توضیح | «آمار فروش، تخفیف و وضعیت سفارشهای فروشگاه تخفیفی...» | «آمار فروش و وضعیت سفارشها بر اساس بازه تاریخ و وضعیت سفارش» |
نمودار جدید:
- ✅ «وضعیت سفارشها» — نمودار میلهای تعداد سفارش بر اساس وضعیت (مطابق فروشگاه عادی)
فایلهای تغییر یافته:
Pages/DiscountShop/SalesReports.razor
۵. هاب سفارشات (DiscountShopHub)
| تغییر | قبل | بعد |
|---|---|---|
| عنوان | «فروشگاه تخفیفی» | «سفارشات فروشگاه تخفیفی» |
| آیکون تب سفارشات | ShoppingCart |
ReceiptLong (مطابق OrdersHub فروشگاه عادی) |
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountShopHub.razor
۶. تغییرات فروشگاه عادی (مزایای تخفیفی ← عادی)
CategoryMainPage
- ✅ ستون «ترتیب» (
SortOrder) اضافه شد (از تخفیفی) - ✅ غیرفعالسازی حذف دستهبندی دارای زیردسته (از تخفیفی)
فایلهای تغییر یافته:
Pages/Category/CategoryMainPage.razorPages/Category/CategoryMainPage.razor.cs
تغییرات فاز ۲ — ارتقاء به Admin RPC و فیلدهای پیشرفته
۷. سرویس سفارشات تخفیفی — سوئیچ به Admin RPC
| تغییر | قبل | بعد |
|---|---|---|
| RPC مورد استفاده | GetUserOrders (user-scoped) |
GetAllDiscountOrders (admin-scoped) |
| DTO | OrderSummaryDto (محدود) |
AdminOrderDto (کامل با user_full_name, user_mobile, shipping_address, payment_date, vat_amount...) |
| فیلترها | فقط userId, paymentCompleted, deliveryStatus | userId, paymentStatus, deliveryStatus, userMobile, trackingCode, fromDate, toDate, minAmount, maxAmount |
| گزارش فروش | محاسبه کلاینتساید + N+1 (۵۰ فراخوان gRPC جداگانه!) | GetDiscountSalesReport RPC سرور-ساید با fallback |
فایلهای تغییر یافته:
Services/DiscountOrder/IDiscountOrderService.cs← فیلترهای جدید + DTOهای گزارش فروشServices/DiscountOrder/DiscountOrderService.cs← سوئیچ بهGetAllDiscountOrdersAsync+GetDiscountSalesReportAsync
۸. ستونها و فیلترهای ادمین در سفارشات تخفیفی
ستونهای جدید اضافهشده:
- ✅ نام کاربر (لینک به پروفایل — مطابق فروشگاه عادی)
- ✅ موبایل کاربر
- ✅ وضعیت پرداخت (Pending/Completed/Failed/Refunded — مطابق فروشگاه عادی)
- ✅ تاریخ پرداخت
- ✅ آدرس (truncated با tooltip — مطابق فروشگاه عادی)
- ✅ وضعیت ارسال (جدا از وضعیت پرداخت — مطابق فروشگاه عادی)
فیلترهای جدید اضافهشده:
- ✅ شناسه سفارش
- ✅ جستجوی کاربر (UserAutoComplete)
- ✅ موبایل کاربر
- ✅ کد رهگیری
- ✅ از تاریخ / تا تاریخ
- ✅ وضعیت پرداخت (Pending/Completed/Failed/Refunded)
- ✅ وضعیت ارسال
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountOrdersMainPage.razor← ستونها + فیلترهاPages/DiscountShop/DiscountOrdersMainPage.razor.cs← فیلدها + متدهای وضعیت پرداخت
۹. گزارش فروش تخفیفی — حذف مشکل N+1
| تغییر | قبل | بعد |
|---|---|---|
| محصولات پرفروش | ۵۰ فراخوان gRPC جداگانه (GetByIdAsync × 50) |
یک فراخوان GetDiscountSalesReport |
| خلاصه آماری | محاسبه کلاینتساید | سرور-ساید (دقیقتر + سریعتر) |
| نمودار روند | GroupBy کلاینتساید | SalesPeriodDto از سرور |
| جدول سفارشها | فقط شماره سفارش | شناسه + نام کاربر (لینک) |
| خروجی Excel/PDF | فقط OrderNumber | شناسه + نام کاربر + موبایل |
فایلهای تغییر یافته:
Pages/DiscountShop/SalesReports.razor
۱۰. دستهبندی فروشگاه عادی — فیلد ImagePath
- ✅ فیلد
ImagePathبه دیالوگ ایجاد/ویرایش دستهبندی اضافه شد (مطابق فروشگاه تخفیفی)
فایلهای تغییر یافته:
Pages/Category/Components/CreateOrUpdateCategoryDialog.razorPages/Category/Components/CreateOrUpdateCategoryDialog.razor.cs
۱۱. گزارش فروش عادی — نمودار محصولات پرفروش + خروجی PDF
- ✅ نمودار «محصولات پرفروش (بر اساس مبلغ)» از FactorDetails سفارشات
- ✅ دکمه خروجی PDF (نسخه متنی) — مطابق فروشگاه تخفیفی
فایلهای تغییر یافته:
Pages/UserOrder/OrderSalesReports.razorPages/UserOrder/OrderSalesReports.razor.cs
تغییرات فاز ۳ — تگهای محصول و نهاییسازی
۱۲. تگهای محصول در فروشگاه تخفیفی
- ✅ دکمه «تگهای محصول» (
Labelicon) به ستون عملیات صفحه محصولات تخفیفی اضافه شد - ✅ از همان
AssignTagsDialogفروشگاه عادی استفاده شد (کامپوننت مشترک) - ✅ سرویس
ProductTagContractمشترک بین هر دو فروشگاه — بدون نیاز به API جدید
نکته:
ProductTagContractیک سرویس ژنریکproduct_id ↔ tag_idاست و محدود به فروشگاه خاصی نیست.
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountProductsMainPage.razor← دکمه تگPages/DiscountShop/DiscountProductsMainPage.razor.cs← متدOpenTagAssignment+ using
تغییرات فاز ۴ — یکسانسازی دیالوگها و جزئیات تکمیلی
۱۳. دیالوگ جزئیات سفارش تخفیفی — Timeline + ویرایش Inline
| تغییر | قبل | بعد |
|---|---|---|
| Timeline وضعیت | ❌ فاقد | ✅ ۵ مرحله (ثبت → پرداخت → آمادهسازی → ارسال → تحویل/مرجوعی) |
| ویرایش وضعیت | ❌ فقط خواندنی | ✅ درونخطی (وضعیت + کد رهگیری + یادداشت ادمین) |
| دکمه ذخیره | ❌ فقط «بستن» | ✅ «ثبت تغییرات» + اسپینر بارگذاری |
| هشدارهای شرطی | ❌ فاقد | ✅ هشدار لغو/مرجوعی + اطلاعرسانی ارسال |
| Code-behind | @code درونخطی |
فایل جداگانه .razor.cs |
فایلهای تغییر یافته:
Pages/DiscountShop/Components/OrderDetailsDialog.razor← Timeline + ویرایش inlinePages/DiscountShop/Components/OrderDetailsDialog.razor.cs← فایل جدید — timeline + save logic
۱۴. دیالوگ تغییر وضعیت فروشگاه عادی — ارتقاء
| تغییر | قبل | بعد |
|---|---|---|
| فرم | MudStack ساده |
MudForm با validation |
| فیلدها | فقط وضعیت | ✅ وضعیت + کد رهگیری + توضیحات ارسال |
| هشدارهای شرطی | ❌ فاقد | ✅ هشدار مرجوعی + اطلاعرسانی ارسال |
| دکمه | رنگ ثابت Primary |
✅ رنگ داینامیک بر اساس وضعیت + اسپینر |
| عنوان | بدون آیکون | ✅ آیکون Edit + عنوان |
| RPC | فقط UpdateOrderStatusAsync |
✅ UpdateOrderStatusAsync + UpdateUserOrderAsync (کد رهگیری + توضیحات) |
فایلهای تغییر یافته:
Pages/UserOrder/Components/ChangeOrderStatusDialog.razorPages/UserOrder/Components/ChangeOrderStatusDialog.razor.cs
۱۵. گزارش فروش تخفیفی — Empty chart guard + ترتیب نمودارها
| تغییر | قبل | بعد |
|---|---|---|
| نمودار روند فروش | بدون بررسی خالی بودن | ✅ نمایش «داده کافی برای نمایش نمودار وجود ندارد» |
| ترتیب نمودارها | روند → پرفروش → وضعیت | ✅ روند → وضعیت → پرفروش (مطابق فروشگاه عادی) |
فایلهای تغییر یافته:
Pages/DiscountShop/SalesReports.razor
۱۶. گزارش فروش عادی — لینک نام کاربر
- ✅ نام کاربر در جدول سفارشها از متن ساده به
MudLinkتبدیل شد (لینک به پروفایل کاربر)
فایلهای تغییر یافته:
Pages/UserOrder/OrderSalesReports.razor
۱۷. دیالوگ دستهبندی فروشگاه عادی — MudForm + UX
| تغییر | قبل | بعد |
|---|---|---|
| اعتبارسنجی | ❌ بدون validation | ✅ MudForm با Required + RequiredError |
| فیلد فعال | MudCheckBox |
✅ MudSwitch رنگی (مطابق فروشگاه تخفیفی) |
| Helper text | ❌ فاقد | ✅ «عدد کمتر = اولویت بالاتر» + «برای دسته اصلی خالی بگذارید» |
| دکمه ذخیره | همیشه «ثبت» | ✅ «ذخیره تغییرات» / «ایجاد دستهبندی» (داینامیک) |
| اسپینر بارگذاری | ❌ فاقد | ✅ MudProgressCircular + غیرفعالسازی دکمه |
| عنوان | بدون آیکون | ✅ آیکون Edit/Add + عنوان داینامیک |
| غیرفعالسازی دکمه | ❌ فاقد | ✅ غیرفعال تا validation سبز نشود |
فایلهای تغییر یافته:
Pages/Category/CreateOrUpdateCategoryDialog.razorPages/Category/CreateOrUpdateCategoryDialog.razor.cs
۱۸. سفارشات تخفیفی — لغو سفارش واقعی
| تغییر | قبل | بعد |
|---|---|---|
| دکمه «حذف» | آیکون DeleteOutline — فقط snackbar (بدون API) |
✅ آیکون Cancel — فراخوان UpdateStatusAsync با Cancelled |
| متن تأییدیه | «آیا از حذف مطمئن هستید؟» | «آیا از لغو سفارش مطمئن هستید؟ وضعیت به لغو شده تغییر میکند» |
| عملکرد | ❌ هیچ | ✅ واقعی — UpdateStatusAsync(Cancelled) |
فایلهای تغییر یافته:
Pages/DiscountShop/DiscountOrdersMainPage.razor← آیکون + tooltipPages/DiscountShop/DiscountOrdersMainPage.razor.cs← فراخوان API
تغییرات فاز ۵ — فرمتبندی قیمت، زیردسته و برچسب فیلدها
۵.۱ فرمتبندی قیمت در لیست محصولات عادی
مشکل: ستون قیمت عدد خام بدون separator و بدون واحد نشان میداد.
راهحل: تبدیل PropertyColumn به TemplateColumn با Price.ToString("N0") ریال — مطابق فروشگاه تخفیفی.
فایل تغییر یافته:
Pages/Products/ProductsMainPage.razor← TemplateColumn + فرمت N0 + ریال
۵.۲ دکمه «افزودن زیردسته» در دستهبندیهای عادی
مشکل: فروشگاه تخفیفی دکمه «افزودن زیردسته» در ستون عملیات داشت ولی فروشگاه عادی نداشت.
راهحل: افزودن MudIconButton با آیکون CreateNewFolder + رنگ Color.Primary + متد CreateSubcategory(parent) که دیالوگ را با ParentId = parent.Id باز میکند.
فایلهای تغییر یافته:
Pages/Category/CategoryMainPage.razor← دکمه جدید در ستون عملیاتPages/Category/CategoryMainPage.razor.cs← متدCreateSubcategory
۵.۳ برچسب واحد ریال در دیالوگهای محصول
مشکل: فیلد قیمت در دیالوگهای ایجاد/ویرایش محصول عادی Label="قیمت" داشت — بدون واحد.
راهحل: تغییر به Label="قیمت (ریال)" — مطابق فروشگاه تخفیفی.
فایلهای تغییر یافته:
Pages/Products/Components/CreateDialog.razor← قیمت (ریال)Pages/Products/Components/UpdateDialog.razor← قیمت (ریال)
تغییرات فاز ۶ — تغییرات بکند (Proto + Handler + gRPC Service)
این فاز تمام موارد "محدودیت API" که در فازهای قبلی شناسایی شده بودند را حل میکند.
۶.۱ ستون وضعیت فعال/غیرفعال محصولات (is_active)
مشکل: پروتوباف GetAllProductsByFilterResponseModel فیلد is_active نداشت. محصولات عادی ستون وضعیت نداشتند.
راهحل (end-to-end):
- Proto: افزودن
bool is_active = 15بهGetAllProductsByFilterResponseModel+google.protobuf.BoolValue is_active = 15بهGetAllProductsByFilterFilter - DTO: افزودن
bool IsActiveبهCustomerProductModel - Query: افزودن
bool? IsActiveبهGetCustomerProductsByFilterQuery - Handler: فیلتر
IsDeleted != IsActive+ مپIsActive = !p.IsDeleted - gRPC Service: مپ
IsActiveدر فیلتر و ریسپانسProductsService - Frontend: ستون
TemplateColumnباMudChipرنگی درProductsMainPage.razor
فایلهای تغییر یافته:
CMS/.../Protos/products.protoCMS/.../GetCustomerProductsByFilterResponseDto.csCMS/.../GetCustomerProductsByFilterQuery.csCMS/.../GetCustomerProductsByFilterQueryHandler.csCMS/.../Services/ProductsService.csBackOffice/.../Pages/Products/ProductsMainPage.razor
۶.۲ ستون تعداد محصولات دستهبندی (product_count)
مشکل: پروتوباف GetAllCategoryByFilterResponseModel فیلد product_count نداشت.
راهحل (end-to-end):
- Proto: افزودن
int32 product_count = 9بهGetAllCategoryByFilterResponseModel - DTO: افزودن
int ProductCountبهGetAllCategoryByFilterResponseModel(C#) - Handler: تغییر از
ProjectToType<>()(Mapster auto-map) به manualSelect()باProductCount = x.ProductCategories.Count - gRPC Service: auto-map Mapster (نام یکسان)
- Frontend: ستون
PropertyColumnجدید درCategoryMainPage.razor
فایلهای تغییر یافته:
CMS/.../Protos/category.protoCMS/.../GetAllCategoryByFilterResponseDto.csCMS/.../GetAllCategoryByFilterQueryHandler.csBackOffice/.../Pages/Category/CategoryMainPage.razor
۶.۳ فیلتر بازه تاریخ سفارشات (from_date / to_date)
مشکل: پروتوباف GetAllUserOrderByFilterFilter فقط یک payment_date داشت. امکان فیلتر بازه تاریخ وجود نداشت.
راهحل (end-to-end):
- Proto: افزودن
google.protobuf.Timestamp from_date = 11وgoogle.protobuf.Timestamp to_date = 12به فیلتر - gRPC Service: مپ
FromDateازfrom_date(با fallback بهpayment_date)،ToDateازto_date - Handler: بدون تغییر — از قبل
FromDate/ToDateرا ساپورت میکرد - Frontend: افزودن
MudDatePickerدوم (تا تاریخ)، مپ بهFilter.FromDate/Filter.ToDate
فایلهای تغییر یافته:
CMS/.../Protos/userorder.protoCMS/.../Services/UserOrderService.csBackOffice/.../Pages/UserOrder/UserOrderMainPage.razorBackOffice/.../Pages/UserOrder/UserOrderMainPage.razor.cs
۶.۴ تصویر محصول در آیتمهای سفارش تخفیفی (image_path)
مشکل: OrderItemDto در proto و C# فیلد image_path نداشت. آیتمهای سفارش بدون تصویر بودند.
راهحل (end-to-end):
- Proto: افزودن
string image_path = 9وstring thumbnail_path = 10بهOrderItemDtoدرdiscountorder.proto - Backend DTO: افزودن
ImagePath/ThumbnailPathبهOrderItemDto(C# Application layer) - Handler: مپ
ImagePath = od.Product.ImagePathدرGetOrderByIdQueryHandler(Product nav property از قبل Include شده بود) - Frontend DTO: افزودن فیلدها به
IDiscountOrderService.OrderItemDto - Frontend Service: مپ در
DiscountOrderService - Frontend Dialog:
MudImage+MudStackبرای نمایش تصویر کنار نام محصول
فایلهای تغییر یافته:
CMS/.../Protos/discountorder.protoCMS/.../GetOrderByIdQuery.cs(OrderItemDto)CMS/.../GetOrderByIdQueryHandler.csBackOffice/.../Services/DiscountOrder/IDiscountOrderService.csBackOffice/.../Services/DiscountOrder/DiscountOrderService.csBackOffice/.../Pages/DiscountShop/Components/OrderDetailsDialog.razor
وضعیت مقایسهای نهایی
محصولات
| قابلیت | عادی | تخفیفی |
|---|---|---|
| لیست با MudDataGrid + server-side | ✅ | ✅ |
| فیلتر با BasePageComponent | ✅ | ✅ |
| نمایش تصویر (Image component) | ✅ | ✅ |
| برش عنوان (Truncate) | ✅ | ✅ |
| ایجاد/ویرایش/حذف | ✅ | ✅ |
| گالری تصاویر (GalleryDialog سرور-محور) | ✅ | ✅ |
| پیشنمایش تصویر (ImagePreviewDialog) | ✅ | ✅ |
| مدیریت دستهبندی (درگ و دراپ) | ✅ | ✅ |
| خروجی Excel | ✅ | ✅ |
| تگهای محصول (AssignTagsDialog مشترک) | ✅ | ✅ |
| فرمت قیمت (N0 + ریال) | ✅ | ✅ |
| ستون وضعیت فعال/غیرفعال | ✅ | ✅ |
| Bulk Edit/Delete/Toggle | ✅ | ❌ (طبق درخواست — بیخیال) |
دستهبندیها
| قابلیت | عادی | تخفیفی |
|---|---|---|
| درخت سایدبار | ✅ | ✅ |
| گرید با MudDataGrid | ✅ | ✅ |
| ستونها: شناسه، نام لاتین، عنوان، والد، ترتیب، فعال | ✅ | ✅ |
| ستون تعداد محصولات | ✅ | ✅ |
| ایجاد/ویرایش/حذف | ✅ | ✅ |
| غیرفعالسازی حذف دارای زیردسته | ✅ | ✅ |
| افزودن زیردسته | ✅ | ✅ |
| درگاندراپ محصولات دسته | ✅ | ✅ |
سفارشات
| قابلیت | عادی | تخفیفی |
|---|---|---|
| BasePageComponent با فیلتر | ✅ | ✅ |
| MudDataGrid + تولبار | ✅ | ✅ |
| فیلتر شناسه / کاربر / تاریخ / وضعیت | ✅ | ✅ |
| فیلتر بازه تاریخ (از تاریخ + تا تاریخ) | ✅ | ✅ |
| ستون نام کاربر (لینک به پروفایل) | ✅ | ✅ |
| ستون وضعیت پرداخت (Chip رنگی) | ✅ | ✅ |
| ستون وضعیت ارسال (Chip رنگی) | ✅ | ✅ |
| ستون تاریخ پرداخت | ✅ | ✅ |
| ستون آدرس (truncated + tooltip) | ✅ | ✅ |
| جزئیات سفارش (Timeline + ویرایش inline) | ✅ | ✅ |
| تصویر محصول در آیتمهای سفارش | ✅ | ✅ |
| تغییر وضعیت (MudForm + کد رهگیری + هشدار) | ✅ | ✅ |
| لغو سفارش | ✅ | ✅ (via UpdateStatus) |
| خروجی Excel | ✅ | ✅ |
| ستونهای مالی تخفیف (DiscountBalanceUsed/GatewayAmount) | ❌ (مربوط نیست) | ✅ |
| اعمال تخفیف | ✅ | ❌ (API ندارد) |
گزارش فروش
| قابلیت | عادی | تخفیفی |
|---|---|---|
| فیلتر تاریخ + وضعیت | ✅ | ✅ |
| کارتهای خلاصه | ✅ | ✅ |
| نمودار روند فروش | ✅ | ✅ |
| نمودار وضعیت سفارشها | ✅ | ✅ |
| نمودار محصولات پرفروش | ✅ | ✅ |
| خروجی Excel | ✅ | ✅ |
| خروجی PDF | ✅ | ✅ |
موارد باقیمانده
این موارد نیاز به تغییرات بیشتر دارند:
| مورد | جزئیات | وضعیت |
|---|---|---|
| اعمال تخفیف سفارش تخفیفی | discountorder.proto فاقد ApplyDiscountToOrder RPC |
نیاز به RPC جدید + لاجیک سرور |
| لغو سفارش با بازپرداخت | لغو وضعیت ✅ ولی refund/بازگشت موجودی نیاز به RPC اختصاصی | نیاز به CancelOrder RPC |
نکته: موارد قبلی (is_active، product_count، from_date/to_date، image_path) در فاز ۶ حل شدند.
ساختار فایلهای تغییریافته
CMS/src/
├── CMSMicroservice.Protobuf/Protos/
│ ├── products.proto ← is_active (filter + response field 15)
│ ├── category.proto ← product_count (response field 9)
│ ├── userorder.proto ← from_date/to_date (filter fields 11,12)
│ └── discountorder.proto ← image_path/thumbnail_path (OrderItemDto fields 9,10)
├── CMSMicroservice.Application/
│ ├── ProductsCQ/Queries/GetCustomerProductsByFilter/
│ │ ├── GetCustomerProductsByFilterQuery.cs ← IsActive filter
│ │ ├── GetCustomerProductsByFilterQueryHandler.cs ← IsActive filter + mapping
│ │ └── GetCustomerProductsByFilterResponseDto.cs ← IsActive field
│ ├── CategoryCQ/Queries/GetAllCategoryByFilter/
│ │ ├── GetAllCategoryByFilterQueryHandler.cs ← manual Select + ProductCount
│ │ └── GetAllCategoryByFilterResponseDto.cs ← ProductCount field
│ └── DiscountShopCQ/Queries/GetOrderById/
│ ├── GetOrderByIdQuery.cs ← ImagePath/ThumbnailPath
│ └── GetOrderByIdQueryHandler.cs ← Product image mapping
└── CMSMicroservice.WebApi/Services/
├── ProductsService.cs ← IsActive filter + response mapping
└── UserOrderService.cs ← FromDate/ToDate mapping
BackOffice/src/BackOffice/
├── Services/DiscountOrder/
│ ├── IDiscountOrderService.cs ← OrderItemDto + ImagePath/ThumbnailPath
│ └── DiscountOrderService.cs ← image mapping
├── Pages/
│ ├── Category/
│ │ ├── CategoryMainPage.razor ← ستون ProductCount + SortOrder + زیردسته
│ │ ├── CategoryMainPage.razor.cs ← HasChildren + CreateSubcategory
│ │ ├── CreateOrUpdateCategoryDialog.razor ← MudForm + ImagePath
│ │ └── CreateOrUpdateCategoryDialog.razor.cs ← validation + loading
│ ├── DiscountShop/
│ │ ├── DiscountShopHub.razor
│ │ ├── DiscountProductsMainPage.razor/.cs
│ │ ├── DiscountCategoriesMainPage.razor/.cs
│ │ ├── DiscountOrdersMainPage.razor/.cs
│ │ ├── SalesReports.razor
│ │ └── Components/
│ │ ├── OrderDetailsDialog.razor ← تصویر محصول + Timeline
│ │ └── OrderDetailsDialog.razor.cs
│ ├── UserOrder/
│ │ ├── UserOrderMainPage.razor ← فیلتر بازه تاریخ (از + تا)
│ │ ├── UserOrderMainPage.razor.cs ← FromDate/ToDate mapping
│ │ ├── OrderSalesReports.razor/.cs
│ │ └── Components/ChangeOrderStatusDialog.razor/.cs
│ └── Products/
│ ├── ProductsMainPage.razor ← ستون IsActive + فرمت قیمت
│ └── Components/
│ ├── CreateDialog.razor ← قیمت (ریال)
│ └── UpdateDialog.razor ← قیمت (ریال)