Refactor: Update Protobuf references to CMSMicroservice across User, UserAddress, UserOrder, UserRole, and related services
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 3m9s

- Changed Protobuf imports from BackOffice.BFF to CMSMicroservice for User, UserAddress, UserOrder, UserRole components and services.
- Updated appsettings for direct connection to CMS, removing BFF references.
- Adjusted logic in services to accommodate new Protobuf structure and fields.
- Moved documentation to totalDoc directory.
This commit is contained in:
masoodafar-web
2026-02-10 22:05:13 +03:30
parent 7a27347142
commit 8d9942ddc2
139 changed files with 374 additions and 4293 deletions
-501
View File
@@ -1,501 +0,0 @@
# BackOffice Build Fix Status
> آخرین بروزرسانی: December 20, 2025
## وضعیت فعلی
**Build Status**: ✅ SUCCESS - 0 Error
### BackOffice.BFF Solution:
- **Build**: ✅ موفق - 0 Error
- **Proto Projects فعال**:
- ✅ BackOffice.BFF.Tag.Protobuf
- ✅ BackOffice.BFF.ProductTag.Protobuf
- ✅ BackOffice.BFF.DiscountProduct.Protobuf
- ✅ BackOffice.BFF.DiscountCategory.Protobuf
- ✅ BackOffice.BFF.DiscountOrder.Protobuf
- ✅ BackOffice.BFF.DiscountShoppingCart.Protobuf
- ✅ BackOffice.BFF.PublicMessage.Protobuf
- ✅ BackOffice.BFF.ManualPayment.Protobuf
- ✅ BackOffice.BFF.ClubMembership.Protobuf
- ✅ BackOffice.BFF.Commission.Protobuf
### BackOffice UI:
- **Build**: ✅ موفق - 0 Error
- **Framework**: Blazor WebAssembly .NET 9.0
- **UI Library**: MudBlazor 8.14.0
### CMS Microservice:
- **Build**: ✅ موفق - 0 Error
**پیشرفت کلی**: از 60+ خطا به 0 خطا رسیدیم ✨
---
## ⚠️ ملاحظات مهم Proto Packages
> **هشدار مهم**: هر تغییری در Proto files نیاز به این 3 مرحله دارد:
### چک‌لیست اجباری بعد از تغییر Proto:
1. **افزایش Version** در `.csproj`:
```xml
<Version>0.0.142</Version> → <Version>0.0.143</Version>
```
2. **Pack کردن** Proto project:
```bash
cd path/to/proto/project
dotnet pack -c Release
# ✅ خودکار push می‌شه به GitLab Registry
```
3. **Update Version** در پروژه‌های وابسته (لایه بالاتر):
```xml
<PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.143" />
```
**مثال**: تغییر در CMS Proto → Pack → Update در BFF Protos → Pack → Update در UI
**⚠️ فراموش کردن این مراحل = Build Error یا Runtime Bug**
---
## ماژول‌های فعال شده (Enabled Modules)
### ✅ کاملاً فعال و تست شده:
1. **DiscountShop Module** (فروشگاه تخفیفی)
- ✅ DiscountProductsMainPage - مدیریت محصولات تخفیفی
- ✅ DiscountCategoriesMainPage - مدیریت دسته‌بندی‌ها (با MudDataGrid)
- ✅ DiscountOrdersMainPage - مدیریت سفارشات
- ✅ SalesReports - گزارش فروش
- ✅ ProductImageGallery - گالری تصاویر (با MudBlazor 8 fixes)
- Services: IDiscountProductService, IDiscountCategoryService, IDiscountOrderService
2. **PublicMessages Module** (پیام‌های عمومی)
- ✅ PublicMessagesMainPage - مدیریت پیام‌ها
- ✅ MessageFormDialog - فرم ایجاد/ویرایش
- ✅ MessageViewDialog - نمایش جزئیات
- ✅ MessageTemplatesDialog - قالب‌های آماده
- Services: IPublicMessageService
- Proto: BackOffice.BFF.PublicMessage.Protobuf
3. **ManualPayment Module** (پرداخت‌های دستی)
- ✅ ManualPayments - صفحه اصلی مدیریت
- ✅ ManualPaymentDialog - فرم ایجاد و تایید/رد
- Services: Direct gRPC to ManualPaymentContract
- Proto: BackOffice.BFF.ManualPayment.Protobuf
4. **Tag Module** (برچسب‌ها)
- ✅ TagManagementPage - مدیریت تگ‌ها
- ✅ TagEditDialog - ویرایش تگ
- Services: ITagService, IProductTagService
- Proto: BackOffice.BFF.Tag.Protobuf, BackOffice.BFF.ProductTag.Protobuf
5. **Dashboard Widgets**
- ✅ DiscountShopWidget - آمار فروشگاه تخفیفی (7 روز اخیر)
6. **Payment Pages**
- ✅ Transactions - صفحه تراکنش‌ها
7. **DragDrop Pages**
- ✅ CategoryProductsDragDropPage - مدیریت محصولات دسته
- ✅ ProductCategoriesDragDropPage - مدیریت دسته‌های محصول
8. **BulkEdit Module**
- ✅ BulkEdit - ویرایش گروهی محصولات (قیمت، موجودی، وضعیت)
- Proto: BackOffice.BFF.Products.Protobuf (BulkUpdateProductPrices, BulkUpdateProductStock, ToggleProductStatus)
- Note: استفاده از `BackOffice.BFF.Protobuf.Common.PaginationState` با using alias
9. **Product Image Management** - ✅ FULLY OPERATIONAL
- ✅ GalleryDialog - گالری تصاویر محصول
- ✅ CreateDialog - ایجاد محصول با آپلود تصویر
- ✅ UpdateDialog - ویرایش محصول با آپلود تصویر
- ✅ Proto: GetProductGallery, AddProductImage, RemoveProductImage
- ✅ Messages: ImageFileModel, ProductGalleryItem
- ✅ Backend: ProductsService methods uncommented and active
- ✅ CQRS Handlers: AddProductImageCommandHandler, GetProductGalleryQueryHandler, RemoveProductImageCommandHandler
- ✅ CMS Integration: ProductGalleries microservice connected
- ✅ Image Optimization: SixLabors.ImageSharp (1200x1200 + 300x300 thumbnail)
---
## ماژول‌های Exclude شده (نیاز به کار اضافی)
**هیچ فایلی Exclude نیست!** ✅
تمامی صفحات و کامپوننت‌ها build می‌شوند. فقط Backend implementation برای Image Upload لازمه.
---
## تغییرات مهم MudBlazor 8
### Breaking Changes برطرف شده:
1. **MudDialogInstance → IMudDialogInstance**
```csharp
// قبلی:
[CascadingParameter] MudDialogInstance MudDialog { get; set; }
// جدید:
[CascadingParameter] IMudDialogInstance MudDialog { get; set; }
```
2. **MudSwitch نیاز به T parameter**
```razor
<!-- قبلی: -->
<MudSwitch @bind-Checked="Model.IsActive" />
<!-- جدید: -->
<MudSwitch T="bool" @bind-Value="Model.IsActive" />
```
3. **MudChip نیاز به T parameter**
```razor
<!-- قبلی: -->
<MudChip>Text</MudChip>
<!-- جدید: -->
<MudChip T="string">Text</MudChip>
```
4. **MudTreeView تغییر API**
- راه‌حل: جایگزینی با `MudDataGrid` در DiscountCategoriesMainPage
5. **MudFileUpload تغییر signature**
```csharp
// FilesChanged حالا IBrowserFile می‌گیرد نه IReadOnlyList
<MudFileUpload T="IReadOnlyList<IBrowserFile>" FilesChanged="OnFilesSelected" />
```
6. **DragEventArgs.PreventDefault() حذف شد**
```razor
<!-- استفاده از directive attribute: -->
@ondragover:preventDefault
```
---
## تغییرات Proto
### 1. Google.Protobuf.WellKnownTypes Simplification
در همه جا از wrapper به مقدار مستقیم تغییر یافت:
```csharp
// قبلی (اشتباه):
request.UserId = new Google.Protobuf.WellKnownTypes.Int64Value { Value = userId };
request.Status = new Google.Protobuf.WellKnownTypes.Int32Value { Value = status };
request.ReferenceNumber = new Google.Protobuf.WellKnownTypes.StringValue { Value = refNum };
// جدید (صحیح):
request.UserId = userId;
request.Status = status;
request.ReferenceNumber = refNum;
```
### 2. Timestamp to DateTime Conversion
```csharp
// Proto Timestamp به DateTime تبدیل می‌شود:
var dateTime = timestamp.ToDateTime(); // به جای ToLocalTime()
```
---
## تغییرات معماری
### BasePageComponent Pattern
صفحات با فیلتر از `BasePageComponent` استفاده می‌کنند ولی `ReloadAsync()` ندارد.
راه‌حل: استفاده مستقیم از `MudDataGrid.ReloadServerData()`:
```csharp
private MudDataGrid<ModelType>? _dataGrid;
private async Task OnFilterSubmit()
{
if (_dataGrid != null)
await _dataGrid.ReloadServerData();
}
```
---
- `ProductGalleryImage`
- `GetCategoriesRequest/Response`
- `UpdateProductCategoriesRequest`
- `GetProductsForCategoryRequest/Response`
- `UpdateCategoryProductsRequest`
### 3. تغییرات csproj
**Products از NuGet به ProjectReference تغییر کرد**:
```xml
<!-- قبلی: -->
<PackageReference Include="Foursat.BackOffice.BFF.Products.Protobuf" Version="0.0.8" />
<!-- جدید: -->
<ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.Products.Protobuf/BackOffice.BFF.Products.Protobuf.csproj" />
```
### 4. فیکس‌های MudBlazor
**MudSwitch T parameter**:
- `Pages/Settings/UserSettings.razor`
- `Pages/Club/ClubMembers.razor`
- `Pages/Configuration/Configuration.razor`
```razor
<!-- قبلی: -->
<MudSwitch @bind-Value="..." />
<!-- جدید: -->
<MudSwitch T="bool" @bind-Value="..." />
```
### 5. فیکس Snackbar Duplicate
در فایل‌های زیر `[Inject] ISnackbar Snackbar` حذف شد (چون در `_Imports.razor` inject شده):
- `ApplyDiscountDialog.razor.cs`
- `CancelOrderDialog.razor.cs`
- `ChangeOrderStatusDialog.razor.cs`
### 6. فیکس ConfigureService.cs
Using های زیر comment شدند:
```csharp
// using BackOffice.Services.DiscountProduct;
// using BackOffice.Services.DiscountCategory;
// using BackOffice.Services.DiscountOrder;
// using BackOffice.Services.Tag;
// using BackOffice.Services.ProductTag;
// using BackOffice.Services.PublicMessage;
```
---
## کارهای باقیمانده (TODO)
### فوری - نیاز به Proto Methods:
#### 1. Product Image Management
**فایل‌های Excluded**:
- `Pages/Products/Components/GalleryDialog.razor`
- `Pages/Products/Components/CreateDialog.razor`
- `Pages/Products/Components/UpdateDialog.razor`
**Proto Methods مورد نیاز در `products.proto`**:
```protobuf
service ProductsContract {
// برای GalleryDialog:
rpc AddProductImage(AddProductImageRequest) returns (AddProductImageResponse);
rpc RemoveProductImage(RemoveProductImageRequest) returns (google.protobuf.Empty);
// برای Create/Update Dialogs:
rpc CreateProductWithImage(CreateProductWithImageRequest) returns (CreateProductResponse);
rpc UpdateProductWithImage(UpdateProductWithImageRequest) returns (google.protobuf.Empty);
}
message ImageFileModel {
bytes file = 1;
string mime = 2;
string file_name = 3;
}
message AddProductImageRequest {
int64 product_id = 1;
string title = 2;
ImageFileModel image_file = 3;
}
message AddProductImageResponse {
int64 product_gallery_id = 1;
}
message RemoveProductImageRequest {
int64 product_gallery_id = 1;
}
message CreateProductWithImageRequest {
// ... سایر فیلدهای محصول
ImageFileModel image_file = 1;
ImageFileModel thumbnail_file = 2;
}
message UpdateProductWithImageRequest {
int64 id = 1;
// ... سایر فیلدها
ImageFileModel image_file = 2;
ImageFileModel thumbnail_file = 3;
}
```
**وضعیت**: 🔴 نیاز به پیاده‌سازی در Backend
---
#### 2. BulkEdit Refactoring
**فایل Excluded**: `Pages/Products/BulkEdit.razor`
**مشکل**: استفاده مستقیم از `CMSMicroservice.Protobuf.Protos`
**راه‌حل**:
1. حذف dependency به `CMSMicroservice.Protobuf`
2. افزودن bulk update methods به `products.proto`:
```protobuf
service ProductsContract {
rpc BulkUpdateProducts(BulkUpdateProductsRequest) returns (BulkUpdateProductsResponse);
}
message BulkUpdateProductsRequest {
repeated int64 product_ids = 1;
google.protobuf.Int64Value new_price = 2;
google.protobuf.Int32Value new_discount = 3;
google.protobuf.Int32Value new_club_discount_percent = 4;
StockUpdateOperation stock_operation = 5;
google.protobuf.BoolValue status_enable = 6;
}
enum StockUpdateOperation {
STOCK_NO_CHANGE = 0;
STOCK_SET = 1;
STOCK_ADD = 2;
STOCK_SUBTRACT = 3;
}
message BulkUpdateProductsResponse {
int32 updated_count = 1;
repeated int64 failed_product_ids = 2;
}
```
**وضعیت**: 🔴 نیاز به پیاده‌سازی در Backend
---
### اختیاری - بهبودها:
#### 3. Transactions API Implementation
**فایل**: `Pages/Payment/Transactions.razor`
**وضعیت فعلی**: ✅ Enabled ولی متد `LoadData` فقط `TODO` دارد
**نیاز**: پیاده‌سازی Transaction API در Backend
---
## آمار نهایی
### ماژول‌های فعال: 7 ✅
1. DiscountShop (Products, Categories, Orders, Reports)
2. PublicMessages
3. ManualPayments
4. Tag Management
5. Dashboard DiscountShopWidget
6. Transactions Page
7. DragDrop Pages (Category ↔ Products)
### ماژول‌های Excluded: 3 ❌
1. GalleryDialog (نیاز به Image Upload API)
2. CreateDialog/UpdateDialog (نیاز به Image Upload API)
3. BulkEdit (نیاز به Refactoring + Bulk API)
### Build Errors: 0 🎉
### Proto Projects: 14 فعال
### صفحات فعال: ~30+
### کامپوننت‌های فعال: ~50+
---
---
## Handler های موقتاً Exclude شده در BackOffice.BFF.Application
### فایل‌های Exclude شده:
```xml
<Compile Remove="DiscountOrderCQ/**/*.cs" />
<Compile Remove="DiscountShoppingCartCQ/**/*.cs" />
<Compile Remove="ManualPaymentCQ/**/*.cs" />
<Compile Remove="ConfigurationCQ/**/*.cs" />
<Compile Remove="CommissionCQ/Commands/ProcessWithdrawal/**/*.cs" />
```
### دلیل Exclude:
این Handler ها فیلدهای متفاوتی با proto های CMS دارند و نیاز به بازنویسی دارند.
### مثال عدم تطابق DiscountOrder:
**Handler انتظار دارد:**
- Request: `UserId`, `AddressId`, `DiscountBalanceAmount`, `GatewayAmount`
- Response: `OrderId`, `TrackingCode`, `RequiresGatewayPayment`, `GatewayPayableAmount`
**Proto CMS دارد:**
- Request: `user_id`, `user_address_id`, `discount_balance_to_use`, `notes`
- Response: `success`, `message`, `order_id`, `gateway_amount`, `payment_url`
---
## Proto Update های مورد نیاز
### UserOrder.Protobuf
متدهای زیر باید اضافه شوند:
- `CancelOrderAsync(CancelOrderRequest)`
- `ApplyDiscountToOrderAsync(ApplyDiscountToOrderRequest)`
- `UpdateOrderStatusAsync(UpdateOrderStatusRequest)`
فیلدهای زیر باید اضافه شوند:
- `VatAmount`
- `VatPercentage`
- `VatBaseAmount`
- `VatTotalAmount`
- `PaymentStatus.None`
### Products.Protobuf
متدهای زیر باید اضافه شوند:
- `AddProductImageAsync`
- `RemoveProductImageAsync`
فیلدهای زیر باید اضافه شوند:
- `ImageFile` (bytes)
- `ThumbnailFile` (bytes)
- `ImageFileModel` message
---
## دستورات برای ادامه کار
### 1. اجرای build برای دیدن خطاهای فعلی:
```bash
cd /home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice
dotnet build 2>&1 | grep -E "error CS|Error"
```
### 2. فایل‌های مهم برای بررسی:
- `BackOffice.csproj` - لیست exclude ها و references
- `ConfigureService.cs` - DI registrations
- `_Imports.razor` - global using و inject ها
### 3. Proto فایل‌های مهم:
- `BackOffice.BFF/src/Protobufs/BackOffice.BFF.Products.Protobuf/Protos/products.proto`
- `BackOffice.BFF/src/Protobufs/BackOffice.BFF.UserOrder.Protobuf/Protos/userorder.proto`
---
## چک‌لیست برای chat جدید
- [ ] خطاهای build رو چک کن
- [ ] `PaginationState` namespace رو فیکس کن
- [ ] `WithdrawalReports` binding رو فیکس کن
- [ ] `OpenGalleryDialog` رو comment کن در `ProductsMainPage`
- [ ] `DiscountShopWidget` رو از `SystemOverview` حذف کن
- [ ] تست build موفق
---
## نکات مهم
1. **هیچ فایلی حذف نشده** - فقط از build exclude شدند
2. **Proto های local** از ProjectReference استفاده می‌کنند نه NuGet
3. **MudBlazor 8.14.0** نیاز به `T` parameter برای generic components دارد
4. **Snackbar** در `_Imports.razor` inject شده، نباید در component ها duplicate بشه
-118
View File
@@ -1,118 +0,0 @@
# BackOffice Changelog
> تاریخچه تغییرات پروژه BackOffice
---
## December 20, 2025
### 🐛 Bug Fixes
#### 1. صفحه `/network/balances` - ValidationException
**مشکل**: خطای ValidationException هنگام لود صفحه
**راه‌حل**: اضافه کردن Mapster mapping در `CommissionProfile.cs`:
```csharp
config.NewConfig<GetUserWeeklyBalancesRequest, GetUserWeeklyBalancesQuery>()
.Map(dest => dest.PaginationState, src => src.PaginationState);
```
---
#### 2. صفحه `/club/members` - داده‌ها لود نمی‌شدند
**مشکل**: صفحه خالی بود و داده‌ای نمایش نمی‌داد
**راه‌حل**: ایجاد `ClubMembershipProfile.cs` در CMS و BFF با mappings کامل:
- `GetAllClubMembershipsRequest``GetAllClubMembershipsQuery`
- `GetAllClubMembershipsResponseDto``GetAllClubMembershipsResponse`
**فایل‌های جدید**:
- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs`
- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` (بازنویسی)
---
#### 3. صفحه `/club/statistics` - Unimplemented Error
**مشکل**: خطای `Status(StatusCode="Unimplemented")`
**راه‌حل**:
1. اضافه کردن override `GetClubStatistics` در `ClubMembershipService.cs`
2. اضافه کردن mappings برای Statistics در هر دو Profile
---
### ✨ New Features
#### 4. فعال‌سازی قابلیت‌های Products
**قبل**: همه دکمه‌ها "در حال توسعه" نشان می‌دادند
**بعد**: همه قابلیت‌ها فعال شدند:
- ✅ ایجاد محصول جدید (CreateDialog)
- ✅ ویرایش محصول (UpdateDialog)
- ✅ گالری تصاویر (GalleryDialog)
- ✅ مدیریت تگ‌ها (AssignTagsDialog)
**فایل**: `ProductsMainPage.razor.cs`
---
#### 5. فیلد "تعداد موجودی" در Products
**اضافات**:
- فیلد موجودی در فرم ایجاد محصول
- فیلد موجودی در فرم ویرایش محصول
- ستون موجودی در لیست با رنگ‌بندی:
- 🔴 ناموجود (0 یا کمتر)
- 🟡 کم موجود (کمتر از 10)
- 🟢 موجود (10 یا بیشتر)
**فایل‌های تغییر یافته**:
- `CreateDialog.razor`
- `UpdateDialog.razor`
- `ProductsMainPage.razor`
- `CreateNewProductsCommand.cs` (BFF)
- `UpdateProductsCommand.cs` (BFF)
---
## December 6, 2025
### ✅ Major Milestones
- Build Errors: 60+ → 0
- MudBlazor 8 Migration Complete
- All Product Image Management APIs Implemented
- BulkEdit Module Enabled
- All Files Unexcluded
### 🔧 Technical Changes
- `IMudDialogInstance` جایگزین `MudDialogInstance`
- `MudSwitch T="bool"` اضافه شد
- `MudChip T="string"` اضافه شد
- Products از NuGet به ProjectReference تغییر کرد
---
## December 1, 2025
### ✅ Network & Commission System
- Commission Dashboard Complete
- Network Members Page Complete
- Club Members Page Complete
- Weekly Pool Management
- Withdrawal System
- Payout System
---
## November 29, 2025
### ✅ Initial Setup
- SystemConfigurations Table Created
- Base Configuration Values Added:
- `Network.MaxDepth`: 10
- `Club.DefaultMembershipDurationMonths`: 12
- `Commission.MinimumPayoutAmount`: 100000
- `System.MaintenanceMode`: false
-274
View File
@@ -1,274 +0,0 @@
# Refactoring DiscountProduct Form - Session 2026-01-05
## هدف
یکسان‌سازی فرم ایجاد/ویرایش محصولات تخفیفی (DiscountProduct) با فرم محصولات عادی (Product) برای بهبود تجربه کاربری و افزودن قابلیت‌های حرفه‌ای.
## تغییرات انجام شده
### 1. Frontend - ProductFormDialog.razor
#### قبل:
- استفاده از MudGrid
- TextField ساده برای مسیر تصویر (بدون قابلیت آپلود)
- TextField چند خطی برای توضیحات
- MudSelect ساده برای دسته‌بندی‌ها
- فاقد پیش‌نمایش تصویر
#### بعد:
- **تغییر Layout**: از MudGrid به MudStack
- **آپلود تصویر**:
- MudFileUpload برای انتخاب تصویر اصلی و بندانگشتی
- پیش‌نمایش تصویر قبل از آپلود
- نمایش تصویر موجود در حالت ویرایش
- **ویرایشگر HTML**:
- استفاده از MudHtmlEditor برای FullInformation
- قابلیت فرمت‌دهی متن (bold, italic, لیست و...)
- **دسته‌بندی**:
- استفاده از MudSelect با MultiSelection
- لود خودکار DiscountCategory ها (نه Category های عادی)
- نمایش تعداد دسته‌بندی‌های انتخاب شده
- **فیلدهای اختصاصی حفظ شده**:
- MaxDiscountPercent
- IsActive
- SortOrder
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Pages/DiscountShop/Components/ProductFormDialog.razor`
### 2. Proto File - discountproduct.proto
#### تغییرات:
```protobuf
message CreateDiscountProductRequest {
// ... فیلدهای قبلی
ImageFileModel image_file = 12; // جدید
ImageFileModel thumbnail_file = 13; // جدید
}
message UpdateDiscountProductRequest {
// ... فیلدهای قبلی
ImageFileModel image_file = 12; // جدید
ImageFileModel thumbnail_file = 13; // جدید
}
// تعریف مدل جدید
message ImageFileModel {
bytes file = 1;
string mime = 2;
string file_name = 3;
}
```
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/Protobufs/BackOffice.BFF.DiscountProduct.Protobuf/Protos/discountproduct.proto`
### 3. DTOs - Backend
#### CreateDiscountProductDto و UpdateDiscountProductDto:
```csharp
// پراپرتی‌های جدید اضافه شده:
public byte[]? ImageFile { get; set; }
public string? ImageMime { get; set; }
public string? ImageFileName { get; set; }
public byte[]? ThumbnailFile { get; set; }
public string? ThumbnailMime { get; set; }
public string? ThumbnailFileName { get; set; }
```
**فایل‌ها**:
- `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Services/DiscountProduct/IDiscountProductService.cs`
### 4. Service Layer - DiscountProductService
#### تغییرات CreateAsync و UpdateAsync:
```csharp
// افزودن لاجیک آپلود فایل
if (dto.ImageFile != null && !string.IsNullOrEmpty(dto.ImageMime)) {
request.ImageFile = new ImageFileModel {
File = ByteString.CopyFrom(dto.ImageFile),
Mime = dto.ImageMime,
FileName = dto.ImageFileName
};
}
```
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Services/DiscountProduct/DiscountProductService.cs`
### 5. Page Integration - DiscountProductsMainPage
#### تغییرات در OpenCreateDialog و OpenEditDialog:
```csharp
var dto = new CreateDiscountProductDto {
// ... سایر فیلدها
InitialCount = 0, // تغییر: همیشه 0 - موجودی از طریق Inventory مدیریت می‌شود
ImageFile = formData.ImageFile,
ImageMime = formData.ImageMime,
ImageFileName = formData.ImageFileName,
ThumbnailFile = formData.ThumbnailFile,
ThumbnailMime = formData.ThumbnailMime,
ThumbnailFileName = formData.ThumbnailFileName
};
```
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice/src/BackOffice/Pages/DiscountShop/DiscountProductsMainPage.razor`
### 6. BFF - Validators
#### اصلاح CreateDiscountProductCommandValidator:
```csharp
// قبل: الزامی بودن ShortInformation و FullInformation
RuleFor(x => x.ShortInformation)
.NotEmpty().WithMessage("اطلاعات کوتاه محصول الزامی است")
// بعد: اختیاری شدن با چک طول
RuleFor(x => x.ShortInformation)
.MaximumLength(500)
.When(x => !string.IsNullOrEmpty(x.ShortInformation));
RuleFor(x => x.FullInformation)
.MaximumLength(10000)
.When(x => !string.IsNullOrEmpty(x.FullInformation));
```
**فایل‌ها**:
- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandValidator.cs`
- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandValidator.cs`
### 7. BFF - Command Handlers
#### اصلاح CreateDiscountProductCommandHandler:
```csharp
// افزودن null coalescing برای جلوگیری از ArgumentNullException
var createRequest = new CreateDiscountProductRequest {
ShortInfomation = request.ShortInformation ?? string.Empty,
FullInformation = request.FullInformation ?? string.Empty,
// ...
};
// افزودن لاجیک آپلود فایل به File Storage
if (request.ImageFile != null && request.ImageFile.File.Length > 0) {
var imageFileInfo = await _context.FileInfos.CreateNewFileInfoAsync(...);
if (imageFileInfo != null)
createRequest.ImagePath = imageFileInfo.File;
}
```
**فایل‌ها**:
- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandHandler.cs`
- `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandHandler.cs`
### 8. CMS - Validators
#### اصلاح CreateDiscountProductCommandValidator:
```csharp
// حذف الزامی بودن ImagePath و ThumbnailPath
// قبل:
RuleFor(v => v.ImagePath).NotEmpty()
RuleFor(v => v.ThumbnailPath).NotEmpty()
// بعد: حذف شده - فایل‌ها از طریق BFF آپلود می‌شوند
// ShortInformation و FullInformation اختیاری شدن
RuleFor(v => v.ShortInfomation)
.MaximumLength(500)
.When(v => !string.IsNullOrEmpty(v.ShortInfomation));
```
**فایل‌ها**:
- `/home/masoud/Apps/project/FourSat/CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/CreateDiscountProduct/CreateDiscountProductCommandValidator.cs`
- `/home/masoud/Apps/project/FourSat/CMS/src/CMSMicroservice.Application/DiscountShopCQ/Commands/UpdateDiscountProduct/UpdateDiscountProductCommandValidator.cs`
### 9. Bug Fixes
#### 9.1. Foreign Key Constraint Error
**مشکل**: استفاده از CategoryMultiSelectCombo که Category های عادی را لود می‌کرد، در حالی که DiscountProduct نیاز به DiscountCategory دارد.
**راه‌حل**:
- برگشت به MudSelect ساده
- لود DiscountCategory از IDiscountCategoryService
- Flatten کردن tree برای نمایش در dropdown
#### 9.2. GetDiscountProducts NullReferenceException
**مشکل**: `response.MetaData` یا `response.Models` می‌توانست null باشد.
**راه‌حل**:
```csharp
Products = response.Models?.Select(p => new DiscountProductDto {
Created = p.Created?.ToDateTime() ?? DateTime.MinValue
}).ToList() ?? new List<DiscountProductDto>()
```
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountProductCQ/Queries/GetDiscountProducts/GetDiscountProductsQueryHandler.cs`
#### 9.3. GetDiscountCategories Handler Bugs
**مشکل‌ها**:
1. `response.Categories` بدون null check
2. شرط‌های `string.IsNullOrWhiteSpace` معکوس بودند
3. `ParentCategoryId` چک نادرست
4. `node.Children` بدون null check
**راه‌حل**:
```csharp
Categories = response.Categories?.Select(MapCategory).ToList()
?? new List<DiscountCategoryTreeDto>()
// اصلاح شرط‌ها
Description = !string.IsNullOrWhiteSpace(node.Description) ? node.Description : string.Empty,
ParentCategoryId = node.ParentCategoryId != 0 ? node.ParentCategoryId : null,
ChildCategories = node.Children?.Select(MapCategory).ToList()
?? new List<DiscountCategoryTreeDto>()
```
**فایل**: `/home/masoud/Apps/project/FourSat/BackOffice.BFF/src/BackOffice.BFF.Application/DiscountCategoryCQ/Queries/GetDiscountCategories/GetDiscountCategoriesQueryHandler.cs`
## Build و Deploy
### Build Status
- ✅ BackOffice: 0 errors, 248 warnings (MudBlazor style warnings only)
- ✅ BackOffice.BFF: 0 errors
- ✅ CMS: 0 errors
### دستور Build Proto
```bash
bash /home/masoud/Apps/project/FourSat/BackOffice/build-deps.sh
```
### فایل‌های نیاز به Deploy
1. **BackOffice.BFF** (stage)
- تغییرات: Validators, Command Handlers, Query Handlers
2. **CMS** (stage)
- تغییرات: Validators
3. **BackOffice** (local)
- در حال اجرا با `dotnet watch`
- تغییرات بلافاصله اعمال می‌شود
## نتیجه نهایی
### قابلیت‌های جدید:
✅ آپلود تصویر با drag & drop
✅ پیش‌نمایش تصویر قبل از ذخیره
✅ ویرایشگر HTML برای محتوای غنی
✅ انتخاب چندگانه دسته‌بندی با UI بهتر
✅ مدیریت صحیح DiscountCategory ها
✅ حذف الزامی بودن فیلدهای اختیاری
✅ رفع تمام خطاهای NullReference
### تفاوت با قبل:
| قبل | بعد |
|-----|-----|
| TextField برای مسیر تصویر | آپلود فایل واقعی |
| TextField ساده | HTML Editor |
| CategoryMultiSelectCombo (اشتباه) | MudSelect با DiscountCategory |
| الزامی بودن توضیحات | اختیاری |
| خطای Foreign Key | حل شده |
## نکات مهم
1. **موجودی (InitialCount)**: همیشه 0 قرار می‌گیرد - موجودی باید از صفحه Inventory مدیریت شود
2. **دسته‌بندی**: حتماً DiscountCategory استفاده شود نه Category معمولی
3. **Validators**: فیلدهای اختیاری با `.When()` چک شوند
4. **Null Safety**: همیشه `??` و `?.` استفاده شود در LINQ queries
## مراجع
- Proto Guide: `/home/masoud/Apps/project/FourSat/PROTO-PACKAGING-GUIDE.md`
- Build Script: `/home/masoud/Apps/project/FourSat/BackOffice/build-deps.sh`
-164
View File
@@ -1,164 +0,0 @@
# فیچر فعالسازی (پرداخت) دستی باشگاه مشتریان
## خلاصه
این فیچر امکان فعالسازی دستی عضویت باشگاه مشتریان را برای ادمین فراهم می‌کند. ادمین می‌تواند کاربر را انتخاب کرده، تصویر فیش پرداخت را آپلود کند و عضویت را فعال کند.
## تاریخ: 2 ژانویه 2026
---
## تغییرات انجام شده
### 1. CMS (Backend)
#### Entity - `ManualPayment.cs`
- اضافه شدن فیلد `ImageDocumentId` برای ذخیره شناسه سند در FMS
```csharp
public long? ImageDocumentId { get; set; }
```
#### Proto - `manualpayment.proto`
- اضافه شدن `image_document_id` به `CreateManualPaymentRequest` (فیلد 7)
- اضافه شدن `image_document_id` به `ManualPaymentModel` (فیلد 21)
#### Command - `CreateManualPaymentCommand.cs`
- اضافه شدن پراپرتی `ImageDocumentId`
#### Handler - `CreateManualPaymentCommandHandler.cs`
- ذخیره `ImageDocumentId` از request در entity
---
### 2. BFF (Backend For Frontend)
#### Proto - `manualpayment.proto`
- اضافه شدن `image_document_id` به `ManualPaymentModel` (فیلد 21)
- اضافه شدن `FileUploadModel` برای آپلود فایل
- اضافه شدن `image_file` به `CreateManualPaymentRequest`
#### Command - `CreateManualPaymentCommand.cs`
- اضافه شدن `FileUploadDto` برای دریافت فایل از فرانت
#### Handler - `CreateManualPaymentCommandHandler.cs`
- اتصال به FMS برای آپلود فایل
- استخراج `ImagePath` و `ImageDocumentId` از پاسخ FMS
- ارسال هر دو به CMS
```csharp
var fileInfo = await _context.FileInfos.CreateNewFileInfoAsync(new()
{
Directory = "Images/ManualPayments",
IsBase64 = false,
MIME = request.ImageFile.Mime,
FileName = request.ImageFile.FileName,
File = ByteString.CopyFrom(request.ImageFile.File)
}, cancellationToken: cancellationToken);
if (fileInfo != null)
{
if (!string.IsNullOrWhiteSpace(fileInfo.File))
grpcRequest.ImagePath = fileInfo.File;
if (fileInfo.Id > 0)
grpcRequest.ImageDocumentId = fileInfo.Id;
}
```
#### Query Handler - `GetManualPaymentsQueryHandler.cs`
- اضافه شدن mapping برای `ImagePath` و `ImageDocumentId`
#### DTO - `GetManualPaymentsResponseDto.cs`
- اضافه شدن فیلدهای:
```csharp
public string? ImagePath { get; set; }
public long? ImageDocumentId { get; set; }
```
#### Mapping - `ManualPaymentProfile.cs`
- اضافه شدن mapping برای `FileUploadModel -> FileUploadDto`
---
### 3. Frontend (Blazor)
#### `ManualPaymentDialog.razor`
- استفاده از `UserAutoComplete` برای انتخاب کاربر
- استفاده از `MudFileUpload` برای آپلود تصویر فیش
- استفاده از `MudSelect` برای انتخاب نوع پرداخت
- پیش‌نمایش تصویر قبل از ارسال
- تغییر عنوان‌ها از "پرداخت دستی" به "فعالسازی دستی"
#### `ManualPaymentDialog.razor.cs`
- هندل کردن انتخاب فایل با `IBrowserFile`
- تبدیل فایل به Base64 برای پیش‌نمایش
- ایجاد `FileUploadModel` برای ارسال به BFF
- مقادیر پیش‌فرض:
- `Type = 1` (واریز نقدی)
- `Description = "عضویت دستی باشگاه مشتریان"`
#### `ManualPayments.razor`
- تغییر عنوان صفحه به "فعالسازی (پرداخت) دستی"
- تغییر دکمه به "ثبت فعالسازی دستی جدید"
#### `NavMenu.razor`
- حذف آیتم منوی "پرداخت دستی عضویت"
- تغییر نام "پرداخت‌های دستی" به "فعالسازی (پرداخت) دستی"
#### حذف شده
- `ManualMembershipPayment.razor` و `ManualMembershipPayment.razor.cs`
---
## مقادیر ثابت
```csharp
// مبلغ پایه پکیج: 56 میلیون ریال
SystemConstants.BasePackageAmount = 56_000_000;
// شارژ کیف پول:
// - مجموع شارژ: 56M ریال
```
---
## فلو کامل
1. ادمین کاربر را با `UserAutoComplete` انتخاب می‌کند
2. نوع پرداخت را انتخاب می‌کند (پیش‌فرض: واریز نقدی)
3. توضیحات را وارد می‌کند (پیش‌فرض: عضویت دستی باشگاه مشتریان)
4. تصویر فیش را آپلود می‌کند (اختیاری)
5. دکمه ثبت را می‌زند
6. Frontend فایل را به BFF ارسال می‌کند
7. BFF فایل را به FMS آپلود می‌کند
8. FMS مسیر فایل (`File`) و شناسه سند (`Id`) را برمی‌گرداند
9. BFF هر دو را به CMS ارسال می‌کند
10. CMS تراکنش، پرداخت دستی و لاگ کیف پول را ثبت می‌کند
11. کیف پول کاربر شارژ می‌شود
---
## فایل‌های تغییر یافته
### CMS
- `CMSMicroservice.Domain/Entities/Payment/ManualPayment.cs`
- `CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommand.cs`
- `CMSMicroservice.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs`
- `Protos/manualpayment.proto`
### BFF
- `BackOffice.BFF.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommand.cs`
- `BackOffice.BFF.Application/ManualPaymentCQ/Commands/CreateManualPayment/CreateManualPaymentCommandHandler.cs`
- `BackOffice.BFF.Application/ManualPaymentCQ/Queries/GetManualPayments/GetManualPaymentsQueryHandler.cs`
- `BackOffice.BFF.Application/ManualPaymentCQ/Queries/GetManualPayments/GetManualPaymentsResponseDto.cs`
- `BackOffice.BFF.Application/ManualPaymentCQ/ManualPaymentProfile.cs`
- `Protobufs/BackOffice.BFF.ManualPayment.Protobuf/Protos/manualpayment.proto`
### Frontend
- `BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor`
- `BackOffice/Pages/Payment/Components/ManualPaymentDialog.razor.cs`
- `BackOffice/Pages/Payment/ManualPayments.razor`
- `BackOffice/Shared/NavMenu.razor`
### حذف شده
- `BackOffice.Main/Pages/Payment/ManualMembershipPayment.razor`
- `BackOffice.Main/Pages/Payment/ManualMembershipPayment.razor.cs`
+1
View File
@@ -0,0 +1 @@
Docs moved to /totalDoc — see totalDoc/INDEX.md
-28
View File
@@ -1,28 +0,0 @@
# ⚠️ توجه: مستندات اصلی منتقل شده
مستندات اصلی پروژه در فولدر زیر قرار دارند:
```
/home/masoud/Apps/project/FourSat/totalDoc/
```
## 🗂️ ساختار اصلی مستندات:
- **00-INDEX.md** - فهرست جامع مستندات
- **QUICK-REFERENCE.md** - مرجع سریع
- **FINAL-STATUS.md** - وضعیت نهایی پروژه
- **CHANGELOG-2025-12-XX.md** - لاگ تغییرات روزانه
- **01-BUSINESS/** - منطق تجاری
- **02-ARCHITECTURE/** - معماری سیستم
- **03-BACKEND/** - مستندات Backend (CMS, BFF)
- **04-FRONTEND/** - مستندات Frontend (BackOffice, FrontOffice)
- **05-TASKS/** - کارهای جاری
- **06-DEPLOYMENT/** - راهنمای استقرار
## 📝 این پوشه:
فایل‌های این پوشه (`BackOffice/docs/`) برای مرجع محلی نگه داشته شده‌اند ولی **مستندات اصلی و به‌روز** در `totalDoc` قرار دارند.
---
**تاریخ**: ۳۰ آذر ۱۴۰۴ (20 December 2025)
-34
View File
@@ -1,34 +0,0 @@
# BackOffice Documentation - README
> آخرین بروزرسانی: **December 20, 2025**
## فایل‌های این پوشه
| فایل | شرح |
|------|-----|
| `STATUS.md` | وضعیت کلی پروژه و Build Status |
| `CHANGELOG.md` | تاریخچه تغییرات به ترتیب تاریخ |
| `TECHNICAL-NOTES.md` | نکات فنی، Mapster، MudBlazor، Proto |
| `development-plan.md` | برنامه توسعه (قدیمی - برای مرجع) |
---
## وضعیت فعلی
```
✅ Build Status: SUCCESS (0 Errors)
✅ Proto Projects: 24 فعال
✅ صفحات فعال: 40+
✅ Excluded Files: 0
```
## دستورات سریع
```bash
# Build همه
cd /home/masoud/Apps/project/FourSat/BackOffice/src
dotnet build BackOffice.sln
# فقط UI
dotnet build BackOffice/BackOffice.csproj
```
-412
View File
@@ -1,412 +0,0 @@
# کارهای باقیمانده - BackOffice
> آخرین بروزرسانی: January 1, 2026
## وضعیت کلی
**Build Status**: ✅ SUCCESS (0 Errors)
**Enabled Modules**: 12+ ماژول کامل
**System Status**: **PRODUCTION READY** 🚀
---
## ✅ کارهای انجام شده - Session January 1, 2026
### فعال‌سازی ماژول‌های فروشگاه تخفیفی (DiscountShop Frontend)
**وضعیت**: ✅ COMPLETED - همه چیز فعال و build موفق
**فایل اصلی تغییر یافته**:
- `BackOffice/Common/Configure/ConfigureService.cs`
**تغییرات**:
#### 1. Using Statements فعال شدند:
```csharp
// Discount Shop Proto Clients
using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct;
using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory;
using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder;
using BackOffice.BFF.Tag.Protobuf.Protos.Tag;
using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag;
using Foursat.BackOffice.BFF.PublicMessage.Protobuf;
// Application Services
using BackOffice.Services.DiscountProduct;
using BackOffice.Services.DiscountCategory;
using BackOffice.Services.DiscountOrder;
using BackOffice.Services.PublicMessage;
using BackOffice.Services.Tag;
```
#### 2. gRPC Clients فعال شدند:
```csharp
// Discount Shop Services
services.AddTransient(sp => new DiscountProductContract.DiscountProductContractClient(...));
services.AddTransient(sp => new DiscountCategoryContract.DiscountCategoryContractClient(...));
services.AddTransient(sp => new DiscountOrderContract.DiscountOrderContractClient(...));
// Public Message Service
services.AddTransient(sp => new PublicMessageContract.PublicMessageContractClient(...));
// Tag Management Services
services.AddTransient(sp => new TagContract.TagContractClient(...));
services.AddTransient(sp => new ProductTagContract.ProductTagContractClient(...));
```
#### 3. Application Services فعال شدند:
```csharp
services.AddScoped<IDiscountProductService, DiscountProductService>();
services.AddScoped<IDiscountCategoryService, DiscountCategoryService>();
services.AddScoped<IDiscountOrderService, DiscountOrderService>();
services.AddScoped<IPublicMessageService, PublicMessageService>();
services.AddScoped<ITagService, TagService>();
```
### صفحات فعال شده:
| صفحه | Route | توضیحات |
|------|-------|---------|
| مدیریت محصولات تخفیفی | `/discount-products` | CRUD + گالری تصاویر |
| مدیریت دسته‌بندی‌ها | `/discount-categories` | CRUD + سلسله‌مراتب |
| مدیریت سفارشات | `/discount-orders` | مشاهده + تغییر وضعیت |
| گزارش فروش | `/sales-reports` | آمار و نمودار |
| مدیریت تگ‌ها | `/tags` | CRUD تگ‌ها |
| پیام‌های عمومی | `/public-messages` | CRUD + انتشار |
---
## ✅ کارهای انجام شده - Session December 20, 2025
### 1. صفحه `/network/balances` - ✅ FIXED
**مشکل**: ValidationException هنگام لود صفحه
**راه‌حل**: اضافه کردن Mapster mapping برای `GetUserWeeklyBalancesRequest``GetUserWeeklyBalancesQuery`
**فایل تغییر یافته**:
- `BackOffice.BFF/WebApi/Common/Mappings/CommissionProfile.cs`
```csharp
config.NewConfig<GetUserWeeklyBalancesRequest, GetUserWeeklyBalancesQuery>()
.Map(dest => dest.PaginationState, src => src.PaginationState);
```
### 2. صفحه `/club/members` - ✅ FIXED
**مشکل**: داده‌ها لود نمی‌شدند (Mapster mapping نداشت)
**راه‌حل**: ایجاد ClubMembershipProfile در CMS و BFF
**فایل‌های جدید**:
- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs` (NEW)
- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` (REWRITTEN)
**Mappings اضافه شده**:
- `GetAllClubMembershipsRequest``GetAllClubMembershipsQuery`
- `GetAllClubMembershipsResponseDto``GetAllClubMembershipsResponse`
### 3. صفحه `/club/statistics` - ✅ FIXED
**مشکل**: خطای `Status(StatusCode="Unimplemented")`
**راه‌حل**: پیاده‌سازی متد gRPC در BFF و اضافه کردن mappings
**فایل‌های تغییر یافته**:
- `BackOffice.BFF/WebApi/Services/ClubMembershipService.cs` - اضافه شدن `GetClubStatistics` override
- `CMS/WebApi/Common/Mappings/ClubMembershipProfile.cs` - اضافه شدن mappings
- `BackOffice.BFF/WebApi/Common/Mappings/ClubMembershipProfile.cs` - اضافه شدن mappings
**Mappings اضافه شده**:
- `GetClubStatisticsRequest``GetClubStatisticsQuery`
- `GetClubStatisticsResponseDto``GetClubStatisticsResponse`
- PackageDistribution و MonthlyTrend mappings
### 4. صفحه Products - ✅ ALL FEATURES ENABLED
**مشکل**: همه قابلیت‌ها disabled بودند و "در حال توسعه" نشان می‌دادند
**راه‌حل**: Uncomment کردن کدهای دیالوگ‌ها
**فایل تغییر یافته**:
- `BackOffice/Pages/Products/ProductsMainPage.razor.cs`
**قابلیت‌های فعال شده**:
-`CreateNew()` - ایجاد محصول جدید
-`Update()` - ویرایش محصول
-`OpenGallery()` - گالری تصاویر
-`OpenTagAssignment()` - اختصاص تگ
### 5. فیلد "تعداد موجودی" در Products - ✅ ADDED
**مشکل**: فیلد RemainingCount در فرم‌ها و لیست نبود
**راه‌حل**: اضافه کردن فیلد به همه لایه‌ها
**فایل‌های تغییر یافته**:
- `BackOffice/Pages/Products/Components/CreateDialog.razor` - اضافه شدن فیلد موجودی
- `BackOffice/Pages/Products/Components/UpdateDialog.razor` - اضافه شدن فیلد موجودی
- `BackOffice/Pages/Products/ProductsMainPage.razor` - اضافه شدن ستون موجودی با رنگ‌بندی
- `BackOffice.BFF.Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommand.cs` - اضافه شدن `RemainingCount`
- `BackOffice.BFF.Application/ProductsCQ/Commands/UpdateProducts/UpdateProductsCommand.cs` - اضافه شدن `RemainingCount`
**نمایش موجودی در لیست**:
- 🔴 **ناموجود** - اگر موجودی `0` یا کمتر (Chip قرمز)
- 🟡 **عدد** - اگر موجودی کمتر از `10` (Chip زرد - هشدار)
- 🟢 **عدد** - اگر موجودی `10` یا بیشتر (Chip سبز)
---
## ✅ کارهای انجام شده قبلی
### 1. BulkEdit Module - COMPLETED ✅
- ✅ حذف dependency به CMSMicroservice
- ✅ استفاده از BackOffice.BFF.Products.Protobuf
- ✅ تصحیح PaginationState namespace issue
- ✅ فایل فعال شد و build موفق
### 2. Product Image Management - Proto COMPLETED ✅
- ✅ تعریف ImageFileModel message
- ✅ اضافه کردن GetProductGallery RPC
- ✅ اضافه کردن AddProductImage RPC
- ✅ اضافه کردن RemoveProductImage RPC
- ✅ اضافه کردن ImageFile و ThumbnailFile به Create/Update requests
- ✅ هر 3 دیالوگ فعال شدند و build موفق
**فایل‌های Enabled**:
- `Pages/Products/Components/GalleryDialog.razor`
- `Pages/Products/Components/CreateDialog.razor`
- `Pages/Products/Components/UpdateDialog.razor`
---
## 🔴 کارهای باقیمانده (Backend Only)
### 1. Product Image Management - Backend Implementation
**اولویت**: بالا
**وضعیت**: ✅ COMPLETED - همه چیز آماده!
**آخرین تغییرات**:
- ✅ ProductsService.cs: همه methods فعال شدند (AddProductImage, GetProductGallery, RemoveProductImage)
- ✅ Application Layer: CQRS handlers از قبل پیاده‌سازی شده‌اند
- ✅ CMS Integration: ProductGalleries microservice متصل است
- ✅ Image Optimization: 1200x1200 main + 300x300 thumbnail ready
#### Proto Messages (✅ Ready):
```protobuf
// Image file model
message ImageFileModel {
bytes file = 1;
string mime = 2;
string file_name = 3;
}
// Get Product Gallery
rpc GetProductGallery(GetProductGalleryRequest) returns (GetProductGalleryResponse);
message GetProductGalleryRequest {
int64 product_id = 1;
}
message ProductGalleryItem {
int64 product_gallery_id = 1;
int64 product_image_id = 2;
string title = 3;
string image_path = 4;
string image_thumbnail_path = 5;
}
message GetProductGalleryResponse {
repeated ProductGalleryItem items = 1;
}
// Add Product Image
rpc AddProductImage(AddProductImageRequest) returns (AddProductImageResponse);
message AddProductImageRequest {
int64 product_id = 1;
string title = 2;
ImageFileModel image_file = 3;
}
message AddProductImageResponse {
int64 product_gallery_id = 1;
int64 product_image_id = 2;
string title = 3;
string image_path = 4;
string image_thumbnail_path = 5;
}
// Remove Product Image
rpc RemoveProductImage(RemoveProductImageRequest) returns (google.protobuf.Empty);
message RemoveProductImageRequest {
int64 product_gallery_id = 1;
}
```
#### Backend Implementation Steps:
1. **افزودن Messages به Proto** ✅ (فقط تعریف)
2. **پیاده‌سازی RPCs در Backend**:
- AddProductImage: دریافت فایل، ذخیره در storage، ثبت در DB
- RemoveProductImage: حذف فایل از storage و DB
- CreateProductWithImage: ایجاد محصول + آپلود تصاویر
- UpdateProductWithImage: ویرایش محصول + آپلود تصاویر (اختیاری)
3. **File Storage**:
- پیشنهاد: MinIO, Azure Blob, یا local file system
- ذخیره تصویر اصلی و thumbnail
- برگرداندن URL های قابل دسترسی
4. **تست و Enable فایل‌ها در UI**
**زمان تخمینی**: 2-3 روز کاری
---
### 2. BulkEdit Backend Implementation (اختیاری)
**اولویت**: پایین
**وضعیت**: ✅ UI کامل، Backend موجود و کار می‌کند
**نکته**: BulkEdit از RPCهای موجود استفاده می‌کند:
- `BulkUpdateProductPricesAsync`
- `BulkUpdateProductStockAsync`
- `ToggleProductStatusAsync`
همه چیز آماده و کار می‌کند! فقط نیاز به تست دارد.
---
### 3. Transactions API Implementation
**اولویت**: پایین
**وضعیت**: UI آماده، API نیاز به پیاده‌سازی
#### فایل:
- `Pages/Payment/Transactions.razor` - ✅ Enabled اما TODO
#### وضعیت فعلی:
```csharp
private async Task<GridData<TransactionModel>> LoadData(GridState<TransactionModel> state)
{
// TODO: Connect to BackOffice.BFF Transactions when API is ready
await Task.CompletedTask;
return new GridData<TransactionModel>
{
Items = Array.Empty<TransactionModel>(),
TotalItems = 0
};
}
```
#### نیاز:
- ایجاد Transaction proto در BackOffice.BFF
- پیاده‌سازی GetTransactions RPC
- اتصال UI به API
**زمان تخمینی**: 1 روز کاری
---
## 📊 آمار پیشرفت
### Modules Status:
| Module | Status | Files | Notes |
|--------|--------|-------|-------|
| DiscountShop | ✅ Complete | 10+ | Products, Categories, Orders, Reports |
| PublicMessages | ✅ Complete | 4 | CRUD + Templates |
| ManualPayments | ✅ Complete | 2 | Create, Approve, Reject |
| Tag Management | ✅ Complete | 3 | CRUD Tags |
| Dashboard Widget | ✅ Complete | 1 | DiscountShop Stats |
| Transactions | ⚠️ Partial | 1 | UI ready, API TODO |
| DragDrop Pages | ✅ Complete | 2 | Category ↔ Products |
| **BulkEdit** | ✅ Complete | 1 | Fully working! |
| **Product Images** | ✅ Complete | 3 | Backend FULLY implemented! |
### Overall Progress:
- **Enabled**: 38+ صفحه و کامپوننت ✅
- **Blocked**: 0 فایل ✅
- **Proto Projects**: 14 فعال
- **Build Errors**: 0 ✅
- **UI Completion**: 100% 🎉
- **Backend Implementation**: 100% ✅✅✅
- **System Status**: FULLY OPERATIONAL 🚀
---
## 🎯 Next Steps
### ✅ ALL TASKS COMPLETED!
**BackOffice System Status**: **PRODUCTION READY** 🚀
**آماده برای استفاده**:
---
## 📝 نکات مهم
### ⚠️ CRITICAL: Proto Package Management
**هر بار که Proto تغییر می‌کند (در هر سرویسی):**
```bash
# 1. افزایش Version در csproj
<Version>X.Y.Z</Version> → <Version>X.Y.Z+1</Version>
# 2. Pack کردن
cd path/to/proto/project
dotnet pack -c Release # Auto-push به GitLab
# 3. Update در لایه بالاتر
<PackageReference Include="PackageName" Version="NEW_VERSION" />
```
**این قانون برای همه سرویس‌ها صادق است:**
- CMS → BFF ها
- BackOffice.BFF → BackOffice UI
- FrontOffice.BFF → FrontOffice UI
**⚠️ عدم رعایت = ساعت‌ها Debug بیهوده!**
---
### برای Backend Developer:
1. **Image Upload**:
- استفاده از streaming برای فایل‌های بزرگ
- اعتبارسنجی نوع و سایز فایل
- تولید thumbnail خودکار
- مدیریت storage (MinIO recommended)
2. **Bulk Update**:
- استفاده از Transaction برای atomicity
- مدیریت concurrent updates
- Logging تغییرات برای audit
3. **Security**:
- اعتبارسنجی سمت سرور
- محدودیت سایز فایل
- sanitize file names
### برای Frontend Developer:
1. **Image Upload**:
- Progress indicator
- Preview قبل از upload
- مدیریت خطاها
- Retry mechanism
2. **BulkEdit**:
- Confirmation قبل از تغییرات
- نمایش نتایج
- Undo capability (آینده)
---
## 🔗 Related Docs
- [BUILD-FIX-STATUS.md](./BUILD-FIX-STATUS.md) - وضعیت کلی build
- [EXCLUDED-FILES.md](./EXCLUDED-FILES.md) - لیست فایل‌های exclude
- [PROTO-DEPENDENCIES.md](./PROTO-DEPENDENCIES.md) - وابستگی‌های proto
---
**Last Updated**: December 6, 2025
**By**: GitHub Copilot (Claude Sonnet 4.5)
-311
View File
@@ -1,311 +0,0 @@
# Session Log - December 20, 2025
## خلاصه Session
این session شامل رفع چندین باگ در صفحات BackOffice و فعال‌سازی قابلیت‌های Products بود.
---
## 1. فیکس صفحه `/network/balances`
### مشکل
```
ValidationException هنگام لود صفحه بالانس‌های هفتگی
```
### علت
Mapster mapping برای تبدیل `GetUserWeeklyBalancesRequest` به `GetUserWeeklyBalancesQuery` وجود نداشت.
### راه‌حل
اضافه کردن mapping در `CommissionProfile.cs`:
```csharp
// File: BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/CommissionProfile.cs
config.NewConfig<GetUserWeeklyBalancesRequest, GetUserWeeklyBalancesQuery>()
.Map(dest => dest.PaginationState, src => src.PaginationState);
```
---
## 2. فیکس صفحه `/club/members`
### مشکل
```
صفحه لود می‌شد ولی هیچ داده‌ای نمایش نمی‌داد
```
### علت
Mapster mappings در CMS و BFF برای `GetAllClubMemberships` وجود نداشتند.
### راه‌حل
ایجاد `ClubMembershipProfile.cs` در هر دو لایه:
**CMS/src/CMSMicroservice.WebApi/Common/Mappings/ClubMembershipProfile.cs** (NEW):
```csharp
public class ClubMembershipProfile : IRegister
{
void IRegister.Register(TypeAdapterConfig config)
{
// GetAllClubMemberships mappings
config.NewConfig<GetAllClubMembershipsRequest, GetAllClubMembershipsQuery>()
.Map(dest => dest.PaginationState, src => src.PaginationState)
.Map(dest => dest.Filter, src => src.Filter);
config.NewConfig<GetAllClubMembershipsResponseDto, GetAllClubMembershipsResponse>()
.MapWith(src => new GetAllClubMembershipsResponse
{
MetaData = src.MetaData != null ? new CMSMicroservice.Protobuf.Common.MetaData
{
PageIndex = src.MetaData.PageIndex,
TotalPages = src.MetaData.TotalPages,
TotalCount = src.MetaData.TotalCount
} : null,
Models = { src.Models?.Select(...) ?? Enumerable.Empty<...>() }
});
}
}
```
**BackOffice.BFF/src/BackOffice.BFF.WebApi/Common/Mappings/ClubMembershipProfile.cs** (REWRITTEN):
- Mapping از BFF Proto به Query
- Mapping از CMS Response به BFF Proto Response
- استفاده از alias imports برای disambiguation
---
## 3. فیکس صفحه `/club/statistics`
### مشکل
```
Status(StatusCode="Unimplemented", Detail="Method cms.ClubMembershipContract/GetClubStatistics is unimplemented")
```
### علت
متد `GetClubStatistics` در BFF Service override نشده بود.
### راه‌حل
**1. اضافه کردن override در ClubMembershipService.cs:**
```csharp
public override async Task<GetClubStatisticsResponse> GetClubStatistics(
GetClubStatisticsRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetClubStatisticsRequest, GetClubStatisticsQuery, GetClubStatisticsResponse>(request, context);
}
```
**2. اضافه کردن mappings در CMS ClubMembershipProfile:**
```csharp
config.NewConfig<GetClubStatisticsRequest, GetClubStatisticsQuery>();
config.NewConfig<GetClubStatisticsResponseDto, GetClubStatisticsResponse>()
.MapWith(src => new GetClubStatisticsResponse
{
TotalMembers = src.TotalMembers,
ActiveMembers = src.ActiveMembers,
// ... سایر فیلدها
PackageDistribution = { src.PackageDistribution?.Select(...) },
MonthlyTrend = { src.MonthlyTrend?.Select(...) }
});
```
**3. اضافه کردن mappings در BFF ClubMembershipProfile:**
- Mapping از BFF Proto به Query
- Mapping از CMS Response DTO به BFF Proto Response
---
## 4. فعال‌سازی قابلیت‌های Products
### مشکل
```
همه دکمه‌های صفحه محصولات "در حال توسعه" نشان می‌دادند
```
### علت
کدهای دیالوگ‌ها comment شده بودند با TODO markers.
### راه‌حل
Uncomment کردن کدها در `ProductsMainPage.razor.cs`:
**فایل: BackOffice/src/BackOffice/Pages/Products/ProductsMainPage.razor.cs**
```csharp
// ✅ CreateNew() - فعال شد
public async Task CreateNew()
{
var dialog = await DialogService.ShowAsync<CreateDialog>("افزودن محصول",
new DialogParameters<CreateDialog> { { x => x.Model, new CreateNewProductsRequest() } },
new DialogOptions { CloseButton = true, FullWidth = true, MaxWidth = MaxWidth.Small });
// ...
}
// ✅ Update() - فعال شد
public async Task Update(DataModel model)
{
var parameters = new DialogParameters<UpdateDialog> { { x => x.Model, model.Adapt<UpdateProductsRequest>() } };
var dialog = await DialogService.ShowAsync<UpdateDialog>("ویرایش محصول", parameters, ...);
// ...
}
// ✅ OpenGallery() - فعال شد
public async Task OpenGallery(DataModel model)
{
var parameters = new DialogParameters<GalleryDialog>
{
{ x => x.ProductId, model.Id },
{ x => x.ProductTitle, model.Title }
};
await DialogService.ShowAsync<GalleryDialog>("گالری تصاویر", parameters, ...);
}
// ✅ OpenTagAssignment() - فعال شد
public async Task OpenTagAssignment(DataModel model)
{
var parameters = new DialogParameters<AssignTagsDialog>
{
{ x => x.ProductId, model.Id },
{ x => x.ProductTitle, model.Title }
};
await DialogService.ShowAsync<AssignTagsDialog>("مدیریت تگ‌های محصول", parameters, ...);
}
```
**Using statement uncomment شد:**
```csharp
using BackOffice.Pages.Tag.Components; // برای AssignTagsDialog
```
---
## 5. اضافه کردن فیلد "تعداد موجودی" به Products
### نیاز
نمایش و ویرایش تعداد موجودی محصول در فرم‌ها و لیست
### تغییرات
**1. فرم‌های دیالوگ (CreateDialog.razor & UpdateDialog.razor):**
```razor
<MudStack Row="true" AlignItems="AlignItems.Center">
<MudItem xs="6">
<MudNumericField T="int" HideSpinButtons="true" @bind-Value="Model.Discount"
Disabled="_isLoading" Label="تخفیف (%)" Variant="Variant.Outlined" Margin="Margin.Dense" />
</MudItem>
<MudItem xs="6">
<MudNumericField T="int" HideSpinButtons="true" @bind-Value="Model.RemainingCount"
Disabled="_isLoading" Label="تعداد موجودی" Variant="Variant.Outlined" Margin="Margin.Dense" />
</MudItem>
</MudStack>
```
**2. ستون جدید در لیست (ProductsMainPage.razor):**
```razor
<TemplateColumn Title="موجودی" CellStyle="text-wrap: nowrap;">
<CellTemplate>
@if (context.Item.RemainingCount <= 0)
{
<MudChip T="string" Color="Color.Error" Size="Size.Small">ناموجود</MudChip>
}
else if (context.Item.RemainingCount < 10)
{
<MudChip T="string" Color="Color.Warning" Size="Size.Small">@context.Item.RemainingCount</MudChip>
}
else
{
<MudChip T="string" Color="Color.Success" Size="Size.Small">@context.Item.RemainingCount</MudChip>
}
</CellTemplate>
</TemplateColumn>
```
**3. اضافه کردن فیلد به BFF Commands (فیکس مهم!):**
مشکل: فیلد `RemainingCount` در BFF Application Commands نبود و باعث می‌شد مقدار ارسال/دریافت نشه.
**CreateNewProductsCommand.cs:**
```csharp
public int Discount { get; init; }
public int Rate { get; init; }
public int RemainingCount { get; init; } // ← اضافه شد
public ImageFileModel ImageFile { get; init; }
```
**UpdateProductsCommand.cs:**
```csharp
public int Discount { get; init; }
public int Rate { get; init; }
public int RemainingCount { get; init; } // ← اضافه شد
public string ImagePath { get; init; }
```
---
## لیست کامل فایل‌های تغییر یافته
### BackOffice.BFF
| فایل | نوع تغییر | توضیح |
|------|----------|-------|
| `WebApi/Common/Mappings/CommissionProfile.cs` | MODIFIED | اضافه شدن mapping برای GetUserWeeklyBalances |
| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | REWRITTEN | Mappings کامل برای ClubMembership |
| `WebApi/Services/ClubMembershipService.cs` | MODIFIED | اضافه شدن GetClubStatistics override |
| `Application/ProductsCQ/Commands/CreateNewProducts/CreateNewProductsCommand.cs` | MODIFIED | اضافه شدن RemainingCount |
| `Application/ProductsCQ/Commands/UpdateProducts/UpdateProductsCommand.cs` | MODIFIED | اضافه شدن RemainingCount |
### CMS
| فایل | نوع تغییر | توضیح |
|------|----------|-------|
| `WebApi/Common/Mappings/ClubMembershipProfile.cs` | NEW | Mappings برای ClubMembership |
### BackOffice UI
| فایل | نوع تغییر | توضیح |
|------|----------|-------|
| `Pages/Products/ProductsMainPage.razor.cs` | MODIFIED | فعال‌سازی CreateNew, Update, OpenGallery, OpenTagAssignment |
| `Pages/Products/ProductsMainPage.razor` | MODIFIED | اضافه شدن ستون موجودی |
| `Pages/Products/Components/CreateDialog.razor` | MODIFIED | اضافه شدن فیلد موجودی |
| `Pages/Products/Components/UpdateDialog.razor` | MODIFIED | اضافه شدن فیلد موجودی |
---
## نکات فنی مهم
### 1. Mapster با Proto Types
برای proto types که immutable هستند، باید از `MapWith` استفاده کرد:
```csharp
config.NewConfig<SourceDto, ProtoResponse>()
.MapWith(src => new ProtoResponse
{
Field1 = src.Field1,
RepeatedField = { src.List?.Select(...) ?? Enumerable.Empty<...>() }
});
```
### 2. Alias Imports برای Proto Disambiguation
وقتی دو proto با اسم یکسان داریم:
```csharp
using BffProtos = BackOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership;
using CmsProtos = CMSMicroservice.Protobuf.Protos.ClubMembership;
```
### 3. Null-Safe MetaData Mapping
```csharp
MetaData = src.MetaData != null ? new MetaData
{
PageIndex = src.MetaData.PageIndex,
TotalPages = src.MetaData.TotalPages,
TotalCount = src.MetaData.TotalCount
} : null
```
---
## Build Status پایان Session
```
BackOffice.BFF: ✅ Build succeeded (0 errors)
CMS: ✅ Build succeeded (0 errors)
BackOffice UI: ✅ Build succeeded (0 errors)
```
@@ -1,289 +0,0 @@
# Session 2026-01-03: Proto DLL Migration & Domain Changes
> **تاریخ**: January 3, 2026
> **موضوع**: مایگریشن به DLL-based Proto References + تغییر دامنه‌ها
---
## 📋 خلاصه تغییرات
### 1. ✅ مایگریشن Proto References به DLL-based Approach
**مشکل**: در CI/CD نمی‌توانستیم از `ProjectReference` به پروژه‌های proto در `BackOffice.BFF` استفاده کنیم چون ریپوها جدا هستند.
**راه‌حل**: ایجاد سیستم hybrid با DLL های pre-built:
#### فایل‌های ایجاد شده:
1. **`BackOffice/build-deps.sh`**:
```bash
#!/bin/bash
# Build all BFF proto dependencies and copy DLLs to libs folder
# Builds all 24 proto projects from BackOffice.BFF/src/Protobufs/
# Copies DLLs to BackOffice/libs/ folder
# Supports both net8.0 and net9.0 target frameworks
```
2. **`BackOffice/libs/`**: فولدر شامل 24 فایل DLL:
- `BackOffice.BFF.Category.Protobuf.dll`
- `BackOffice.BFF.ClubMembership.Protobuf.dll`
- `BackOffice.BFF.Commission.Protobuf.dll`
- `BackOffice.BFF.Common.Protobuf.dll`
- `BackOffice.BFF.Configuration.Protobuf.dll`
- `BackOffice.BFF.DiscountCategory.Protobuf.dll`
- `BackOffice.BFF.DiscountOrder.Protobuf.dll`
- `BackOffice.BFF.DiscountProduct.Protobuf.dll`
- `BackOffice.BFF.DiscountShoppingCart.Protobuf.dll`
- `BackOffice.BFF.Health.Protobuf.dll`
- `BackOffice.BFF.Inventory.Protobuf.dll`
- `BackOffice.BFF.ManualPayment.Protobuf.dll`
- `BackOffice.BFF.NetworkMembership.Protobuf.dll`
- `BackOffice.BFF.Otp.Protobuf.dll`
- `BackOffice.BFF.Package.Protobuf.dll`
- `BackOffice.BFF.Products.Protobuf.dll`
- `BackOffice.BFF.ProductTag.Protobuf.dll`
- `BackOffice.BFF.PublicMessage.Protobuf.dll` ⚠️ (net8.0)
- `BackOffice.BFF.Role.Protobuf.dll`
- `BackOffice.BFF.Tag.Protobuf.dll`
- `BackOffice.BFF.User.Protobuf.dll`
- `BackOffice.BFF.UserAddress.Protobuf.dll`
- `BackOffice.BFF.UserOrder.Protobuf.dll`
- `BackOffice.BFF.UserRole.Protobuf.dll`
#### تغییرات در `BackOffice/src/BackOffice/BackOffice.csproj`:
**PackageReferences اضافه شده** (برای transitive dependencies):
```xml
<!-- Proto dependencies (needed when using DLL references) -->
<PackageReference Include="Google.Protobuf" Version="3.28.3"/>
<PackageReference Include="Grpc.Core.Api" Version="2.71.0"/>
<PackageReference Include="Google.Api.CommonProtos" Version="2.10.0"/>
<PackageReference Include="FluentValidation" Version="11.2.2"/>
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="11.2.2"/>
```
**Conditional ItemGroups**:
```xml
<!-- CI/CD Mode: Use pre-built DLLs from libs/ folder -->
<ItemGroup Condition="Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')">
<Reference Include="BackOffice.BFF.Common.Protobuf">
<HintPath>../../libs/BackOffice.BFF.Common.Protobuf.dll</HintPath>
</Reference>
<!-- ... all 24 proto DLLs ... -->
</ItemGroup>
<!-- Development Mode: Fallback to ProjectReference if libs/ doesn't exist -->
<ItemGroup Condition="!Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')">
<ProjectReference Include="..\..\..\BackOffice.BFF\src\Protobufs\BackOffice.BFF.Common.Protobuf\BackOffice.BFF.Common.Protobuf.csproj"/>
<!-- ... all 24 proto projects ... -->
</ItemGroup>
```
#### تغییرات در `BackOffice/Dockerfile`:
```dockerfile
# Copy pre-built proto DLLs
COPY ["libs/", "libs/"]
```
#### مشکلات حل شده:
1. **Google.Protobuf Version Conflict**:
- مشکل: `PublicMessage.Protobuf` از ورژن `3.28.3` استفاده می‌کرد ولی بقیه از `3.23.3`
- راه‌حل: آپگرید به `3.28.3` در `BackOffice.csproj`
2. **Grpc.Core.Api Version Conflict**:
- مشکل: Downgrade از `2.71.0` به `2.54.0`
- راه‌حل: تنظیم explicit version `2.71.0` در `BackOffice.csproj`
3. **PublicMessage.Protobuf Missing**:
- مشکل: این پروژه `net8.0` است نه `net9.0`
- راه‌حل: اسکریپت `build-deps.sh` حالا هر دو framework را چک می‌کند
### نتیجه:
✅ **Build: SUCCESS** (0 Errors, 246 Warnings - فقط MudBlazor)
✅ **Publish: SUCCESS** - همه 24 proto assembly به WASM کامپایل شدند
✅ **CI/CD Ready**: می‌توان با `./build-deps.sh` قبل از build، DLL ها را آماده کرد
---
## 2. ✅ تغییر دامنه‌ها (Domain Migration)
### تغییر از `*.foursat.afrino.co` به `*.se.kbs1.ir`
**دستور اجرا شده**:
```bash
cd /home/masoud/Apps/project/FourSat
find . -type f \( -name "*.json" -o -name "*.yml" -o -name "*.yaml" \) \
-exec sed -i 's/foursat\.afrino\.co/se.kbs1.ir/g' {} \;
```
#### فایل‌های تغییر یافته:
**Workflow Files** (`.gitea/workflows/*.yml`):
- `BackOffice/.gitea/workflows/prod-deploy.yml`
- `BackOffice/.gitea/workflows/kub-deploy.yml`
- `BackOffice.BFF/.gitea/workflows/prod-deploy.yml`
- `BackOffice.BFF/.gitea/workflows/kub-deploy.yml`
- `FrontOffice/.gitea/workflows/prod-deploy.yml`
- `FrontOffice/.gitea/workflows/kub-deploy.yml`
- `FrontOffice.BFF/.gitea/workflows/prod-deploy.yml`
- `FrontOffice.BFF/.gitea/workflows/kub-deploy.yml`
- `CMS/.gitea/workflows/prod-deploy.yml`
- `CMS/.gitea/workflows/kub-deploy.yml`
**تغییرات در Workflows**:
```yaml
# قبل:
EXTERNAL_REGISTRY: git.foursat.afrino.co
"insecure-registries": ["git.foursat.afrino.co", "gitea-svc:3000"]
# بعد:
EXTERNAL_REGISTRY: git.se.kbs1.ir
"insecure-registries": ["git.se.kbs1.ir", "gitea-svc:3000"]
```
**Configuration Files** (appsettings):
- `BackOffice/src/BackOffice/wwwroot/appsettings.json`
- `BackOffice/src/BackOffice/wwwroot/appsettings.Staging.json`
- `FrontOffice/src/FrontOffice.Main/appsettings.json`
- `FrontOffice/src/FrontOffice.Main/appsettings.Staging.json`
- `FrontOffice.BFF/src/FrontOffice.BFF.WebApi/appsettings.json`
**تغییرات در appsettings**:
```json
// BackOffice
"GwUrl": "https://backoffice-bff.se.kbs1.ir"
// FrontOffice
"GwUrl": "https://frontoffice-bff.se.kbs1.ir"
// FrontOffice.BFF
"CMSMSAddress": "https://cms.se.kbs1.ir"
```
### نتیجه:
✅ **21 فایل** با موفقیت تغییر کرد
✅ **0 آدرس قدیمی** باقی مانده
---
## 3. ✅ تغییر Git Remote URLs
**دستورات اجرا شده**:
```bash
# FrontOffice
cd FrontOffice
git remote set-url kub-stage https://git.se.kbs1.ir/admin/FrontOffice.git
# BackOffice
cd BackOffice
git remote set-url kub-stage https://git.se.kbs1.ir/admin/BackOffice.git
# BackOffice.BFF
cd BackOffice.BFF
git remote set-url kub-stage https://git.se.kbs1.ir/admin/BackOffice.BFF.git
# FrontOffice.BFF
cd FrontOffice.BFF
git remote set-url kub-stage https://git.se.kbs1.ir/admin/FrontOffice.BFF.git
# CMS
cd CMS
git remote set-url gitea https://git.se.kbs1.ir/admin/CMS.git
# totalDoc
cd totalDoc
git remote set-url foursatDocs https://git.se.kbs1.ir/FourSat/docs.git
```
### نتیجه:
✅ **6 ریپو** بروز شد
✅ همه remote ها به `git.se.kbs1.ir` تغییر کرد
---
## 📊 آمار کلی
| مورد | تعداد |
|------|-------|
| Proto DLL های ایجاد شده | 24 |
| فایل‌های JSON/YAML تغییر یافته | 21 |
| Git Repositories بروز شده | 6 |
| Build Errors | 0 ✅ |
| Build Warnings | 246 (MudBlazor) |
---
## 🚀 دستورات CI/CD
### قبل از Build/Deploy:
```bash
# 1. Build proto dependencies
cd /home/masoud/Apps/project/FourSat/BackOffice
./build-deps.sh
# 2. Build project
cd src
dotnet build BackOffice.sln -c Release
# 3. Publish
dotnet publish BackOffice/BackOffice.csproj -c Release -o ./publish
```
### بررسی Output:
```bash
# تعداد proto assemblies در output
ls ./publish/wwwroot/_framework/*.wasm | grep "BackOffice.BFF" | wc -l
# Result: 24 ✅
```
---
## 🔧 Troubleshooting
### اگر Build شکست:
1. **بررسی libs/ folder**:
```bash
ls BackOffice/libs/*.dll | wc -l
# باید 24 باشد
```
2. **Rebuild proto dependencies**:
```bash
cd BackOffice
rm -rf libs/
./build-deps.sh
```
3. **بررسی Package Versions**:
- `Google.Protobuf`: باید `3.28.3` باشد
- `Grpc.Core.Api`: باید `2.71.0` باشد
### اگر Git Push شکست:
```bash
# تست اتصال به remote جدید
git ls-remote https://git.se.kbs1.ir/admin/BackOffice.git
```
---
## 📝 نکات مهم
1. **PublicMessage.Protobuf** تنها پروژه‌ای است که `net8.0` دارد
2. اسکریپت `build-deps.sh` خودکار هر دو framework را چک می‌کند
3. در Development Mode می‌توان از ProjectReference استفاده کرد (اگر libs/ وجود نداشته باشد)
4. همه آدرس‌های `*.foursat.afrino.co` به `*.se.kbs1.ir` تغییر کرد
5. همه Git remote ها بروز شدند
---
## ✅ Status: COMPLETED
**تاریخ تکمیل**: January 3, 2026
**Build Status**: ✅ SUCCESS
**Publish Status**: ✅ SUCCESS
**Domain Migration**: ✅ COMPLETED
**Git Remotes**: ✅ UPDATED
-135
View File
@@ -1,135 +0,0 @@
# BackOffice Project Status
> آخرین بروزرسانی: **December 20, 2025**
---
## 🎯 وضعیت کلی
| Component | Build Status | Errors |
|-----------|--------------|--------|
| BackOffice UI | ✅ SUCCESS | 0 |
| BackOffice.BFF | ✅ SUCCESS | 0 |
| CMS Microservice | ✅ SUCCESS | 0 |
**System Status**: 🟢 **PRODUCTION READY**
---
## 📦 Proto Projects (24 پروژه فعال)
### Core Protos:
- ✅ Common.Protobuf
- ✅ Health.Protobuf
- ✅ Configuration.Protobuf
### User Management:
- ✅ User.Protobuf
- ✅ UserRole.Protobuf
- ✅ Role.Protobuf
- ✅ UserAddress.Protobuf
- ✅ UserWallet.Protobuf
- ✅ Otp.Protobuf
### Products & Shop:
- ✅ Products.Protobuf
- ✅ Category.Protobuf
- ✅ Tag.Protobuf
- ✅ ProductTag.Protobuf
- ✅ Package.Protobuf
### Discount Shop:
- ✅ DiscountProduct.Protobuf
- ✅ DiscountCategory.Protobuf
- ✅ DiscountOrder.Protobuf
- ✅ DiscountShoppingCart.Protobuf
### Network & Commission:
- ✅ NetworkMembership.Protobuf
- ✅ ClubMembership.Protobuf
- ✅ Commission.Protobuf
### Orders & Payments:
- ✅ UserOrder.Protobuf
- ✅ ManualPayment.Protobuf
### Messaging:
- ✅ PublicMessage.Protobuf
---
## 🗂️ ماژول‌های فعال
### 1. Products Module ✅
- صفحه اصلی محصولات با فیلتر و صفحه‌بندی
- ایجاد محصول جدید با آپلود تصویر
- ویرایش محصول
- گالری تصاویر محصول
- مدیریت تگ‌های محصول
- ویرایش گروهی (قیمت، موجودی، وضعیت)
- **ستون موجودی** با رنگ‌بندی هوشمند (🔴🟡🟢)
- DragDrop دسته‌بندی محصولات
### 2. Discount Shop Module ✅
- مدیریت محصولات تخفیفی
- مدیریت دسته‌بندی‌ها
- مدیریت سفارشات
- گزارش فروش
### 3. Commission Module ✅
- داشبورد استخر هفتگی
- لیست پرداخت‌ها
- لیست برداشت‌ها
- بالانس‌های هفتگی کاربران
### 4. Network Module ✅
- لیست اعضای شبکه
- نمای درختی شبکه
- آمار شبکه
### 5. Club Module ✅
- لیست اعضای باشگاه
- آمار باشگاه
- مدیریت ویژگی‌های باشگاه
### 6. Tag Module ✅
- مدیریت تگ‌ها (CRUD)
- اختصاص تگ به محصولات
### 7. Public Messages Module ✅
- مدیریت پیام‌های عمومی
- قالب‌های پیام
### 8. Manual Payments Module ✅
- ثبت پرداخت دستی
- تایید/رد پرداخت
### 9. System Management ✅
- تنظیمات سیستم
- لاگ تغییرات
- Health Check
### 10. Dashboard ✅
- ویجت آمار فروشگاه تخفیفی (7 روز اخیر)
---
## 📊 آمار
| Metric | Value |
|--------|-------|
| Build Errors | 0 |
| Proto Projects | 24 |
| Active Pages | 40+ |
| Active Components | 60+ |
| Excluded Files | 0 |
| Test Coverage | N/A |
---
## 🔧 Environment
- **Framework**: Blazor WebAssembly .NET 9.0
- **UI Library**: MudBlazor 8.14.0
- **gRPC**: Grpc.Net.Client 2.70.0
- **Mapping**: Mapster 7.4.0+
-230
View File
@@ -1,230 +0,0 @@
# BackOffice Technical Notes
> نکات فنی برای توسعه‌دهندگان
---
## 1. Mapster Mapping Patterns
### 1.1 Proto Types (Immutable)
برای proto types که immutable هستند، باید از `MapWith` استفاده کرد:
```csharp
config.NewConfig<SourceDto, ProtoResponse>()
.MapWith(src => new ProtoResponse
{
Field1 = src.Field1,
Field2 = src.Field2 ?? string.Empty,
RepeatedField = { src.List?.Select(x => new Item { ... }) ?? Enumerable.Empty<Item>() }
});
```
### 1.2 Null-Safe MetaData
```csharp
MetaData = src.MetaData != null ? new MetaData
{
PageIndex = src.MetaData.PageIndex,
TotalPages = src.MetaData.TotalPages,
TotalCount = src.MetaData.TotalCount
} : null
```
### 1.3 Alias Imports برای Disambiguation
وقتی دو proto با نام یکسان داریم:
```csharp
using BffProtos = BackOffice.BFF.ClubMembership.Protobuf.Protos.ClubMembership;
using CmsProtos = CMSMicroservice.Protobuf.Protos.ClubMembership;
// استفاده:
config.NewConfig<BffProtos.GetRequest, CmsProtos.GetRequest>();
```
### 1.4 PaginationState Mapping
```csharp
config.NewConfig<BffRequest, AppQuery>()
.Map(dest => dest.PaginationState, src => src.PaginationState);
```
---
## 2. MudBlazor 8 Breaking Changes
### 2.1 Dialog Instance
```csharp
// ❌ قبلی
[CascadingParameter] MudDialogInstance MudDialog { get; set; }
// ✅ جدید
[CascadingParameter] IMudDialogInstance MudDialog { get; set; }
```
### 2.2 Generic Components
```razor
<!-- ❌ قبلی -->
<MudSwitch @bind-Value="isActive" />
<MudChip>Text</MudChip>
<!-- ✅ جدید -->
<MudSwitch T="bool" @bind-Value="isActive" />
<MudChip T="string">Text</MudChip>
```
### 2.3 Drag Events
```razor
<!-- ❌ قبلی -->
@ondragover="e => e.PreventDefault()"
<!-- ✅ جدید -->
@ondragover:preventDefault
```
### 2.4 File Upload
```csharp
// FilesChanged حالا IBrowserFile می‌گیرد
<MudFileUpload T="IBrowserFile" FilesChanged="OnFileSelected">
```
---
## 3. gRPC Patterns
### 3.1 Service Override in BFF
```csharp
public override async Task<GetResponse> GetData(GetRequest request, ServerCallContext context)
{
return await _dispatchRequestToCQRS.Handle<GetRequest, GetQuery, GetResponse>(request, context);
}
```
### 3.2 CQRS Handler
```csharp
public class GetQueryHandler : IRequestHandler<GetQuery, GetResponseDto>
{
private readonly IApplicationContractContext _context;
public async Task<GetResponseDto> Handle(GetQuery request, CancellationToken ct)
{
var cmsRequest = request.Adapt<CmsProtos.GetRequest>();
var response = await _context.Service.GetAsync(cmsRequest, cancellationToken: ct);
return response.Adapt<GetResponseDto>();
}
}
```
---
## 4. Proto Update Checklist
هر تغییری در Proto نیاز به این مراحل دارد:
### Step 1: Update Version
```xml
<!-- در .csproj -->
<Version>0.0.142</Version><Version>0.0.143</Version>
```
### Step 2: Pack
```bash
cd path/to/proto/project
dotnet pack -c Release
# Push به GitLab Registry خودکار انجام می‌شود
```
### Step 3: Update References
```xml
<PackageReference Include="Foursat.Proto" Version="0.0.143" />
```
### Step 4: Build & Test
```bash
dotnet build
dotnet test
```
---
## 5. Common Fixes
### 5.1 Snackbar Duplicate Injection
اگر در `_Imports.razor` inject شده، در component نیاز نیست:
```csharp
// ❌ حذف کن
[Inject] ISnackbar Snackbar { get; set; }
```
### 5.2 BasePageComponent Reload
```csharp
private MudDataGrid<Model>? _gridData;
private async Task OnFilterSubmit()
{
if (_gridData != null)
await _gridData.ReloadServerData();
}
```
### 5.3 Nullable Wrapper Types
```csharp
// Proto nullable types:
// google.protobuf.Int64Value → long?
// google.protobuf.BoolValue → bool?
// Set value:
request.UserId = userId; // نه new Int64Value { Value = userId }
```
---
## 6. Build Commands
```bash
# Full Solution Build
cd /home/masoud/Apps/project/FourSat/BackOffice/src
dotnet build BackOffice.sln
# Single Project
dotnet build BackOffice/BackOffice.csproj
# With Restore
dotnet build --restore
# Clean Build
dotnet clean && dotnet build
# Check Errors Only
dotnet build 2>&1 | grep -E "error CS"
```
---
## 7. Project References
### ProjectReference (Local Development):
```xml
<ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/X.Protobuf/X.Protobuf.csproj" />
```
### PackageReference (Production):
```xml
<PackageReference Include="Foursat.X.Protobuf" Version="0.0.143" />
```
---
## 8. File Organization
```
BackOffice/
├── docs/
│ ├── README.md # Index
│ ├── STATUS.md # Current Status
│ ├── CHANGELOG.md # History
│ ├── TECHNICAL-NOTES.md # This file
│ └── SESSION-*.md # Session logs
├── src/
│ └── BackOffice/
│ ├── Pages/ # Blazor pages
│ ├── Services/ # gRPC clients
│ └── Common/ # Shared components
```
File diff suppressed because it is too large Load Diff
+14 -6
View File
@@ -132,13 +132,21 @@
</ItemGroup> </ItemGroup>
<!-- ============================================================ --> <!-- ============================================================ -->
<!-- Proto References: Uses libs/ DLLs if available (CI/CD mode) --> <!-- Proto References: Direct reference to CMS Protobuf project -->
<!-- Falls back to ProjectReference if libs/ missing (dev mode) --> <!-- This enables direct communication with CMS (no BFF needed) -->
<!-- Run ./build-deps.sh to populate libs/ folder --> <!-- ============================================================ -->
<!-- Direct reference to CMS Protobuf project -->
<ItemGroup>
<ProjectReference Include="../../../CMS/src/CMSMicroservice.Protobuf/CMSMicroservice.Protobuf.csproj" />
</ItemGroup>
<!-- ============================================================ -->
<!-- OLD BFF Proto References (DEPRECATED - kept for reference) -->
<!-- ============================================================ --> <!-- ============================================================ -->
<!-- CI/CD Mode: Use pre-built DLLs from libs/ folder --> <!-- CI/CD Mode: Use pre-built DLLs from libs/ folder -->
<ItemGroup Condition="Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')"> <ItemGroup Condition="false AND Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')">
<Reference Include="BackOffice.BFF.Common.Protobuf"> <Reference Include="BackOffice.BFF.Common.Protobuf">
<HintPath>../../libs/BackOffice.BFF.Common.Protobuf.dll</HintPath> <HintPath>../../libs/BackOffice.BFF.Common.Protobuf.dll</HintPath>
</Reference> </Reference>
@@ -213,8 +221,8 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<!-- Dev Mode: Use ProjectReference when libs/ doesn't exist --> <!-- Dev Mode: OLD BFF ProjectReference (DEPRECATED) -->
<ItemGroup Condition="!Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')"> <ItemGroup Condition="false AND !Exists('../../libs/BackOffice.BFF.Common.Protobuf.dll')">
<ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.Common.Protobuf/BackOffice.BFF.Common.Protobuf.csproj" /> <ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.Common.Protobuf/BackOffice.BFF.Common.Protobuf.csproj" />
<ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.Category.Protobuf/BackOffice.BFF.Category.Protobuf.csproj" /> <ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.Category.Protobuf/BackOffice.BFF.Category.Protobuf.csproj" />
<ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.ClubMembership.Protobuf/BackOffice.BFF.ClubMembership.Protobuf.csproj" /> <ProjectReference Include="../../../BackOffice.BFF/src/Protobufs/BackOffice.BFF.ClubMembership.Protobuf/BackOffice.BFF.ClubMembership.Protobuf.csproj" />
@@ -1,28 +1,28 @@
using BackOffice.BFF.Otp.Protobuf.Protos.Otp; using CMSMicroservice.Protobuf.Protos.OtpToken;
using BackOffice.BFF.Package.Protobuf.Protos.Package; using CMSMicroservice.Protobuf.Protos.Package;
using BackOffice.BFF.Role.Protobuf.Protos.Role; using CMSMicroservice.Protobuf.Protos.Role;
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using BackOffice.BFF.User.Protobuf.Protos.User; using CMSMicroservice.Protobuf.Protos.User;
using BackOffice.BFF.UserAddress.Protobuf.Protos.UserAddress; using CMSMicroservice.Protobuf.Protos.UserAddress;
using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder; using CMSMicroservice.Protobuf.Protos.UserOrder;
using BackOffice.BFF.UserRole.Protobuf.Protos.UserRole; using CMSMicroservice.Protobuf.Protos.UserRole;
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos.Category;
using Foursat.BackOffice.BFF.Commission.Protos; using CMSMicroservice.Protobuf.Protos.Commission;
using Foursat.BackOffice.BFF.ClubMembership.Protos; using CMSMicroservice.Protobuf.Protos.ClubMembership;
using Foursat.BackOffice.BFF.Configuration.Protos; using CMSMicroservice.Protobuf.Protos.Configuration;
using Foursat.BackOffice.BFF.NetworkMembership.Protos; using CMSMicroservice.Protobuf.Protos.NetworkMembership;
using Foursat.BackOffice.BFF.Health.Protobuf; using CMSMicroservice.Protobuf.Protos.Health;
using BackOffice.BFF.Configuration.Protobuf.Protos.AppVersion; using CMSMicroservice.Protobuf.Protos.AppVersion;
// Discount Shop Proto Clients // Discount Shop Proto Clients
using BackOffice.BFF.DiscountProduct.Protobuf.Protos.DiscountProduct; using CMSMicroservice.Protobuf.Protos.DiscountProduct;
using BackOffice.BFF.DiscountCategory.Protobuf.Protos.DiscountCategory; using CMSMicroservice.Protobuf.Protos.DiscountCategory;
using BackOffice.BFF.DiscountOrder.Protobuf.Protos.DiscountOrder; using CMSMicroservice.Protobuf.Protos.DiscountOrder;
using BackOffice.BFF.Tag.Protobuf.Protos.Tag; using CMSMicroservice.Protobuf.Protos.Tag;
using BackOffice.BFF.ProductTag.Protobuf.Protos.ProductTag; using CMSMicroservice.Protobuf.Protos.ProductTag;
using BackOffice.BFF.ManualPayment.Protobuf; using CMSMicroservice.Protobuf.Protos.ManualPayment;
using Foursat.BackOffice.BFF.PublicMessage.Protobuf; using CMSMicroservice.Protobuf.Protos;
using Foursat.BackOffice.BFF.Inventory.Protos; using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
using BackOffice.Services.DiscountProduct; using BackOffice.Services.DiscountProduct;
using BackOffice.Services.DiscountCategory; using BackOffice.Services.DiscountCategory;
@@ -102,7 +102,7 @@ public static class ConfigureServices
return CreateAuthenticatedChannel(baseUri, httpClient, sp); return CreateAuthenticatedChannel(baseUri, httpClient, sp);
}); });
services.AddTransient(sp => new OtpContract.OtpContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new OtpTokenContract.OtpTokenContractClient(sp.GetRequiredService<CallInvoker>()));
services.AddTransient(sp => new PackageContract.PackageContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new PackageContract.PackageContractClient(sp.GetRequiredService<CallInvoker>()));
services.AddTransient(sp => new ProductsContract.ProductsContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new ProductsContract.ProductsContractClient(sp.GetRequiredService<CallInvoker>()));
services.AddTransient(sp => new RoleContract.RoleContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new RoleContract.RoleContractClient(sp.GetRequiredService<CallInvoker>()));
@@ -136,7 +136,7 @@ public static class ConfigureServices
services.AddTransient(sp => new ManualPaymentContract.ManualPaymentContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new ManualPaymentContract.ManualPaymentContractClient(sp.GetRequiredService<CallInvoker>()));
// Inventory Management Service // Inventory Management Service
services.AddTransient(sp => new InventoryBFFContract.InventoryBFFContractClient(sp.GetRequiredService<CallInvoker>())); services.AddTransient(sp => new InventoryContract.InventoryContractClient(sp.GetRequiredService<CallInvoker>()));
return services; return services;
} }
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Category
<MudAutocomplete T="GetAllCategoryByFilterResponseModel" <MudAutocomplete T="GetAllCategoryByFilterResponseModel"
Label="@Label" Label="@Label"
@@ -1,4 +1,5 @@
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.Category;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace BackOffice.Pages.AutoComplete; namespace BackOffice.Pages.AutoComplete;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Category
<MudAutocomplete T="GetAllCategoryByFilterResponseModel" <MudAutocomplete T="GetAllCategoryByFilterResponseModel"
Label="@Label" Label="@Label"
@@ -1,4 +1,5 @@
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.Category;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace BackOffice.Pages.AutoComplete; namespace BackOffice.Pages.AutoComplete;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Category
<MudSelect T="long" <MudSelect T="long"
@ref="_selectRef" @ref="_selectRef"
@@ -1,7 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.Category;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace BackOffice.Pages.AutoComplete; namespace BackOffice.Pages.AutoComplete;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
<MudAutocomplete T="GetAllProductsByFilterResponseModel" <MudAutocomplete T="GetAllProductsByFilterResponseModel"
Label="@Label" Label="@Label"
@@ -1,5 +1,5 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using BackOffice.BFF.Protobuf.Common; using CMSMicroservice.Protobuf.Protos;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace BackOffice.Pages.AutoComplete; namespace BackOffice.Pages.AutoComplete;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Role.Protobuf.Protos.Role @using CMSMicroservice.Protobuf.Protos.Role
<MudAutocomplete T="GetAllRoleByFilterResponseModel" <MudAutocomplete T="GetAllRoleByFilterResponseModel"
Label="@Label" Label="@Label"
@@ -1,4 +1,4 @@
using BackOffice.BFF.Role.Protobuf.Protos.Role; using CMSMicroservice.Protobuf.Protos.Role;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop; using Microsoft.JSInterop;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.User.Protobuf.Protos.User @using CMSMicroservice.Protobuf.Protos.User
<MudAutocomplete T="GetAllUserByFilterResponseModel" <MudAutocomplete T="GetAllUserByFilterResponseModel"
Label="@Label" Label="@Label"
@@ -1,4 +1,4 @@
using BackOffice.BFF.User.Protobuf.Protos.User; using CMSMicroservice.Protobuf.Protos.User;
using Grpc.Core; using Grpc.Core;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
<MudAutocomplete T="WeekInfo" <MudAutocomplete T="WeekInfo"
Label="@Label" Label="@Label"
@@ -1,5 +1,5 @@
using BackOffice.Services; using BackOffice.Services;
using Foursat.BackOffice.BFF.Commission.Protos; using CMSMicroservice.Protobuf.Protos.Commission;
using Grpc.Core; using Grpc.Core;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -1,9 +1,9 @@
@attribute [Route(RouteConstance.Category)] @attribute [Route(RouteConstance.Category)]
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Category
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@using DataModel = BackOffice.BFF.Category.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel @using DataModel = CMSMicroservice.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel
<BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit"> <BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit">
<Filters> <Filters>
@@ -1,11 +1,12 @@
using System.Text.Json; using System.Text.Json;
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos;
using CMSMicroservice.Protobuf.Protos.Category;
using BackOffice.Common.BaseComponents; using BackOffice.Common.BaseComponents;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
using Mapster; using Mapster;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using DataModel = BackOffice.BFF.Category.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel; using DataModel = CMSMicroservice.Protobuf.Protos.Category.GetAllCategoryByFilterResponseModel;
namespace BackOffice.Pages.Category; namespace BackOffice.Pages.Category;
@@ -1,6 +1,6 @@
@attribute [Route(RouteConstance.CategoryProducts + "{CategoryId:long?}")] @attribute [Route(RouteConstance.CategoryProducts + "{CategoryId:long?}")]
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -1,5 +1,5 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos.Category;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using MudBlazor; using MudBlazor;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Category
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -1,4 +1,4 @@
using BackOffice.BFF.Category.Protobuf.Protos.Category; using CMSMicroservice.Protobuf.Protos.Category;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
+1 -1
View File
@@ -3,7 +3,7 @@
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
@using BackOffice.Pages.Club.Components @using BackOffice.Pages.Club.Components
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
<MudText Typo="Typo.h4" Class="mb-4">مدیریت اعضای باشگاه</MudText> <MudText Typo="Typo.h4" Class="mb-4">مدیریت اعضای باشگاه</MudText>
@@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using BackOffice.Pages.Club.Components; using BackOffice.Pages.Club.Components;
using Foursat.BackOffice.BFF.ClubMembership.Protos; using CMSMicroservice.Protobuf.Protos.ClubMembership;
namespace BackOffice.Pages.Club; namespace BackOffice.Pages.Club;
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
+1 -1
View File
@@ -1,7 +1,7 @@
@page "/club/statistics" @page "/club/statistics"
@using MudBlazor @using MudBlazor
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
<MudText Typo="Typo.h4" GutterBottom="true">آمار باشگاه</MudText> <MudText Typo="Typo.h4" GutterBottom="true">آمار باشگاه</MudText>
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -93,7 +93,8 @@
</tr> </tr>
<tr> <tr>
<td><strong>آخرین ویرایش:</strong></td> <td><strong>آخرین ویرایش:</strong></td>
<td>@Payout.LastModified.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss")</td> @* CMS UserCommissionPayoutModel does not have LastModified - using Created as fallback *@
<td>@Payout.Created.ToDateTime().ToLocalTime().ToString("yyyy/MM/dd HH:mm:ss")</td>
</tr> </tr>
</tbody> </tbody>
</MudSimpleTable> </MudSimpleTable>
@@ -1,7 +1,7 @@
@page "/commission/dashboard" @page "/commission/dashboard"
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using MudBlazor @using MudBlazor
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using System.Globalization; using System.Globalization;
using System.Text.Json; using System.Text.Json;
using Foursat.BackOffice.BFF.Commission.Protos; using CMSMicroservice.Protobuf.Protos.Commission;
using BackOffice.Services; using BackOffice.Services;
namespace BackOffice.Pages.Commission; namespace BackOffice.Pages.Commission;
@@ -24,8 +24,8 @@ public partial class Dashboard
private GetWeeklyCommissionPoolResponse? _poolData; private GetWeeklyCommissionPoolResponse? _poolData;
// Available weeks data // Available weeks data
private Foursat.BackOffice.BFF.Commission.Protos.GetAvailableWeeksResponse? _availableWeeks; private CMSMicroservice.Protobuf.Protos.Commission.GetAvailableWeeksResponse? _availableWeeks;
private List<Foursat.BackOffice.BFF.Commission.Protos.WeekInfo> _allWeeks = new(); private List<CMSMicroservice.Protobuf.Protos.Commission.WeekInfo> _allWeeks = new();
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
@@ -1,7 +1,7 @@
@page "/commission/payouts" @page "/commission/payouts"
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
@using MudBlazor @using MudBlazor
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -1,5 +1,5 @@
using BackOffice.BFF.Protobuf.Common; using CMSMicroservice.Protobuf.Protos;
using Foursat.BackOffice.BFF.Commission.Protos; using CMSMicroservice.Protobuf.Protos.Commission;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
@@ -22,29 +22,26 @@ public partial class UserPayouts
{ {
try try
{ {
// CMS proto uses flat fields instead of nested PaginationState/Filter
var request = new GetUserCommissionPayoutsRequest var request = new GetUserCommissionPayoutsRequest
{ {
PaginationState = new PaginationState() PageIndex = state.Page + 1,
{ PageSize = state.PageSize
PageNumber = state.Page + 1,
PageSize = state.PageSize
},
Filter = new GetUserPayoutsFilter()
}; };
if (_filterUserId.HasValue && _filterUserId.Value > 0) if (_filterUserId.HasValue && _filterUserId.Value > 0)
{ {
request.Filter.UserId = _filterUserId.Value; request.UserId = _filterUserId.Value;
} }
if (_filterWeekDefinitionId.HasValue && _filterWeekDefinitionId.Value > 0) if (_filterWeekDefinitionId.HasValue && _filterWeekDefinitionId.Value > 0)
{ {
request.Filter.WeekDefinitionId = _filterWeekDefinitionId.Value; request.WeekDefinitionId = _filterWeekDefinitionId.Value;
} }
if (_filterStatus.HasValue) if (_filterStatus.HasValue)
{ {
request.Filter.Status = _filterStatus.Value; request.Status = _filterStatus.Value;
} }
var result = await CommissionContract.GetUserCommissionPayoutsAsync(request); var result = await CommissionContract.GetUserCommissionPayoutsAsync(request);
@@ -1,7 +1,7 @@
@page "/commission/reports" @page "/commission/reports"
@using MudBlazor @using MudBlazor
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -2,7 +2,7 @@
@attribute [Authorize] @attribute [Authorize]
@using MudBlazor @using MudBlazor
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
@using Microsoft.JSInterop @using Microsoft.JSInterop
@using System.Text @using System.Text
@@ -1,7 +1,7 @@
@page "/commission/withdrawals" @page "/commission/withdrawals"
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -1,9 +1,9 @@
using Foursat.BackOffice.BFF.Commission.Protos; using CMSMicroservice.Protobuf.Protos.Commission;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using GrpcWithdrawalRequestModel = Foursat.BackOffice.BFF.Commission.Protos.WithdrawalRequestModel; using GrpcWithdrawalRequestModel = CMSMicroservice.Protobuf.Protos.Commission.WithdrawalRequestModel;
using GrpcGetWithdrawalRequestsRequest = Foursat.BackOffice.BFF.Commission.Protos.GetWithdrawalRequestsRequest; using GrpcGetWithdrawalRequestsRequest = CMSMicroservice.Protobuf.Protos.Commission.GetWithdrawalRequestsRequest;
namespace BackOffice.Pages.Commission; namespace BackOffice.Pages.Commission;
@@ -1,8 +1,8 @@
@page "/dashboard/overview" @page "/dashboard/overview"
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
@using Foursat.BackOffice.BFF.ClubMembership.Protos @using CMSMicroservice.Protobuf.Protos.ClubMembership
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
+6 -5
View File
@@ -1,10 +1,11 @@
@attribute [Route(RouteConstance.HomePage)] @attribute [Route(RouteConstance.HomePage)]
@using BackOffice.BFF.User.Protobuf.Protos.User @using CMSMicroservice.Protobuf.Protos.User
@using BackOffice.BFF.UserOrder.Protobuf.Protos.UserOrder @using CMSMicroservice.Protobuf.Protos.UserOrder
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.BFF.Category.Protobuf.Protos.Category @using CMSMicroservice.Protobuf.Protos.Package
@using CMSMicroservice.Protobuf.Protos.Category
@inject UserContract.UserContractClient UserContract @inject UserContract.UserContractClient UserContract
@inject UserOrderContract.UserOrderContractClient UserOrderContract @inject UserOrderContract.UserOrderContractClient UserOrderContract
@inject ProductsContract.ProductsContractClient ProductsContract @inject ProductsContract.ProductsContractClient ProductsContract
@@ -1,6 +1,6 @@
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
@using InventoryProductType = Foursat.BackOffice.BFF.Inventory.Protos.ProductType @using InventoryProductType = CMSMicroservice.Protobuf.Protos.Inventory.ProductType
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -90,7 +90,7 @@
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
[Parameter] public List<WarehouseDto> Warehouses { get; set; } = new(); [Parameter] public List<WarehouseDto> Warehouses { get; set; } = new();
[Parameter] public long? ProductIdParam { get; set; } [Parameter] public long? ProductIdParam { get; set; }
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -54,7 +54,7 @@
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
[Parameter] public InventoryItemDto Item { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!;
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -56,7 +56,7 @@
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
private MudForm? _form; private MudForm? _form;
private bool _formValid; private bool _formValid;
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -63,7 +63,7 @@
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
[Parameter] public InventoryItemDto Item { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!;
@@ -1,4 +1,4 @@
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
<MudDialog> <MudDialog>
<DialogContent> <DialogContent>
@@ -72,7 +72,7 @@
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!; [CascadingParameter] IMudDialogInstance MudDialog { get; set; } = default!;
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
[Parameter] public InventoryItemDto Item { get; set; } = default!; [Parameter] public InventoryItemDto Item { get; set; } = default!;
@@ -1,7 +1,7 @@
@attribute [Route(RouteConstance.Inventory)] @attribute [Route(RouteConstance.Inventory)]
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
@using BackOffice.Pages.Inventory.Components @using BackOffice.Pages.Inventory.Components
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using Foursat.BackOffice.BFF.Inventory.Protos; using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Pages.Inventory.Components; using BackOffice.Pages.Inventory.Components;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
@@ -9,7 +9,7 @@ namespace BackOffice.Pages.Inventory;
public partial class InventoryMainPage public partial class InventoryMainPage
{ {
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
private MudDataGrid<InventoryItemDto>? _gridData; private MudDataGrid<InventoryItemDto>? _gridData;
private List<WarehouseDto> _warehouses = new(); private List<WarehouseDto> _warehouses = new();
@@ -1,7 +1,7 @@
@attribute [Route(RouteConstance.InventoryLowStock)] @attribute [Route(RouteConstance.InventoryLowStock)]
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="mb-4"> <MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Class="mb-4">
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Foursat.BackOffice.BFF.Inventory.Protos; using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Pages.Inventory.Components; using BackOffice.Pages.Inventory.Components;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
@@ -8,7 +8,7 @@ namespace BackOffice.Pages.Inventory;
public partial class LowStockPage public partial class LowStockPage
{ {
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
private List<InventoryItemDto> _items = new(); private List<InventoryItemDto> _items = new();
private List<WarehouseDto> _warehouses = new(); private List<WarehouseDto> _warehouses = new();
@@ -1,7 +1,7 @@
@attribute [Route(RouteConstance.InventoryMovements)] @attribute [Route(RouteConstance.InventoryMovements)]
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
@using Google.Protobuf.WellKnownTypes @using Google.Protobuf.WellKnownTypes
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -1,14 +1,14 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Google.Protobuf.WellKnownTypes; using Google.Protobuf.WellKnownTypes;
using Foursat.BackOffice.BFF.Inventory.Protos; using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
namespace BackOffice.Pages.Inventory; namespace BackOffice.Pages.Inventory;
public partial class MovementsPage public partial class MovementsPage
{ {
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
[SupplyParameterFromQuery(Name = "itemId")] [SupplyParameterFromQuery(Name = "itemId")]
public long? ItemId { get; set; } public long? ItemId { get; set; }
@@ -1,7 +1,7 @@
@attribute [Route(RouteConstance.InventoryWarehouses)] @attribute [Route(RouteConstance.InventoryWarehouses)]
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Inventory.Protos @using CMSMicroservice.Protobuf.Protos.Inventory
@using BackOffice.Pages.Inventory.Components @using BackOffice.Pages.Inventory.Components
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using Foursat.BackOffice.BFF.Inventory.Protos; using CMSMicroservice.Protobuf.Protos.Inventory;
using BackOffice.Pages.Inventory.Components; using BackOffice.Pages.Inventory.Components;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
@@ -8,7 +8,7 @@ namespace BackOffice.Pages.Inventory;
public partial class WarehousesPage public partial class WarehousesPage
{ {
[Inject] public InventoryBFFContract.InventoryBFFContractClient InventoryContract { get; set; } = default!; [Inject] public InventoryContract.InventoryContractClient InventoryContract { get; set; } = default!;
private List<WarehouseDto> _warehouses = new(); private List<WarehouseDto> _warehouses = new();
private bool _isLoading = true; private bool _isLoading = true;
@@ -1,5 +1,5 @@
using BackOffice.BFF.Otp.Protobuf.Protos.Otp; using CMSMicroservice.Protobuf.Protos.OtpToken;
using BackOffice.BFF.Otp.Protobuf.Validator; using CMSMicroservice.Protobuf.Validator.OtpToken;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
@@ -8,11 +8,11 @@ namespace BackOffice.Pages.Login;
public partial class LoginPage public partial class LoginPage
{ {
private bool _isLoading; private bool _isLoading;
private SendOtpRequest _request = new(); private CreateNewOtpTokenRequest _request = new() { Purpose = "login" };
private SendOtpRequestValidator _requestValidator = new(); private CreateNewOtpTokenRequestValidator _requestValidator = new();
private MudForm _form; private MudForm _form;
[Inject] public OtpContract.OtpContractClient OtpContract { get; set; } [Inject] public OtpTokenContract.OtpTokenContractClient OtpContract { get; set; }
private async Task OnSubmitClick() private async Task OnSubmitClick()
{ {
await _form.Validate(); await _form.Validate();
@@ -25,7 +25,7 @@ public partial class LoginPage
_request.Mobile = _request.Mobile.PersianToEnglish(); _request.Mobile = _request.Mobile.PersianToEnglish();
try try
{ {
await OtpContract.SendOtpAsync(_request); await OtpContract.CreateNewOtpTokenAsync(_request);
Navigation.NavigateTo(RouteConstance.VerifyCodePage + _request.Mobile); Navigation.NavigateTo(RouteConstance.VerifyCodePage + _request.Mobile);
} }
catch (Exception ex) catch (Exception ex)
@@ -1,9 +1,13 @@
using BackOffice.BFF.Otp.Protobuf.Protos.Otp; using CMSMicroservice.Protobuf.Protos.OtpToken;
using BackOffice.BFF.Otp.Protobuf.Validator; using CMSMicroservice.Protobuf.Protos.User;
using CMSMicroservice.Protobuf.Validator.User;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using VerifyOtpTokenRequest = CMSMicroservice.Protobuf.Protos.User.VerifyOtpTokenRequest;
using CreateNewOtpTokenRequest = CMSMicroservice.Protobuf.Protos.OtpToken.CreateNewOtpTokenRequest;
using VerifyOtpTokenRequestValidator = CMSMicroservice.Protobuf.Validator.User.VerifyOtpTokenRequestValidator;
namespace BackOffice.Pages.Login; namespace BackOffice.Pages.Login;
public partial class VerifyCodePage public partial class VerifyCodePage
@@ -12,14 +16,17 @@ public partial class VerifyCodePage
public string Mobile { get; set; } public string Mobile { get; set; }
private bool _isLoading; private bool _isLoading;
private VerifyOtpCodeRequest _request = new(); private VerifyOtpTokenRequest _request = new() { Purpose = "login" };
private VerifyOtpCodeRequestValidator _requestValidator = new(); private VerifyOtpTokenRequestValidator _requestValidator = new();
private MudForm _form; private MudForm _form;
private Timer _timer; private Timer _timer;
private int _currentCount = 120; private int _currentCount = 120;
[Inject] [Inject]
public OtpContract.OtpContractClient OtpContract { get; set; } public UserContract.UserContractClient UserClient { get; set; }
[Inject]
public OtpTokenContract.OtpTokenContractClient OtpTokenClient { get; set; }
protected override void OnInitialized() protected override void OnInitialized()
{ {
@@ -39,9 +46,16 @@ public partial class VerifyCodePage
try try
{ {
var token = await OtpContract.VerifyOtpCodeAsync(_request); var result = await UserClient.VerifyOtpTokenAsync(_request);
await LocalStorageService.SetItemAsync(GlobalConstants.JwtTokenKey, token.Token); if (result.Success && result.Token != null)
Navigation.NavigateTo(RouteConstance.HomePage, forceLoad: true); {
await LocalStorageService.SetItemAsync(GlobalConstants.JwtTokenKey, result.Token);
Navigation.NavigateTo(RouteConstance.HomePage, forceLoad: true);
}
else
{
Snackbar.Add(message: result.Message, severity: Severity.Error);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -61,9 +75,10 @@ public partial class VerifyCodePage
try try
{ {
await OtpContract.SendOtpAsync(request: new() await OtpTokenClient.CreateNewOtpTokenAsync(new CreateNewOtpTokenRequest
{ {
Mobile = Mobile Mobile = Mobile,
Purpose = "login"
}); });
StartTimer(); StartTimer();
} }
@@ -2,7 +2,7 @@
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@using MudBlazor @using MudBlazor
@using Foursat.BackOffice.BFF.Commission.Protos @using CMSMicroservice.Protobuf.Protos.Commission
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
<MudText Typo="Typo.h4" GutterBottom="true">گزارش موجودی‌های هفتگی</MudText> <MudText Typo="Typo.h4" GutterBottom="true">گزارش موجودی‌های هفتگی</MudText>
@@ -3,7 +3,7 @@
@implements IAsyncDisposable @implements IAsyncDisposable
@inject IJSRuntime JS @inject IJSRuntime JS
@using Foursat.BackOffice.BFF.NetworkMembership.Protos @using CMSMicroservice.Protobuf.Protos.NetworkMembership
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
<MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraExtraLarge" Class="mt-4">
@@ -252,7 +252,7 @@
UserId = _searchUserId.Value, UserId = _searchUserId.Value,
MaxDepth = _selectedDepth, MaxDepth = _selectedDepth,
IsClubActive = _clubActiveFilter, IsClubActive = _clubActiveFilter,
ActivationWeekDefinitionId = _activationWeekFilter ActivationWeekDefinitionId = _activationWeekFilter?.ToString()
}; };
_treeData = await NetworkContract.GetNetworkTreeAsync(request); _treeData = await NetworkContract.GetNetworkTreeAsync(request);
@@ -288,7 +288,7 @@
UserId = userId, UserId = userId,
MaxDepth = _selectedDepth, MaxDepth = _selectedDepth,
IsClubActive = _clubActiveFilter, IsClubActive = _clubActiveFilter,
ActivationWeekDefinitionId = _activationWeekFilter ActivationWeekDefinitionId = _activationWeekFilter?.ToString()
}; };
_treeData = await NetworkContract.GetNetworkTreeAsync(request); _treeData = await NetworkContract.GetNetworkTreeAsync(request);
@@ -1,6 +1,6 @@
@page "/network/statistics" @page "/network/statistics"
@using Foursat.BackOffice.BFF.NetworkMembership.Protos @using CMSMicroservice.Protobuf.Protos.NetworkMembership
@using MudBlazor @using MudBlazor
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -1,5 +1,5 @@
@page "/network/user-info/{UserId:long}" @page "/network/user-info/{UserId:long}"
@using Foursat.BackOffice.BFF.NetworkMembership.Protos @using CMSMicroservice.Protobuf.Protos.NetworkMembership
@attribute [Authorize] @attribute [Authorize]
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Package
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@@ -1,4 +1,4 @@
using BackOffice.BFF.Package.Protobuf.Protos.Package; using CMSMicroservice.Protobuf.Protos.Package;
using Google.Protobuf; using Google.Protobuf;
using Grpc.Core; using Grpc.Core;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Package
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@@ -1,4 +1,4 @@
using BackOffice.BFF.Package.Protobuf.Protos.Package; using CMSMicroservice.Protobuf.Protos.Package;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
@@ -1,9 +1,9 @@
@attribute [Route(RouteConstance.Package)] @attribute [Route(RouteConstance.Package)]
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Package
@using BackOffice.Pages.Package.Components @using BackOffice.Pages.Package.Components
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using DataModel = BackOffice.BFF.Package.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel @using DataModel = CMSMicroservice.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel
<BackOffice.Common.BaseComponents.BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit"> <BackOffice.Common.BaseComponents.BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit">
<Filters> <Filters>
@@ -1,10 +1,10 @@
using BackOffice.BFF.Package.Protobuf.Protos.Package; using CMSMicroservice.Protobuf.Protos.Package;
using BackOffice.Common.BaseComponents; using BackOffice.Common.BaseComponents;
using BackOffice.Pages.Package.Components; using BackOffice.Pages.Package.Components;
using Mapster; using Mapster;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using DataModel = BackOffice.BFF.Package.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel; using DataModel = CMSMicroservice.Protobuf.Protos.Package.GetAllPackageByFilterResponseModel;
namespace BackOffice.Pages.Package; namespace BackOffice.Pages.Package;
public partial class PackageMainPage public partial class PackageMainPage
@@ -1,4 +1,4 @@
@using BackOffice.BFF.ManualPayment.Protobuf @using CMSMicroservice.Protobuf.Protos.ManualPayment
@using BackOffice.Pages.Payment.Components @using BackOffice.Pages.Payment.Components
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@@ -1,4 +1,4 @@
using BackOffice.BFF.ManualPayment.Protobuf; using CMSMicroservice.Protobuf.Protos.ManualPayment;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
@@ -102,7 +102,7 @@ public partial class ManualPaymentDialog
{ {
UserId = _selectedUserId.Value, UserId = _selectedUserId.Value,
Amount = _createModel.Amount, Amount = _createModel.Amount,
Type = _selectedType, Type = (ManualPaymentType)_selectedType,
Description = _description Description = _description
}; };
@@ -1,5 +1,5 @@
@page "/payment/manual-payments" @page "/payment/manual-payments"
@using BackOffice.BFF.ManualPayment.Protobuf @using CMSMicroservice.Protobuf.Protos.ManualPayment
@using BackOffice.Pages.Payment.Components @using BackOffice.Pages.Payment.Components
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -69,15 +69,15 @@
</PropertyColumn> </PropertyColumn>
<TemplateColumn Title="نوع"> <TemplateColumn Title="نوع">
<CellTemplate> <CellTemplate>
@GetTypeText(context.Item.Type) @GetTypeText((int)context.Item.Type)
</CellTemplate> </CellTemplate>
</TemplateColumn> </TemplateColumn>
<TemplateColumn Title="وضعیت"> <TemplateColumn Title="وضعیت">
<CellTemplate> <CellTemplate>
<MudChip T="string" <MudChip T="string"
Size="Size.Small" Size="Size.Small"
Color="@GetStatusColor(context.Item.Status)"> Color="@GetStatusColor((int)context.Item.Status)">
@GetStatusText(context.Item.Status) @GetStatusText((int)context.Item.Status)
</MudChip> </MudChip>
</CellTemplate> </CellTemplate>
</TemplateColumn> </TemplateColumn>
@@ -103,7 +103,7 @@
</BasePageComponent> </BasePageComponent>
@code { @code {
[Inject] public BackOffice.BFF.ManualPayment.Protobuf.ManualPaymentContract.ManualPaymentContractClient ManualPaymentClient { get; set; } = default!; [Inject] public CMSMicroservice.Protobuf.Protos.ManualPayment.ManualPaymentContract.ManualPaymentContractClient ManualPaymentClient { get; set; } = default!;
// DialogService is injected via _Imports.razor // DialogService is injected via _Imports.razor
private BasePageComponent? _basePage; private BasePageComponent? _basePage;
@@ -118,7 +118,7 @@
var pageNumber = state.Page + 1; var pageNumber = state.Page + 1;
var pageSize = state.PageSize; var pageSize = state.PageSize;
var request = new GetManualPaymentsRequest var request = new GetAllManualPaymentsRequest
{ {
PageNumber = pageNumber, PageNumber = pageNumber,
PageSize = pageSize PageSize = pageSize
@@ -139,12 +139,7 @@
request.Type = _typeFilter.Value; request.Type = _typeFilter.Value;
} }
if (!string.IsNullOrWhiteSpace(_referenceFilter)) var response = await ManualPaymentClient.GetAllManualPaymentsAsync(request);
{
request.ReferenceNumber = _referenceFilter;
}
var response = await ManualPaymentClient.GetManualPaymentsAsync(request);
return new GridData<ManualPaymentModel> return new GridData<ManualPaymentModel>
{ {
+2 -2
View File
@@ -1,8 +1,8 @@
@attribute [Route(RouteConstance.ProductsBulkEdit)] @attribute [Route(RouteConstance.ProductsBulkEdit)]
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel @using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel
<BasePageComponent @ref="_basePage" <BasePageComponent @ref="_basePage"
OnClearFilterClick="OnFilterCleared" OnClearFilterClick="OnFilterCleared"
@@ -1,9 +1,9 @@
using BackOffice.BFF.Products.Protobuf.Protos; using CMSMicroservice.Protobuf.Protos.Products;
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel; using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel;
using PaginationState = BackOffice.BFF.Protobuf.Common.PaginationState; using PaginationState = CMSMicroservice.Protobuf.Protos.PaginationState;
namespace BackOffice.Pages.Products; namespace BackOffice.Pages.Products;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@@ -1,4 +1,4 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@@ -1,4 +1,4 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@@ -1,4 +1,4 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
@@ -1,6 +1,6 @@
@attribute [Route(RouteConstance.ProductCategories + "{ProductId:long?}")] @attribute [Route(RouteConstance.ProductCategories + "{ProductId:long?}")]
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using BackOffice.Pages.AutoComplete @using BackOffice.Pages.AutoComplete
@@ -1,4 +1,4 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.Web;
using MudBlazor; using MudBlazor;
@@ -1,9 +1,9 @@
@attribute [Route(RouteConstance.Products)] @attribute [Route(RouteConstance.Products)]
@using BackOffice.BFF.Products.Protobuf.Protos.Products @using CMSMicroservice.Protobuf.Protos.Products
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using BackOffice.Pages.Products.Components @using BackOffice.Pages.Products.Components
@using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel @using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel
<BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit"> <BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit">
<Filters> <Filters>
@@ -1,5 +1,5 @@
using BackOffice.BFF.Products.Protobuf.Protos.Products; using CMSMicroservice.Protobuf.Protos.Products;
using BackOffice.BFF.Protobuf.Common; using CMSMicroservice.Protobuf.Protos;
using BackOffice.Common.BaseComponents; using BackOffice.Common.BaseComponents;
using BackOffice.Common.Utilities; using BackOffice.Common.Utilities;
using BackOffice.Pages.Tag.Components; using BackOffice.Pages.Tag.Components;
@@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop; using Microsoft.JSInterop;
using MudBlazor; using MudBlazor;
using System.Text; using System.Text;
using DataModel = BackOffice.BFF.Products.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel; using DataModel = CMSMicroservice.Protobuf.Protos.Products.GetAllProductsByFilterResponseModel;
namespace BackOffice.Pages.Products; namespace BackOffice.Pages.Products;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Package
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@@ -1,4 +1,4 @@
using BackOffice.BFF.Role.Protobuf.Protos.Role; using CMSMicroservice.Protobuf.Protos.Role;
using Google.Protobuf; using Google.Protobuf;
using Grpc.Core; using Grpc.Core;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@@ -1,4 +1,4 @@
@using BackOffice.BFF.Package.Protobuf.Protos.Package @using CMSMicroservice.Protobuf.Protos.Package
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using Tizzani.MudBlazor.HtmlEditor @using Tizzani.MudBlazor.HtmlEditor
@@ -1,4 +1,4 @@
using BackOffice.BFF.Role.Protobuf.Protos.Role; using CMSMicroservice.Protobuf.Protos.Role;
using Google.Protobuf; using Google.Protobuf;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Components.Forms;
+2 -2
View File
@@ -1,9 +1,9 @@
@attribute [Route(RouteConstance.Role)] @attribute [Route(RouteConstance.Role)]
@using BackOffice.BFF.Role.Protobuf.Protos.Role @using CMSMicroservice.Protobuf.Protos.Role
@using BackOffice.Pages.Role.Components @using BackOffice.Pages.Role.Components
@using BackOffice.Common.BaseComponents @using BackOffice.Common.BaseComponents
@using DataModel = BackOffice.BFF.Role.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel @using DataModel = CMSMicroservice.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel
<BackOffice.Common.BaseComponents.BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit"> <BackOffice.Common.BaseComponents.BasePageComponent @ref="_basePage" OnClearFilterClick="OnFilterCleared" OnSubmitClick="OnFilterSubmit">
<Filters> <Filters>
@@ -1,10 +1,10 @@
using BackOffice.BFF.Role.Protobuf.Protos.Role; using CMSMicroservice.Protobuf.Protos.Role;
using BackOffice.Common.BaseComponents; using BackOffice.Common.BaseComponents;
using BackOffice.Pages.Role.Components; using BackOffice.Pages.Role.Components;
using Mapster; using Mapster;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
using MudBlazor; using MudBlazor;
using DataModel = BackOffice.BFF.Role.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel; using DataModel = CMSMicroservice.Protobuf.Protos.Role.GetAllRoleByFilterResponseModel;
namespace BackOffice.Pages.Role; namespace BackOffice.Pages.Role;
public partial class RoleMainPage public partial class RoleMainPage
@@ -1,7 +1,8 @@
@page "/system/configuration" @page "/system/configuration"
@attribute [Authorize(Roles = "Administrator")] @attribute [Authorize(Roles = "Administrator")]
@using Foursat.BackOffice.BFF.Configuration.Protos @using CMSMicroservice.Protobuf.Protos.Configuration
@using CMSMicroservice.Protobuf.Protos
@using MudBlazor @using MudBlazor
<MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4"> <MudContainer MaxWidth="MaxWidth.ExtraLarge" Class="mt-4">
@@ -431,8 +432,11 @@
{ {
var request = new GetAllConfigurationsRequest var request = new GetAllConfigurationsRequest
{ {
PageIndex = 1, PaginationState = new PaginationState
PageSize = 100 {
PageNumber = 1,
PageSize = 100
}
}; };
var response = await ConfigurationClient.GetAllConfigurationsAsync(request); var response = await ConfigurationClient.GetAllConfigurationsAsync(request);
@@ -1,7 +1,8 @@
@page "/system/health" @page "/system/health"
@attribute [Authorize] @attribute [Authorize]
@using Foursat.BackOffice.BFF.Health.Protobuf @using CMSMicroservice.Protobuf.Protos.Health
@using Google.Protobuf.WellKnownTypes
@using MudBlazor @using MudBlazor
@inject HealthContract.HealthContractClient HealthClient @inject HealthContract.HealthContractClient HealthClient
@@ -234,8 +235,8 @@
{ {
try try
{ {
var request = new GetSystemHealthRequest(); // CMS proto uses google.protobuf.Empty instead of GetSystemHealthRequest
var response = await HealthClient.GetSystemHealthAsync(request); var response = await HealthClient.GetSystemHealthAsync(new Empty());
_overallStatus = response.OverallHealthy ? "Healthy" : "Unhealthy"; _overallStatus = response.OverallHealthy ? "Healthy" : "Unhealthy";
_lastUpdated = DateTime.Now; _lastUpdated = DateTime.Now;
@@ -245,11 +246,11 @@
{ {
Name = s.ServiceName, Name = s.ServiceName,
Type = GetServiceType(s.ServiceName), Type = GetServiceType(s.ServiceName),
Status = s.Status, Status = s.Status.ToString(),
Uptime = "99.9%", // Mock - not in API Uptime = "99.9%", // Mock - not in API
ResponseTime = (int)s.ResponseTimeMs, ResponseTime = (int)s.ResponseTimeMs,
Version = "1.0.0", // Mock - not in API Version = "1.0.0", // Mock - not in API
LastError = s.Status != "Healthy" ? s.Description : null LastError = s.Status != HealthStatus.Healthy ? s.Description : null
}).ToList(); }).ToList();
// Keep mock events for now // Keep mock events for now

Some files were not shown because too many files have changed in this diff Show More