16 KiB
🛒 Discount Shop - Implementation Plan
تاریخ ایجاد: ۱۰ دی ۱۴۰۴ (30 December 2025)
وضعیت: 🚧 در حال اجرا
اولویت: 🔴 بالا
📊 وضعیت فعلی
✅ موارد کامل شده:
| بخش | فایلها | وضعیت |
|---|---|---|
| Domain Entities | DiscountProduct, DiscountCategory, DiscountOrder, DiscountOrderDetail, DiscountShoppingCart, DiscountProductCategory |
✅ کامل |
| CMS Commands | Create/Update/Delete برای Product, Category, Order, Cart | ✅ کامل |
| CMS Queries | GetProducts, GetCategories, GetUserOrders, GetUserCart, GetOrderById | ✅ کامل |
| Proto Files | discountproduct.proto, discountcategory.proto, discountorder.proto, discountshoppingcart.proto |
✅ کامل |
| BackOffice UI | DiscountProductsMainPage, DiscountCategoriesMainPage, DiscountOrdersMainPage, SalesReports | ✅ کامل |
| BackOffice Services | IDiscountProductService, IDiscountCategoryService, IDiscountOrderService | ✅ کامل |
| UI کامپوننت گالری | ProductImageGallery.razor (فقط کلاینت، بدون Backend) | ⚠️ ناقص |
❌ موارد باقیمانده:
| # | مورد | توضیح | تخمین زمان |
|---|---|---|---|
| 1 | گالری تصاویر محصول | Entity + CRUD + Proto + Backend | 4 ساعت |
| 2 | API لیست سفارشات ادمین | GetAllDiscountOrders با فیلترها | 2 ساعت |
| 3 | محاسبه VAT | فعالسازی مالیات 10% در سفارشات | 1 ساعت |
| 4 | گزارش فروش | API آماری برای SalesReports | 2 ساعت |
| 5 | اتصال گالری به Backend | Upload + Service در BackOffice | 2 ساعت |
| جمع | 11 ساعت |
📋 مراحل پیادهسازی
مرحله ۱: گالری تصاویر محصول (Backend)
1.1 ایجاد Entity
فایل: CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/DiscountProductImage.cs
namespace CMSMicroservice.Domain.Entities.DiscountShop;
/// <summary>
/// تصویر گالری محصول تخفیفی
/// </summary>
public class DiscountProductImage : BaseAuditableEntity
{
/// <summary>
/// شناسه محصول
/// </summary>
public long DiscountProductId { get; set; }
/// <summary>
/// محصول
/// </summary>
public virtual DiscountProduct DiscountProduct { get; set; }
/// <summary>
/// عنوان تصویر
/// </summary>
public string? Title { get; set; }
/// <summary>
/// متن جایگزین (Alt)
/// </summary>
public string? AltText { get; set; }
/// <summary>
/// مسیر تصویر اصلی
/// </summary>
public string ImagePath { get; set; }
/// <summary>
/// مسیر تصویر کوچک
/// </summary>
public string? ThumbnailPath { get; set; }
/// <summary>
/// ترتیب نمایش
/// </summary>
public int SortOrder { get; set; }
/// <summary>
/// آیا تصویر اصلی محصول است؟
/// </summary>
public bool IsPrimary { get; set; }
}
1.2 ایجاد Configuration
فایل: CMS/src/CMSMicroservice.Infrastructure/Persistence/Configurations/DiscountShop/DiscountProductImageConfiguration.cs
using CMSMicroservice.Domain.Entities.DiscountShop;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
namespace CMSMicroservice.Infrastructure.Persistence.Configurations.DiscountShop;
public class DiscountProductImageConfiguration : IEntityTypeConfiguration<DiscountProductImage>
{
public void Configure(EntityTypeBuilder<DiscountProductImage> builder)
{
builder.ToTable("DiscountProductImages");
builder.HasKey(x => x.Id);
builder.Property(x => x.Title)
.HasMaxLength(200);
builder.Property(x => x.AltText)
.HasMaxLength(500);
builder.Property(x => x.ImagePath)
.IsRequired()
.HasMaxLength(500);
builder.Property(x => x.ThumbnailPath)
.HasMaxLength(500);
builder.HasOne(x => x.DiscountProduct)
.WithMany(p => p.Images)
.HasForeignKey(x => x.DiscountProductId)
.OnDelete(DeleteBehavior.Cascade);
builder.HasIndex(x => x.DiscountProductId);
builder.HasIndex(x => new { x.DiscountProductId, x.SortOrder });
}
}
1.3 بهروزرسانی DiscountProduct Entity
فایل: CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/DiscountProduct.cs
اضافه کردن Navigation Property:
/// <summary>
/// تصاویر گالری محصول
/// </summary>
public virtual ICollection<DiscountProductImage> Images { get; set; }
1.4 بهروزرسانی DbContext
فایل: CMS/src/CMSMicroservice.Infrastructure/Persistence/ApplicationDbContext.cs
public DbSet<DiscountProductImage> DiscountProductImages { get; set; }
1.5 ایجاد Migration
cd CMS/src/CMSMicroservice.Infrastructure
dotnet ef migrations add AddDiscountProductImages -s ../CMSMicroservice.WebApi
1.6 ایجاد Commands
پوشه: CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/
| Command | فایلها |
|---|---|
AddDiscountProductImage |
Command.cs, Handler.cs, Validator.cs |
UpdateDiscountProductImage |
Command.cs, Handler.cs, Validator.cs |
DeleteDiscountProductImage |
Command.cs, Handler.cs |
ReorderDiscountProductImages |
Command.cs, Handler.cs |
1.7 ایجاد Query
پوشه: CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetDiscountProductImages/
| فایل | توضیح |
|---|---|
GetDiscountProductImagesQuery.cs |
Request با ProductId |
GetDiscountProductImagesQueryHandler.cs |
Handler |
GetDiscountProductImagesResponseDto.cs |
Response با لیست تصاویر |
1.8 بهروزرسانی Proto
فایل: CMS/src/CMSMicroservice.Protobuf/Protos/discountproduct.proto
// اضافه کردن به service DiscountProductContract:
rpc AddDiscountProductImage(AddDiscountProductImageRequest) returns (AddDiscountProductImageResponse);
rpc UpdateDiscountProductImage(UpdateDiscountProductImageRequest) returns (google.protobuf.Empty);
rpc DeleteDiscountProductImage(DeleteDiscountProductImageRequest) returns (google.protobuf.Empty);
rpc ReorderDiscountProductImages(ReorderDiscountProductImagesRequest) returns (google.protobuf.Empty);
rpc GetDiscountProductImages(GetDiscountProductImagesRequest) returns (GetDiscountProductImagesResponse);
// Messages:
message AddDiscountProductImageRequest {
int64 product_id = 1;
string title = 2;
string alt_text = 3;
string image_path = 4;
string thumbnail_path = 5;
int32 sort_order = 6;
bool is_primary = 7;
}
message AddDiscountProductImageResponse {
int64 image_id = 1;
}
message UpdateDiscountProductImageRequest {
int64 image_id = 1;
string title = 2;
string alt_text = 3;
string image_path = 4;
string thumbnail_path = 5;
int32 sort_order = 6;
bool is_primary = 7;
}
message DeleteDiscountProductImageRequest {
int64 image_id = 1;
}
message ReorderDiscountProductImagesRequest {
int64 product_id = 1;
repeated int64 image_ids = 2; // ترتیب جدید
}
message GetDiscountProductImagesRequest {
int64 product_id = 1;
}
message GetDiscountProductImagesResponse {
repeated DiscountProductImageDto images = 1;
}
message DiscountProductImageDto {
int64 id = 1;
int64 product_id = 2;
string title = 3;
string alt_text = 4;
string image_path = 5;
string thumbnail_path = 6;
int32 sort_order = 7;
bool is_primary = 8;
}
1.9 ایجاد gRPC Service Methods
فایل: CMS/src/CMSMicroservice.WebApi/Services/DiscountProductService.cs
اضافه کردن 5 متد جدید برای Image CRUD.
مرحله ۲: API لیست سفارشات ادمین
2.1 ایجاد Query
پوشه: CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetAllDiscountOrders/
// GetAllDiscountOrdersQuery.cs
public class GetAllDiscountOrdersQuery : IRequest<GetAllDiscountOrdersResponseDto>
{
public long? UserId { get; set; }
public bool? PaymentCompleted { get; set; }
public int? DeliveryStatus { get; set; }
public DateTime? FromDate { get; set; }
public DateTime? ToDate { get; set; }
public string? SearchQuery { get; set; } // جستجو در شماره سفارش
public int PageNumber { get; set; } = 1;
public int PageSize { get; set; } = 20;
}
2.2 بهروزرسانی Proto
فایل: CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto
// اضافه کردن به service:
rpc GetAllDiscountOrders(GetAllDiscountOrdersRequest) returns (GetAllDiscountOrdersResponse);
message GetAllDiscountOrdersRequest {
google.protobuf.Int64Value user_id = 1;
google.protobuf.BoolValue payment_completed = 2;
google.protobuf.Int32Value delivery_status = 3;
google.protobuf.Timestamp from_date = 4;
google.protobuf.Timestamp to_date = 5;
google.protobuf.StringValue search_query = 6;
int32 page_number = 7;
int32 page_size = 8;
}
message GetAllDiscountOrdersResponse {
messages.MetaData meta_data = 1;
repeated OrderSummaryDto models = 2;
}
2.3 بهروزرسانی BackOffice Service
فایل: BackOffice/src/BackOffice/Services/DiscountOrder/DiscountOrderService.cs
تغییر GetOrdersAsync برای استفاده از API جدید (GetAllDiscountOrders به جای GetUserOrders با UserId=0).
مرحله ۳: فعالسازی محاسبه VAT
3.1 بهروزرسانی PlaceOrderCommandHandler
فایل: CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/PlaceOrder/PlaceOrderCommandHandler.cs
// محاسبه VAT (10%)
const decimal VatRate = 0.10m;
var vatAmount = (long)(totalAmount * VatRate);
order.VatAmount = vatAmount;
// مبلغ نهایی شامل VAT
var finalAmount = totalAmount + vatAmount;
3.2 بهروزرسانی Proto Response
فایل: CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto
اضافه کردن int64 vat_amount به PlaceOrderResponse و GetOrderByIdResponse.
3.3 بهروزرسانی UI
فایل: BackOffice/src/BackOffice/Pages/DiscountShop/Components/OrderDetailsDialog.razor
نمایش VAT در جزئیات سفارش.
مرحله ۴: گزارش فروش (Statistics API)
4.1 ایجاد Query
پوشه: CMS/src/CMSMicroservice.Application/DiscountShopCQ/Queries/GetDiscountShopStatistics/
public class GetDiscountShopStatisticsResponseDto
{
// خلاصه کلی
public long TotalSales { get; set; }
public int TotalOrders { get; set; }
public int TotalProducts { get; set; }
public int TotalCustomers { get; set; }
// گزارش بازه زمانی
public long PeriodSales { get; set; }
public int PeriodOrders { get; set; }
// پرفروشترینها
public List<TopProductDto> TopProducts { get; set; }
// فروش روزانه (برای نمودار)
public List<DailySalesDto> DailySales { get; set; }
}
public class TopProductDto
{
public long ProductId { get; set; }
public string Title { get; set; }
public int SalesCount { get; set; }
public long TotalRevenue { get; set; }
}
public class DailySalesDto
{
public DateTime Date { get; set; }
public long Amount { get; set; }
public int OrderCount { get; set; }
}
4.2 بهروزرسانی Proto
فایل: CMS/src/CMSMicroservice.Protobuf/Protos/discountorder.proto
rpc GetDiscountShopStatistics(GetDiscountShopStatisticsRequest) returns (GetDiscountShopStatisticsResponse);
message GetDiscountShopStatisticsRequest {
google.protobuf.Timestamp from_date = 1;
google.protobuf.Timestamp to_date = 2;
}
message GetDiscountShopStatisticsResponse {
int64 total_sales = 1;
int32 total_orders = 2;
int32 total_products = 3;
int32 total_customers = 4;
int64 period_sales = 5;
int32 period_orders = 6;
repeated TopProductDto top_products = 7;
repeated DailySalesDto daily_sales = 8;
}
4.3 تکمیل SalesReports.razor
فایل: BackOffice/src/BackOffice/Pages/DiscountShop/SalesReports.razor
اتصال به API جدید و نمایش:
- کارتهای آماری (Total Sales, Orders, Products, Customers)
- جدول پرفروشترین محصولات
- نمودار فروش روزانه (MudChart)
مرحله ۵: اتصال گالری به Backend
5.1 ایجاد Service در BackOffice
فایل: BackOffice/src/BackOffice/Services/DiscountProduct/IDiscountProductService.cs
اضافه کردن متدهای:
Task<List<DiscountProductImageDto>> GetProductImagesAsync(long productId);
Task<long> AddProductImageAsync(AddProductImageDto dto);
Task UpdateProductImageAsync(UpdateProductImageDto dto);
Task DeleteProductImageAsync(long imageId);
Task ReorderProductImagesAsync(long productId, List<long> imageIds);
5.2 بهروزرسانی ProductFormDialog
فایل: BackOffice/src/BackOffice/Pages/DiscountShop/Components/ProductFormDialog.razor
- در حالت Edit: بارگذاری تصاویر موجود از API
- اتصال کامپوننت
ProductImageGalleryبه متدهای Service - ذخیره تغییرات گالری همزمان با ذخیره محصول
5.3 آپلود فایل
بررسی سیستم آپلود موجود در پروژه:
- اگر MinIO/S3 استفاده میشود: استفاده از همان سرویس
- اگر فایلسیستم: ایجاد endpoint آپلود در CMS
📝 Checklist
مرحله ۱: گالری تصاویر
- ایجاد Entity
DiscountProductImage - ایجاد Configuration
- بهروزرسانی
DiscountProductEntity - بهروزرسانی DbContext
- ایجاد و اجرای Migration
- ایجاد Commands (Add, Update, Delete, Reorder)
- ایجاد Query (GetImages)
- بهروزرسانی Proto
- پیادهسازی gRPC Service Methods
- تست با Postman/gRPCurl
مرحله ۲: API سفارشات ادمین
- ایجاد Query
GetAllDiscountOrders - بهروزرسانی Proto
- پیادهسازی gRPC Service Method
- بهروزرسانی BackOffice Service
- تست UI DiscountOrdersMainPage
مرحله ۳: محاسبه VAT
- بهروزرسانی
PlaceOrderCommandHandler - بهروزرسانی Proto (VatAmount در responses)
- بهروزرسانی UI نمایش سفارش
- تست محاسبه VAT
مرحله ۴: گزارش فروش
- ایجاد Query
GetDiscountShopStatistics - بهروزرسانی Proto
- پیادهسازی gRPC Service Method
- ایجاد Service در BackOffice
- تکمیل UI
SalesReports.razor
مرحله ۵: اتصال گالری
- اضافه کردن متدهای Image به Service
- بهروزرسانی ProductFormDialog
- پیادهسازی/اتصال به سیستم آپلود
- تست کامل گالری
🔗 فایلهای مرتبط
| فایل | توضیح |
|---|---|
totalDoc/01-BUSINESS/discount-shop-business.md |
مستندات اصلی طراحی |
totalDoc/03-BACKEND/BackOffice.BFF/discount-shop-integration.md |
پلن اولیه integration |
CMS/src/CMSMicroservice.Domain/Entities/DiscountShop/ |
Entity های موجود |
CMS/src/CMSMicroservice.Application/DiscountShopCQ/ |
Commands و Queries موجود |
BackOffice/src/BackOffice/Pages/DiscountShop/ |
صفحات UI موجود |
آخرین بهروزرسانی: ۱۰ دی ۱۴۰۴