docs: move docs to totalDoc, replace with placeholders
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m16s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 10m16s
This commit is contained in:
+2
-1009
File diff suppressed because it is too large
Load Diff
@@ -1,850 +1,3 @@
|
|||||||
# 📝 BackOffice — Changelog
|
# Docs moved to totalDoc
|
||||||
|
|
||||||
**آخرین بروزرسانی:** اسفند ۱۴۰۴ (February 18, 2026)
|
See [totalDoc/INDEX.md](../../totalDoc/INDEX.md) for all documentation.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۷ — بهبود سیستم موجودی + اتوکامپلیت تخفیفی (اسفند ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** UX هوشمند ورود کالا با autocomplete اختصاصی برای هر نوع فروشگاه
|
|
||||||
|
|
||||||
### ۱۷.۱ — کامپوننت DiscountProductsAutoComplete ✅
|
|
||||||
|
|
||||||
- **فایلها:** `Pages/AutoComplete/DiscountProductsAutoComplete.razor(.cs)`
|
|
||||||
- **الگو:** مشابه `ProductsAutoComplete` موجود
|
|
||||||
- **gRPC Client:** `DiscountProductContract.DiscountProductContractClient`
|
|
||||||
- **دِبانس:** ۷۰۰ms، حداکثر ۹ نتیجه
|
|
||||||
- **نکته:** `SearchQuery` از نوع `string` (نه `StringValue`)
|
|
||||||
|
|
||||||
### ۱۷.۲ — UX هوشمند AddStockDialog ✅
|
|
||||||
|
|
||||||
- **فایل:** `Pages/Inventory/Components/AddStockDialog.razor`
|
|
||||||
- **تغییر:** فیلد عددی خام شناسه محصول → autocomplete هوشمند
|
|
||||||
- **رفتار:**
|
|
||||||
- انتخاب «فروشگاه عادی» → نمایش `ProductsAutoComplete`
|
|
||||||
- انتخاب «فروشگاه اعتباری» → نمایش `DiscountProductsAutoComplete`
|
|
||||||
- ولیدیشن قبل از submit
|
|
||||||
|
|
||||||
### ۱۷.۳ — Merge به production ✅
|
|
||||||
|
|
||||||
- **برنچ:** `kub-stage` → `production`
|
|
||||||
- **ریموت:** `kub-stage` (Gitea)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۶ — سادهسازی صفحات سایت + ادیتورهای Shopify-style (اسفند ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** مدیریت typed صفحات سایت با فرمهای اختصاصی
|
|
||||||
|
|
||||||
### ۱۶.۱ — صفحه مدیریت PageSettings ✅
|
|
||||||
|
|
||||||
- **فایلها:** `Pages/Content/PageSettingsManagementPage.razor(.cs)`
|
|
||||||
- **قابلیتها:** لیست ۴ صفحه ثابت (landing/about/contact/licenses)، ویرایش تنظیمات، مدیریت تصاویر
|
|
||||||
|
|
||||||
### ۱۶.۲ — ادیتورهای اختصاصی Shopify-style ✅
|
|
||||||
|
|
||||||
| فایل | صفحه |
|
|
||||||
|------|------|
|
|
||||||
| `AboutSettingsEditor.razor` | درباره ما: ارزشها + اعضای تیم |
|
|
||||||
| `ContactSettingsEditor.razor` | تماس: آدرس/تلفن/ایمیل/شبکههای اجتماعی |
|
|
||||||
| `LandingSettingsEditor.razor` | لندینگ: Hero + Steps + Features + Stats + FAQ + Testimonials |
|
|
||||||
| `LicensesSettingsEditor.razor` | مجوزها: JSON array |
|
|
||||||
|
|
||||||
### ۱۶.۳ — سرویس gRPC و دیالوگها ✅
|
|
||||||
|
|
||||||
- `ISitePageSettingsService` + `SitePageSettingsService`
|
|
||||||
- `PageSettingsEditDialog` + `PageImagesDialog` + `PageImageEditDialog`
|
|
||||||
- `PageSettingsModels.cs` — مدلهای typed برای JSON
|
|
||||||
|
|
||||||
### ۱۶.۴ — Proto v0.0.180 ✅
|
|
||||||
|
|
||||||
- **تغییر:** `Foursat.CMSMicroservice.Protobuf` → `0.0.180`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۵ — Production Deploy + فیکس CI/CD Cross-Deploy (اسفند ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** دیپلوی به سرور Production و رفع باگ cross-deploy
|
|
||||||
|
|
||||||
### ۱۵.۱ — Merge به برنچ production ✅
|
|
||||||
|
|
||||||
- **کامیت:** `4454b8d` — merge `kub-stage` → `production`
|
|
||||||
- **ریموت:** `kub-stage` (Gitea)
|
|
||||||
|
|
||||||
### ۱۵.۲ — فیکس باگ Cross-Deploy ✅
|
|
||||||
|
|
||||||
- **مشکل:** Gitea Act Runner همه workflowهای `.gitea/workflows/` را اجرا میکرد — بدون توجه به `branches:` filter
|
|
||||||
- **عارضه:** push به `production` باعث دیپلوی همزمان به staging و production میشد
|
|
||||||
- **رفع:** حذف فایلهای workflow staging از برنچ production
|
|
||||||
- **فایل حذف شده:** `.gitea/workflows/deploy.yml` (staging) از برنچ production
|
|
||||||
|
|
||||||
### ۱۵.۳ — بروزرسانی Proto به v0.0.179 ✅
|
|
||||||
|
|
||||||
- **تغییر:** `Foursat.CMSMicroservice.Protobuf` → `0.0.179`
|
|
||||||
- **فایل:** `BackOffice.csproj`
|
|
||||||
|
|
||||||
### ۱۵.۴ — فیکس K8S_SERVER در prod-deploy.yml ✅
|
|
||||||
|
|
||||||
- **مشکل:** `K8S_SERVER` هنوز `194.5.195.53` (staging) بود
|
|
||||||
- **رفع:** تغییر به `45.149.79.127` (production)
|
|
||||||
- **فیکس اضافی:** `kubectl rollout restart` → `kubectl set image` (تا ایمیج SHA-tagged واقعاً set بشه)
|
|
||||||
|
|
||||||
### ۱۵.۵ — ساخت appsettings.Production.json ✅
|
|
||||||
|
|
||||||
- **مشکل:** فایل `appsettings.Production.json` وجود نداشت → `GwUrl` fallback به `localhost`
|
|
||||||
- **رفع:** ساخت `wwwroot/appsettings.Production.json` با `GwUrl=https://cms.kbs1.ir`
|
|
||||||
|
|
||||||
### ۱۵.۶ — فیکس nginx image path در Dockerfile (production branch) ✅
|
|
||||||
|
|
||||||
- **مشکل:** Dockerfile روی برنچ production از `library/nginx:alpine` استفاده میکرد — وجود نداشت
|
|
||||||
- **ارور:** `manifest for 194.5.195.53:32082/library/nginx:alpine not found`
|
|
||||||
- **رفع:** تغییر به `194.5.195.53:32082/nginx:alpine`
|
|
||||||
- **کامیت:** `743403e` (مستقیم روی برنچ production)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۴ — فیکس Docker Build + Deployment (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** رفع مشکلات Docker build و CI/CD pipeline
|
|
||||||
|
|
||||||
### ۱۴.۱ — تغییر به NuGet Package ✅
|
|
||||||
|
|
||||||
- **مشکل:** `ProjectReference` به `../../../CMS/src/CMSMicroservice.Protobuf/` خارج از Docker build context بود
|
|
||||||
- **رفع:** تغییر به `PackageReference Include="Foursat.CMSMicroservice.Protobuf" Version="0.0.178"`
|
|
||||||
- **فایل:** `BackOffice.csproj`
|
|
||||||
|
|
||||||
### ۱۴.۲ — حذف COPY libs/ از Dockerfile ✅
|
|
||||||
|
|
||||||
- **مشکل:** `COPY ["libs/", "libs/"]` فیل میشد — `libs/` خارج از build context
|
|
||||||
- **رفع:** حذف خط — دیگه نیازی به DLLهای BFF نیست
|
|
||||||
- **فایل:** `Dockerfile`
|
|
||||||
|
|
||||||
### ۱۴.۳ — تغییر nginx:alpine به رجیستری لوکال ✅
|
|
||||||
|
|
||||||
- **مشکل:** `FROM nginx:alpine` از Docker Hub → TLS handshake timeout
|
|
||||||
- **رفع:** `FROM 194.5.195.53:32082/nginx:alpine`
|
|
||||||
- **فایل:** `Dockerfile`
|
|
||||||
|
|
||||||
### ۱۴.۴ — اضافه شدن SERVER_PASSWORD secret ✅
|
|
||||||
|
|
||||||
- **مشکل:** مرحله Deploy to Kubernetes با `Permission denied` فیل میشد
|
|
||||||
- **رفع:** سکرت `SERVER_PASSWORD` به ریپو Gitea اضافه شد (BackOffice + FrontOffice)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۳ — بهبودهای UI بکآفیس (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** رفع مشکلات بصری، بهبود UX فرمها و ناوبری
|
|
||||||
|
|
||||||
### ۱۳.۱ — فیکس کامپوننت Image (پیشوند `/uploads/`) ✅
|
|
||||||
|
|
||||||
- **مشکل:** تصاویر آپلودشده (بلاگ، صفحات سایت، سکشنها) در بکآفیس نمایش داده نمیشدند — مسیر `GwUrl + Src` با مسیر `UploadsController` هماهنگ نبود
|
|
||||||
- **رفع:** اضافه شدن `/uploads/` بین `FileBaseUrl` و مسیر نسبی تصویر
|
|
||||||
- **فایل:** `BackOffice/Common/BaseComponents/Image.razor.cs`
|
|
||||||
|
|
||||||
### ۱۳.۲ — فیکس فیلتر هفته در گزارشهای هفتگی ✅
|
|
||||||
|
|
||||||
- **مشکل:** فیلتر هفته از `MudTextField` (ورودی متنی) استفاده میکرد — کاربر باید عدد حدس میزد
|
|
||||||
- **رفع:** جایگزینی با `WeekNumberPicker` — انتخاب هفته از لیست با بایندینگ `WeekDefinitionId`
|
|
||||||
- **فایلها:**
|
|
||||||
- `CMS/src/CMSMicroservice.Protobuf/Protos/commission.proto` — تغییر فیلدها از `StringValue` به `Int64Value`
|
|
||||||
- `CMS/.../CommissionCQ/Queries/GetAllWeeklyPools/GetAllWeeklyPoolsQuery.cs` + `Handler.cs`
|
|
||||||
- `BackOffice/Pages/Commission/WeeklyReports.razor`
|
|
||||||
|
|
||||||
### ۱۳.۳ — فیکس دانلود PDF قراردادها ✅
|
|
||||||
|
|
||||||
- **مشکل:** فیلد `SignedPdfFile` محتوای HTML کامل دارد (نه URL فایل PDF) — دکمه دانلود کار نمیکرد
|
|
||||||
- **رفع:** تابع JS جدید `jsHtmlToPdf()` برای باز کردن HTML در پنجره جدید و چاپ/ذخیره بهعنوان PDF
|
|
||||||
- **فایلها:**
|
|
||||||
- `BackOffice/wwwroot/js/main.js` — تابع `jsHtmlToPdf`
|
|
||||||
- `BackOffice/Pages/Contract/UserContractPage.razor`
|
|
||||||
- `BackOffice/Pages/Contract/ContractDetailsDialog.razor`
|
|
||||||
|
|
||||||
### ۱۳.۴ — یکسانسازی ارتفاع ویرایشگر HTML ✅
|
|
||||||
|
|
||||||
- **مشکل:** ارتفاع `MudHtmlEditor` در صفحات مختلف متفاوت بود — برخی خیلی کوتاه
|
|
||||||
- **رفع:** اضافه شدن `MinHeight="300px"` به تمام ۷ ویرایشگر HTML
|
|
||||||
- **فایلها:** `BlogPostEditDialog`, `SitePageSectionEditDialog`, `DiscountShop/ProductFormDialog`, `Package/CreateDialog`, `Package/UpdateDialog`, `Products/CreateDialog`, `Products/UpdateDialog`
|
|
||||||
|
|
||||||
### ۱۳.۵ — تولید خودکار اسلاگ بلاگ ✅
|
|
||||||
|
|
||||||
- **مشکل:** کاربر باید اسلاگ URL را دستی وارد میکرد — غیرضروری و مستعد خطا
|
|
||||||
- **رفع:** حذف فیلد اسلاگ از فرم، تولید خودکار `post-{GUID}` در بکاند (حداکثر ۲۰ کاراکتر)
|
|
||||||
- **فایلها:**
|
|
||||||
- `CMS/.../BlogPostCQ/Commands/CreateBlogPost/CreateBlogPostCommandHandler.cs`
|
|
||||||
- `CMS/.../BlogPostCQ/Commands/UpdateBlogPost/UpdateBlogPostCommandHandler.cs`
|
|
||||||
- `BackOffice/Pages/Blog/Components/BlogPostEditDialog.razor`
|
|
||||||
|
|
||||||
### ۱۳.۶ — انتقال تگها به منوی جداگانه ✅
|
|
||||||
|
|
||||||
- **مشکل:** تگها فقط از تب سوم بلاگ قابل دسترسی بودند — ولی تگها بین محصولات و بلاگ مشترکند
|
|
||||||
- **رفع:** اضافه شدن مسیر `/tags` به `TagManagementPage`، لینک جدید «مدیریت تگها» در منوی ناوبری، حذف تب تگها از `BlogHub`
|
|
||||||
- **فایلها:**
|
|
||||||
- `BackOffice/Pages/Tag/TagManagementPage.razor`
|
|
||||||
- `BackOffice/Shared/NavMenu.razor`
|
|
||||||
- `BackOffice/Pages/Blog/BlogHub.razor`
|
|
||||||
|
|
||||||
### ۱۳.۷ — تولید خودکار کلید سکشن ✅
|
|
||||||
|
|
||||||
- **مشکل:** کاربر باید کلید سکشن صفحه سایت را دستی وارد میکرد (مثلاً `about-us-section`)
|
|
||||||
- **رفع:** فیلد اختیاری شد، تولید خودکار `section-{GUID}` (حداکثر ۲۰ کاراکتر) در هندلر CMS
|
|
||||||
- **فایلها:**
|
|
||||||
- `CMS/.../SitePageCQ/Commands/CreateSitePageSection/CreateSitePageSectionCommandHandler.cs`
|
|
||||||
- `CMS/.../SitePageCQ/Commands/CreateSitePageSection/CreateSitePageSectionCommandValidator.cs`
|
|
||||||
- `BackOffice/Pages/Content/Components/SitePageSectionEditDialog.razor`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۲ — فیکس فلوی ثبتنام / ورود FrontOffice (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** رفع ۳ باگ بحرانی در فلوی ثبتنام و ورود FrontOffice
|
|
||||||
> **مستند کامل:** [`totalDoc/cms/REGISTRATION-FLOW-FIXES.md`](../../totalDoc/cms/REGISTRATION-FLOW-FIXES.md)
|
|
||||||
|
|
||||||
### ۱۲.۱ — رفع ایجاد کاربر جدید در VerifyOtpToken 🔴 ✅
|
|
||||||
|
|
||||||
- **مشکل:** `UserCQ/VerifyOtpTokenCommandHandler` کاربران جدید ایجاد نمیکرد — فقط خطای «کاربر یافت نشد»
|
|
||||||
- **رفع:** اضافه شدن لاجیک کامل: اعتبارسنجی کد معرف، بررسی ظرفیت درخت باینری (حداکثر ۲ فرزند)، تعیین شاخه (چپ/راست)، ایجاد User + UserRole + UserWallet، رویدادهای دامنه
|
|
||||||
- **فایل:** `CMS/src/CMSMicroservice.Application/UserCQ/Commands/VerifyOtpToken/VerifyOtpTokenCommandHandler.cs`
|
|
||||||
|
|
||||||
### ۱۲.۲ — رفع جستجوی موبایل در AcceptContract 🔴 ✅
|
|
||||||
|
|
||||||
- **مشکل:** `_currentUserService.Username` = `"{FirstName} {LastName}"` — نه شماره موبایل! در نتیجه OTP و کاربر هیچوقت پیدا نمیشد
|
|
||||||
- **رفع:** ابتدا کاربر از `UserId` پیدا شود، سپس `user.Mobile` برای جستجوی OTP استفاده شود
|
|
||||||
- **فایل:** `CMS/src/CMSMicroservice.Application/UserCQ/Commands/AcceptContract/AcceptContractCommandHandler.cs`
|
|
||||||
|
|
||||||
### ۱۲.۳ — رفع `IsCompleteRegister()` در FrontOffice 🟡 ✅
|
|
||||||
|
|
||||||
- **مشکل:** `InitUserAuthInfo().GetAwaiter()` بدون `.GetResult()` — عملیات async اجرا نمیشود، منوی کناری وضعیت نادرست
|
|
||||||
- **رفع:** تغییر به `InitUserAuthInfo().GetAwaiter().GetResult()`
|
|
||||||
- **فایل:** `FrontOffice/src/FrontOffice.Main/Utilities/AuthService.cs`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۱ — رفع خطای صفحات + سرویس عمومی تصاویر (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** رفع خطای ۳ صفحه BackOffice + ایجاد اندپوینت HTTP عمومی برای سرو تصاویر
|
|
||||||
|
|
||||||
### ۱۱.۱ — سرویس عمومی سرو تصاویر (CMS) ✅
|
|
||||||
|
|
||||||
- **`UploadsController`** — اندپوینت `GET /uploads/{path}` برای سرو مستقیم فایلها
|
|
||||||
- `[AllowAnonymous]` — بدون نیاز به احراز هویت
|
|
||||||
- کش مرورگر ۲۴ ساعته (`ResponseCache`)
|
|
||||||
- پشتیبانی از Range Requests
|
|
||||||
- **FMS Fallback:** اگر فایل محلی نباشد، از `dl.afrino.co` دانلود و کش میشود
|
|
||||||
- `IHttpClientFactory` با named client `"FMS"` (timeout: 30s)
|
|
||||||
- **فایلها:** `CMS/WebApi/Controllers/UploadsController.cs`, `CMS/WebApi/Program.cs`
|
|
||||||
|
|
||||||
### ۱۱.۲ — رفع صفحه «صفحات سایت» ✅
|
|
||||||
|
|
||||||
- اضافه شدن **دکمه «افزودن صفحه جدید»** به بالای صفحه
|
|
||||||
- اضافه شدن **دکمه «حذف»** (آیکون قرمز) برای هر ردیف
|
|
||||||
- ایجاد **`SitePageCreateDialog`** — دیالوگ ایجاد صفحه جدید با فیلدها:
|
|
||||||
- کلید صفحه (PageKey)، عنوان، توضیحات متا، عنوان هیرو، زیرعنوان هیرو، تصویر هیرو، وضعیت
|
|
||||||
- Proto: اضافه شدن `CreateSitePage` و `DeleteSitePage` RPC
|
|
||||||
- CQRS: `CreateSitePageCommand/Handler` و `DeleteSitePageCommand/Handler`
|
|
||||||
- **فایلها:**
|
|
||||||
- `sitepage.proto` — 2 RPC جدید + پیامهای Request/Response
|
|
||||||
- `SitePageCQ/Commands/CreateSitePage/` — Command + Handler
|
|
||||||
- `SitePageCQ/Commands/DeleteSitePage/` — Command + Handler
|
|
||||||
- `CMS/WebApi/Services/SitePageService.cs` — 2 override جدید
|
|
||||||
- `BackOffice/Services/Content/ISitePageService.cs` — `CreateAsync` + `DeleteAsync` + `SitePageCreateDto`
|
|
||||||
- `BackOffice/Services/Content/SitePageService.cs` — پیادهسازی Create/Delete
|
|
||||||
- `BackOffice/Pages/Content/SitePageManagementPage.razor` — دکمههای Add/Delete
|
|
||||||
- `BackOffice/Pages/Content/SitePageManagementPage.razor.cs` — متدهای CreatePage/DeletePage
|
|
||||||
- `BackOffice/Pages/Content/Components/SitePageCreateDialog.razor` + `.razor.cs`
|
|
||||||
|
|
||||||
### ۱۱.۳ — رفع صفحه «قراردادها» (Contracts) ✅
|
|
||||||
|
|
||||||
- **مشکل:** صفحه `/contracts` اصلاً بارگذاری نمیشد — crash در DI
|
|
||||||
- **علت:** `UserContractContract.UserContractContractClient` در DI ثبت نشده بود
|
|
||||||
- **رفع:** اضافه شدن `using CMSMicroservice.Protobuf.Protos.UserContract` و ثبت gRPC client
|
|
||||||
- **فایل:** `BackOffice/Common/Configure/ConfigureService.cs`
|
|
||||||
|
|
||||||
### ۱۱.۴ — رفع صفحه «کیف پول کاربران» (Wallets) ✅
|
|
||||||
|
|
||||||
- **مشکل:** صفحه `/wallets` اصلاً بارگذاری نمیشد — crash در DI
|
|
||||||
- **علت:** دو سرویس ثبت نشده بود:
|
|
||||||
- `UserWalletContract.UserWalletContractClient`
|
|
||||||
- `UserWalletChangeLogContract.UserWalletChangeLogContractClient`
|
|
||||||
- **رفع:** اضافه شدن usingها و ثبت هر دو gRPC client
|
|
||||||
- **فایل:** `BackOffice/Common/Configure/ConfigureService.cs`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۱۰ — بهبود مدیریت محتوا: بلاگ + صفحات سایت (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **هدف:** فعالسازی آپلود تصویر باینری و ادیتور HTML در صفحات بلاگ و صفحات سایت
|
|
||||||
|
|
||||||
### ۱۰.۱ — بهبود ادیتور پست بلاگ ✅
|
|
||||||
|
|
||||||
- **`MudTextField Lines="10"`** → **`MudHtmlEditor`** برای ویرایش محتوای HTML
|
|
||||||
- **فیلد متنی مسیر تصویر** → **`MudFileUpload`** با پیشنمایش تصویر (`Image` component)
|
|
||||||
- حذف فیلد `FeaturedImageThumbnailPath` (تولید خودکار توسط بکاند)
|
|
||||||
- اضافه شدن `MudForm` با اعتبارسنجی + حالت بارگذاری (`_loading`)
|
|
||||||
- مدیریت خطا: try-catch + Snackbar
|
|
||||||
- **فایلها:** `Pages/Blog/Components/BlogPostEditDialog.razor` + `.razor.cs`
|
|
||||||
|
|
||||||
### ۱۰.۲ — بهبود ادیتور صفحه سایت ✅
|
|
||||||
|
|
||||||
- **فیلد متنی Hero Image** → **`MudFileUpload`** با پیشنمایش تصویر
|
|
||||||
- اضافه شدن `MudForm` + حالت آپلود + مدیریت خطا
|
|
||||||
- **فایلها:** `Pages/Content/Components/SitePageEditDialog.razor` + `.razor.cs`
|
|
||||||
|
|
||||||
### ۱۰.۳ — بهبود ادیتور بخش صفحه سایت (Section) ✅
|
|
||||||
|
|
||||||
- **`MudTextField Lines="8"`** → **`MudHtmlEditor`** برای ویرایش محتوای HTML بخشها
|
|
||||||
- **فیلدهای متنی تصویر/thumbnail** → **`MudFileUpload`** با پیشنمایش
|
|
||||||
- اضافه شدن `MudForm` + حالت آپلود + مدیریت خطا
|
|
||||||
- **فایلها:** `Pages/Content/Components/SitePageSectionEditDialog.razor` + `.razor.cs`
|
|
||||||
|
|
||||||
### ۱۰.۴ — تغییرات Proto ✅
|
|
||||||
|
|
||||||
| Proto | تغییر |
|
|
||||||
|-------|-------|
|
|
||||||
| `blogpost.proto` | اضافه شدن `BlogImageFileModel` + فیلد `image_file` در Create/Update |
|
|
||||||
| `sitepage.proto` | اضافه شدن `SitePageImageFileModel` + فیلد `image_file` در Update/CreateSection/UpdateSection |
|
|
||||||
|
|
||||||
### ۱۰.۵ — تغییرات CQRS (بکاند CMS) ✅
|
|
||||||
|
|
||||||
- **Commands:** اضافه شدن `ImageFileBytes`, `ImageMime`, `ImageFileName` به:
|
|
||||||
- `CreateBlogPostCommand`, `UpdateBlogPostCommand`
|
|
||||||
- `UpdateSitePageCommand`, `CreateSitePageSectionCommand`, `UpdateSitePageSectionCommand`
|
|
||||||
- **Handlers:** تزریق `IFileManager` + فراخوانی `UploadImageAsync`:
|
|
||||||
- BlogPost → `Images/BlogPosts/`
|
|
||||||
- SitePage → `Images/SitePages/`
|
|
||||||
- SitePageSection → `Images/SitePageSections/`
|
|
||||||
|
|
||||||
### ۱۰.۶ — تغییرات سرویسهای BackOffice ✅
|
|
||||||
|
|
||||||
- `BlogPostService.cs` — ارسال `BlogImageFileModel` با `ByteString.CopyFrom(dto.ImageFile)`
|
|
||||||
- `SitePageService.cs` — ارسال `SitePageImageFileModel` در Update/CreateSection/UpdateSection
|
|
||||||
- **DTOs:** اضافه شدن `ImageFile`, `ImageMime`, `ImageFileName` به `BlogPostEditDto`, `SitePageEditDto`, `SitePageSectionEditDto`
|
|
||||||
|
|
||||||
### خلاصه آمار فاز ۱۰
|
|
||||||
| معیار | تعداد |
|
|
||||||
|---|---|
|
|
||||||
| فایلهای proto تغییریافته | 2 |
|
|
||||||
| Commandهای بروزشده | 5 |
|
|
||||||
| Handlerهای بروزشده | 5 |
|
|
||||||
| سرویسهای gRPC تغییریافته | 2 (BlogPostService + SitePageService) |
|
|
||||||
| دیالوگهای UI بازنویسیشده | 3 (BlogPost, SitePage, SitePageSection) |
|
|
||||||
| سرویسهای BackOffice بروزشده | 2 |
|
|
||||||
| DTOهای بروزشده | 3 |
|
|
||||||
| Build | 0 Error ✅ (هر ۳ پروژه) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۹ — معماری مدیریت فایل + رفع سفارشات + مهاجرت DB (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **مستند کامل معماری فایل:** [`totalDoc/cms/FILE-MANAGEMENT-ARCHITECTURE.md`](../../totalDoc/cms/FILE-MANAGEMENT-ARCHITECTURE.md)
|
|
||||||
|
|
||||||
### ۹.۱ — حذف کد مرده FMS ✅
|
|
||||||
- حذف ۳ فایل غیرقابل استفاده مرتبط با FMS خارجی (`https://dl.afrino.co`):
|
|
||||||
|
|
||||||
| فایل حذفشده | شرح |
|
|
||||||
|-------------|------|
|
|
||||||
| `Infrastructure/Services/FmsFileManager.cs` | پیادهسازی HTTP upload به FMS |
|
|
||||||
| `Application/Common/FileManager/FileManagementService.cs` | سرویس قدیمی مدیریت فایل |
|
|
||||||
| `Application/Common/FileManager/IFileManagementService.cs` | اینترفیس قدیمی |
|
|
||||||
|
|
||||||
### ۹.۲ — رفع صفحه سفارشات (Orders) ✅
|
|
||||||
|
|
||||||
**مشکل ۱ — صفحه خالی (بدون پیغام خطا)**
|
|
||||||
- **علت:** `ServerReload` بدون try-catch — exceptionهای gRPC ساکت میشدند
|
|
||||||
- **رفع:** اضافه شدن try-catch + نمایش خطا با Snackbar
|
|
||||||
- **فایل:** `Pages/UserOrder/UserOrderMainPage.razor.cs`
|
|
||||||
|
|
||||||
**مشکل ۲ — Shadow FK تکراری در OrderVAT**
|
|
||||||
- **علت:** `.WithOne()` بدون inverse navigation → EF Core یک shadow FK اضافی میساخت
|
|
||||||
- **رفع:** `.WithOne()` → `.WithOne(x => x.OrderVAT)`
|
|
||||||
- **فایل:** `Persistence/Configurations/OrderVATConfiguration.cs`
|
|
||||||
|
|
||||||
**مشکل ۳ — فیلترهای oneof همیشه فعال**
|
|
||||||
- **علت:** فیلدهای proto `oneof` مقدار پیشفرض enum دارند (هیچوقت null نیستند)، پس `PaymentStatus != null` همیشه true بود
|
|
||||||
- **رفع:** `PaymentStatus != null` → `HasPaymentStatus == true` (و مشابه برای DeliveryStatus و PaymentMethod)
|
|
||||||
- **فایلها:** `UserOrderService.cs` — هر دو متد `GetAllUserOrderByFilter` و `GetCustomerOrders`
|
|
||||||
|
|
||||||
### ۹.۳ — مهاجرت DB: حذف محدودیت طول ستونهای تصویر ✅
|
|
||||||
|
|
||||||
- **علت:** data URIهای base64 بزرگتر از `nvarchar(500)` بودند → truncation خاموش
|
|
||||||
- **رفع:** حذف `HasMaxLength(500)` از تمام ستونهای image path
|
|
||||||
- **Migration:** `RemoveImagePathMaxLength`
|
|
||||||
|
|
||||||
| Entity | ستونها |
|
|
||||||
|--------|---------|
|
|
||||||
| Product | `ImagePath`, `ImageThumbnailPath` |
|
|
||||||
| DiscountProduct | `ImagePath`, `ImageThumbnailPath` |
|
|
||||||
| Category | `ImagePath` |
|
|
||||||
| DiscountCategory | `ImagePath` |
|
|
||||||
| BlogPost | `FeaturedImagePath`, `FeaturedImageThumbnailPath` |
|
|
||||||
| SitePage | `HeroImagePath` |
|
|
||||||
| SitePageSection | `ImagePath`, `ImageThumbnailPath` |
|
|
||||||
|
|
||||||
### ۹.۴ — بازنویسی کامل مدیریت فایل: ذخیره دیسکی ✅
|
|
||||||
|
|
||||||
**معماری قبلی:** ذخیره data URI مستقیم در DB (ناکارآمد + حجم بالا)
|
|
||||||
|
|
||||||
**معماری جدید:**
|
|
||||||
1. فایلها در دیسک ذخیره میشوند: `Uploads/Images/{folder}/{guid}.jpg`
|
|
||||||
2. مسیر نسبی در DB ذخیره میشود
|
|
||||||
3. `ImagePathResolverInterceptor` هنگام serve تبدیل به base64 میکند
|
|
||||||
|
|
||||||
**فایلهای اصلی:**
|
|
||||||
|
|
||||||
| فایل | شرح |
|
|
||||||
|------|------|
|
|
||||||
| `Application/Common/FileManager/IFileManager.cs` | اینترفیس: Upload, UploadImage, Delete, ResolveImageUrl |
|
|
||||||
| `Infrastructure/Services/LocalFileManager.cs` | پیادهسازی: ImageSharp, main 1200×1200 + thumb 300×300, JPEG Q75 |
|
|
||||||
| `WebApi/Interceptors/ImagePathResolverInterceptor.cs` | gRPC Interceptor: walk بازگشتی response → تبدیل path به data URI |
|
|
||||||
|
|
||||||
**تنظیمات:**
|
|
||||||
- `FileStorage:UploadPath` → پوشه ریشه آپلود (پیشفرض: `AppContext.BaseDirectory/Uploads`)
|
|
||||||
- gRPC MaxReceiveMessageSize: 50MB
|
|
||||||
|
|
||||||
### ۹.۵ — پاکسازی LoggingBehaviour ✅
|
|
||||||
|
|
||||||
- **قبل:** فیلدهای باینری (byte[] تصاویر) کامل در لاگ چاپ میشدند → لاگهای چند مگابایتی
|
|
||||||
- **بعد:**
|
|
||||||
- فرمت: `JsonFormatter.Default.Format()` به جای `{@Request}`
|
|
||||||
- Regex: حذف فیلدهای باینری (`File`, `ImageFile`, `image_file`, `file`)
|
|
||||||
- محدودیت: حداکثر 2000 کاراکتر
|
|
||||||
- **فایل:** `WebApi/Common/Behaviours/LoggingBehaviour.cs`
|
|
||||||
|
|
||||||
### خلاصه آمار فاز ۹
|
|
||||||
| معیار | تعداد |
|
|
||||||
|---|---|
|
|
||||||
| فایلهای حذفشده (کد مرده) | 3 |
|
|
||||||
| فایلهای جدید | 2 (LocalFileManager بازنویسی + ImagePathResolverInterceptor) |
|
|
||||||
| فایلهای ویرایششده | ~12 |
|
|
||||||
| باگهای رفعشده | 4 (Orders page ×3 + DB truncation) |
|
|
||||||
| Migrationهای جدید | 1 (RemoveImagePathMaxLength) |
|
|
||||||
| ستونهای DB تغییریافته | 9 (nvarchar(500) → nvarchar(max)) |
|
|
||||||
| Build | 0 Error ✅ (هر ۳ پروژه) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۸ — یکسانسازی فروشگاه عادی و تخفیفی (بهمن ۱۴۰۴)
|
|
||||||
|
|
||||||
> **مستند کامل:** [`totalDoc/ui-modernization/BACKOFFICE-STORE-UNIFICATION.md`](../../totalDoc/ui-modernization/BACKOFFICE-STORE-UNIFICATION.md)
|
|
||||||
|
|
||||||
### ۸.۱ — بازسازی NavMenu ✅
|
|
||||||
- ایجاد دو NavGroup مجزا: «فروشگاه عادی» و «فروشگاه تخفیفی»
|
|
||||||
- حذف «ویرایش دستهجمعی» از منو
|
|
||||||
- انبارداری → گروه مستقل | پکیجها → آیتم مستقل
|
|
||||||
- **فایل:** `Shared/NavMenu.razor`
|
|
||||||
|
|
||||||
### ۸.۲ — حذف گزارشهای کوچک از سفارشات ✅
|
|
||||||
- حذف کارتهای آماری (TotalOrders + TotalAmount) و نمودار Bar ارسال
|
|
||||||
- حذف فیلدها: `_stats`, `_statusChartLabels`, `_statusChartSeries`
|
|
||||||
- حذف متد `UpdateStats()` و کلاس `OrderStatsViewModel`
|
|
||||||
- عنوان: «سفارشهای کاربر» → «لیست سفارشات»
|
|
||||||
- **فایلها:** `Pages/UserOrder/UserOrderMainPage.razor` + `.razor.cs`
|
|
||||||
|
|
||||||
### ۸.۳ — رفع باگ لیست خالی سفارشات ✅
|
|
||||||
- **علت:** `PaymentDate.ToDateTime()` بدون null check → exception ساکت در WASM
|
|
||||||
- **رفع:** `@if (context.Item.PaymentDate != null)` + fallback "-"
|
|
||||||
- **فایل:** `Pages/UserOrder/UserOrderMainPage.razor`
|
|
||||||
|
|
||||||
### ۸.۴ — بازنویسی صفحه محصولات تخفیفی ✅
|
|
||||||
- تبدیل به `BasePageComponent` (مطابق فروشگاه عادی)
|
|
||||||
- فیلترهای جدید: وضعیت + موجودی
|
|
||||||
- ستونهای جدید: تصویر inline + عنوان truncate + چیپ رنگی موجودی + چیپ وضعیت
|
|
||||||
- **فایلها:** `Pages/DiscountShop/DiscountProductsMainPage.razor` + `.razor.cs` (بازنویسی کامل)
|
|
||||||
|
|
||||||
### ۸.۵ — بازنویسی صفحه دستهبندیهای تخفیفی ✅
|
|
||||||
- تبدیل به `BasePageComponent` (مطابق فروشگاه عادی)
|
|
||||||
- ستونهای جدید: نام لاتین، دستهبندی والد (resolve شده)، تعداد محصولات، ترتیب
|
|
||||||
- code-behind جدید (`@code` درونخطی → `.razor.cs`)
|
|
||||||
- **فایلها:** `Pages/DiscountShop/DiscountCategoriesMainPage.razor` + `.razor.cs` (بازنویسی کامل)
|
|
||||||
|
|
||||||
### خلاصه آمار فاز ۸
|
|
||||||
| معیار | تعداد |
|
|
||||||
|---|---|
|
|
||||||
| فایلهای بازنویسیشده | 4 |
|
|
||||||
| فایلهای ویرایششده | 3 |
|
|
||||||
| باگهای رفعشده | 2 (PaymentDate null + لیست خالی) |
|
|
||||||
| Build | 0 Error ✅ |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🏷 فاز ۷ — پس از اجرای Audit v7.0 (تیر ۱۴۰۴)
|
|
||||||
|
|
||||||
### خلاصه تغییرات
|
|
||||||
- **۵۷ مورد** از ۵۸ یافته audit اجرا شد (≈98%)
|
|
||||||
- **تمام ۱۶ مورد بحرانی 🔴** حل شد
|
|
||||||
- **تمام ۱۸ مورد جزئی 🟢** حل شد
|
|
||||||
- **فازهای ۱ تا ۶ تکمیل شدند** (بهجز DayaLoan و Audit Trail که نیاز به بکاند دارند)
|
|
||||||
- **فاز ۷** — Global Search, Notification Bell, NavMenu Badge, Export Excel 4 صفحه جدید
|
|
||||||
- **۱۳+ فایل جدید** ساخته شد
|
|
||||||
- **۹ صفحه** ادغام شدند (۱۴ صفحه → ۵ صفحه)
|
|
||||||
- **Build**: 0 error ✅
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۷ — Global Search + Notifications + Export All + NavMenu Badge (v7.0)
|
|
||||||
|
|
||||||
### 6.5 — Badge Pending در NavMenu — ✅
|
|
||||||
- **`NavMenu.razor`**: اضافه شدن `MudBadge` روی لینک «درخواستهای برداشت»
|
|
||||||
- نمایش تعداد درخواستهای Pending بصورت real-time از gRPC (`CommissionContract.GetWithdrawalRequestsAsync` با `Status=0`)
|
|
||||||
- fire-and-forget در `OnInitializedAsync` با try/catch silent
|
|
||||||
|
|
||||||
### 6.2 — Global Search در AppBar — ✅
|
|
||||||
- **فایل جدید**: `Shared/GlobalSearch.razor`
|
|
||||||
- `MudAutocomplete<SearchResultItem>` با Debounce 400ms
|
|
||||||
- دو نوع جستجو: ۱) نام صفحات (۱۵ صفحه اصلی) ۲) کاربران از gRPC (`UserContract.GetAllUserByFilterAsync`)
|
|
||||||
- Template سفارشی با آیکون + عنوان + زیرنویس
|
|
||||||
- ناوبری خودکار با `Navigation.NavigateTo`
|
|
||||||
- اضافه شده در `MainLayout.razor` داخل `<AuthorizeView>`
|
|
||||||
- CSS در `app.css` — rounded border-radius 24px, compact padding
|
|
||||||
|
|
||||||
### 6.1 — Notification Bell (placeholder) — ✅
|
|
||||||
- **`MainLayout.razor`**: اضافه شدن `MudMenu` + `MudBadge` (Dot) + آیکون Notifications
|
|
||||||
- Dropdown با هدر «اعلانها» + placeholder «اعلان جدیدی وجود ندارد»
|
|
||||||
- آماده اتصال به بکاند — فقط `Visible=true` و populate items
|
|
||||||
|
|
||||||
### 6.3 — Export Excel صفحات جدید — ✅ (۱۰ صفحه کامل)
|
|
||||||
- **۴ صفحه جدید** اضافه شدند به ۶ صفحه قبلی:
|
|
||||||
1. **UserMainPage** — خروجی CSV: شناسه, موبایل, نام, نام خانوادگی, کدملی
|
|
||||||
2. **DiscountOrdersMainPage** — خروجی CSV: شماره سفارش, تاریخ, مبلغ کل, تخفیف, قابل پرداخت, تعداد, وضعیت, پرداخت
|
|
||||||
3. **ManualPayments** — خروجی CSV: شناسه, شناسه کاربر, نام کاربر, مبلغ, نوع, وضعیت, تاریخ
|
|
||||||
4. **InventoryMainPage** — خروجی CSV: شناسه, محصول, انبار, موجودی, رزرو, قابل فروش, حد هشدار, وضعیت
|
|
||||||
- هر ۴ صفحه: دکمه «خروجی Excel» + `ExportToExcel()` + `EscapeCsv()` + UTF-8 BOM + `jsSaveAsFile`
|
|
||||||
- فایلهای code-behind جدید: `ManualPayments.razor.cs`, `DiscountOrdersMainPage.razor.cs`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۶ — تاریخ شمسی + تاریخچهها + Export Excel (v6.0)
|
|
||||||
|
|
||||||
### تاریخ شمسی یکپارچه (3.6) — ✅ کامل
|
|
||||||
- **۱۹+ فایل** آپدیت شدند: تمام تاریخها از فرمت میلادی (`yyyy/MM/dd`) به شمسی تبدیل شدند
|
|
||||||
- از extension methodهای `DateTimeConverterCL` استفاده شد:
|
|
||||||
- `.MiladiToJalali()` — فرمت تاریخ فقط (مثال: ۱۴۰۴/۰۴/۱۲)
|
|
||||||
- `.MiladiToJalaliWithTime()` — فرمت تاریخ و ساعت
|
|
||||||
- **صفحات اصلاحشده شامل**: Club (Members, Statistics, Features, MemberDetailsDialog)، Commission (Dashboard, WeeklyReports, WithdrawalRequests, Payouts, WithdrawalReports)، Network (UserNetworkInfo, BalancesReport, Statistics, NetworkTreeViewer)، UserOrder, Products, Package, Inventory, DiscountShop, Blog, Content, و غیره
|
|
||||||
- `PropertyColumn Format="yyyy/MM/dd"` → `TemplateColumn` با `.MiladiToJalali()`
|
|
||||||
- `MudDatePicker DateFormat` تغییر نکرد (قابلیت تقویم شمسی نیاز به کتابخانه جداگانه دارد)
|
|
||||||
|
|
||||||
### تاریخچه عضویت باشگاه (5.7) — ✅
|
|
||||||
- **`MemberDetailsDialog.razor`**: تب تاریخچه با فیلدهای صحیح proto:
|
|
||||||
- ستونها: `Action`, `Created`, `PackageName`, `Reason`, `PerformedBy`
|
|
||||||
- Request: `PageIndex = 0` (نه PageNumber)
|
|
||||||
|
|
||||||
### تاریخچه تغییرات شبکه (5.8) — ✅
|
|
||||||
- **`UserNetworkInfo.razor`**: تب تاریخچه با فیلدهای تخصصی:
|
|
||||||
- ستونها: `Action`, `Created`, `OldParentId → NewParentId`, `OldNetworkLeg → NewNetworkLeg` (چپ/راست)
|
|
||||||
- ستون `Reason` و `PerformedBy` اضافه شد
|
|
||||||
- Request: `PageIndex = 0`
|
|
||||||
|
|
||||||
### لاگ اجرای Workerها (5.6) — ✅
|
|
||||||
- در تب WorkerControl از SystemHub قبلاً پیادهسازی شده بود
|
|
||||||
|
|
||||||
### Export Excel / CSV (6.3) — ✅ ۶ صفحه
|
|
||||||
قابلیت خروجی CSV (سازگار با Excel) به ۶ صفحه اصلی اضافه شد:
|
|
||||||
|
|
||||||
| صفحه | فایل(ها) | ستونهای خروجی |
|
|
||||||
|---|---|---|
|
|
||||||
| **Products** (قبلاً موجود) | ProductsMainPage.razor.cs | — |
|
|
||||||
| **Club Members** | ClubMembers.razor + .razor.cs | شناسه,کاربر,نام,پکیج,کد فعالسازی,تاریخ فعالسازی,تاریخ انقضا,فعال,منقضی |
|
|
||||||
| **Withdrawal Requests** | WithdrawalRequests.razor + .razor.cs | شناسه,کاربر,نام,مبلغ,وضعیت,روش,شبا,تاریخ درخواست,تاریخ پردازش,مرجع بانکی |
|
|
||||||
| **Weekly Reports** | WeeklyReports.razor + .razor.cs | هفته,مبلغ استخر,موجودیها,ارزش,وضعیت,تاریخ محاسبه |
|
|
||||||
| **User Orders** | UserOrderMainPage.razor + .razor.cs | شناسه,کاربر,نام,مبلغ,وضعیت پرداخت,وضعیت ارسال,روش پرداخت,تاریخ |
|
|
||||||
| **Stock Movements** | MovementsPage.razor + .razor.cs | شناسه,محصول,نوع,تعداد,قبل,بعد,مرجع,یادداشت,تاریخ |
|
|
||||||
|
|
||||||
**الگوی پیادهسازی:**
|
|
||||||
- دکمه `<MudButton>` با آیکون `FileDownload` در ToolBarContent
|
|
||||||
- `StringBuilder` → CSV با هدرهای فارسی
|
|
||||||
- UTF-8 BOM (`Encoding.UTF8.GetPreamble()`) برای نمایش صحیح فارسی در Excel
|
|
||||||
- `jsSaveAsFile(filename, base64)` از `wwwroot/js/main.js`
|
|
||||||
- متد `EscapeCsv()` برای مقادیر حاوی کاما/کوتیشن
|
|
||||||
- تاریخها در خروجی نیز شمسی هستند
|
|
||||||
|
|
||||||
### فایلهای جدید (این نسخه)
|
|
||||||
|
|
||||||
| فایل | عملکرد |
|
|
||||||
|---|---|
|
|
||||||
| `Pages/Commission/WeeklyReports.razor.cs` | Code-behind برای export (بهدلیل محدودیت Razor parser با escaped quotes) |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## نسخه قبلی — Audit v5.0 (خرداد ۱۴۰۴)
|
|
||||||
|
|
||||||
### تم رنگی یکپارچه
|
|
||||||
- **`CustomMudTheme.cs`**: تم Primary از `#0380C0` به `#6366f1` (Indigo) تغییر کرد — هماهنگ با FrontOffice
|
|
||||||
- **`PaletteDark`** اضافه شد: Surface `#1a1a2e`, Background `#16213e`, AppbarBackground `#0f3460`
|
|
||||||
- **`app.css`**: رنگ loading از `#1b6ec2` به `var(--mud-palette-primary)` تغییر کرد
|
|
||||||
- **`NavMenu.razor.css`**: رنگ active از `#0380C0` هاردکد به CSS variable تغییر کرد
|
|
||||||
- **`MainLayout.razor`**: حذف inline style `border: 1px solid #5e4df9`
|
|
||||||
|
|
||||||
### Dark Mode Toggle
|
|
||||||
- آیکون ماه/آفتاب در AppBar اضافه شد
|
|
||||||
- `_isDarkMode` state با `MudThemeProvider` اتصال دارد
|
|
||||||
- تعویض بین `PaletteLight` و `PaletteDark` در CustomMudTheme
|
|
||||||
|
|
||||||
### عنوان اپلیکیشن
|
|
||||||
- "پنل مدیریت **فرصت**" → "پنل مدیریت **کارا بازار سلامت**"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۲ — بازطراحی لایوت صفحات
|
|
||||||
|
|
||||||
### BasePageComponent بازنویسی کامل
|
|
||||||
- **قبل**: فیلتر ثابت سمت راست (20%) + جدول (80%)، ارتفاع 85vh هاردکد
|
|
||||||
- **بعد**: فیلتر collapsible بالای جدول، فیلدها در `MudGrid` با `MudItem`، responsive
|
|
||||||
- **۱۳ صفحه** آپدیت شدند: User, Products, Package, Category, UserOrder, UserAddress, UserRole, Role, BlogPost, BlogCategory, Tag, Transactions, Content
|
|
||||||
|
|
||||||
### DataGrid Height یکسانسازی
|
|
||||||
- همه DataGridها: `Height="calc(100vh - 240px)"`
|
|
||||||
- **صفحات اصلاحشده**: تمام ~33 صفحه دارای DataGrid
|
|
||||||
|
|
||||||
### Pager یکسانسازی
|
|
||||||
- **PageSize**: همه `20, 50, 100`
|
|
||||||
- **متن فارسی**: `RowsPerPageString="تعداد در صفحه"` و `InfoFormat="سطر {first_item} تا {last_item} از {all_items}"`
|
|
||||||
|
|
||||||
### MaxWidth یکسانسازی
|
|
||||||
- `MainLayout.razor` MudContainer wrapper اضافه شد → MaxWidth یکسان برای همه صفحات
|
|
||||||
- **۳۱ صفحه**: حذف `MudContainer` تکراری (double nesting)
|
|
||||||
|
|
||||||
### Breadcrumb
|
|
||||||
- **`Shared/AppBreadcrumb.razor`** ساخته شد
|
|
||||||
- جداکننده چپبهراست (`ChevronLeft`)
|
|
||||||
- نقشه فارسی URL segments (60+ مسیر)
|
|
||||||
- آخرین آیتم disabled (صفحه فعلی)
|
|
||||||
|
|
||||||
### Login + VerifyCode بازطراحی
|
|
||||||
- عرض ثابت 35% → responsive `MaxWidth.Small`
|
|
||||||
- لوگو + برندینگ "کارا بازار سلامت" اضافه شد
|
|
||||||
- طراحی gradient background
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۲.۵ — پاکسازی ساختاری
|
|
||||||
|
|
||||||
### NavMenu بازسازی کامل
|
|
||||||
- **لینک مرده `categories-dragdrop`**: حذف شد
|
|
||||||
- **Transactions**: حذف از NavMenu (صفحه stub خالی)
|
|
||||||
- **AlertsMonitoring**: حذف از NavMenu (100% mock)
|
|
||||||
- **WorkerControl**: به SystemHub منتقل شد (قبلاً لینک نداشت)
|
|
||||||
- **«پیامهای عمومی»**: از بخش فروشگاه تخفیفی به «مدیریت محتوا» منتقل شد
|
|
||||||
- **ساختار گروهبندی** اصلاح شد:
|
|
||||||
- کمیسیون و شبکه: NavGroup واضح
|
|
||||||
- باشگاه مشتریان: اعضا و آمار + فیچرها
|
|
||||||
- فروشگاه: پکیجها، محصولات (group)، سفارشها، فروشگاه تخفیفی (group)
|
|
||||||
- مدیریت: کاربران، نقشها، پرداخت دستی، **کیفپول (جدید)**، **قراردادها (جدید)**
|
|
||||||
- محتوا: بلاگ، صفحات سایت، پیامهای عمومی
|
|
||||||
- سیستم: مدیریت سیستم، نسخه اپها
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۳ — UX بهبودها
|
|
||||||
|
|
||||||
### NoRecordsContent (Empty State)
|
|
||||||
- **۳۳ DataGrid** آپدیت شدند
|
|
||||||
- پیام: `<MudAlert Severity="Info">موردی یافت نشد.</MudAlert>`
|
|
||||||
|
|
||||||
### Delete Confirmation با نام آیتم
|
|
||||||
- **۱۱ صفحه** اصلاح شدند:
|
|
||||||
- Role → `«{model.Title}»`
|
|
||||||
- User → `«{model.FirstName} {model.LastName}»`
|
|
||||||
- Package → `«{model.Title}»`
|
|
||||||
- UserAddress → `«{model.Title}»`
|
|
||||||
- UserRole → `شناسه «{model.Id}»`
|
|
||||||
- UserOrder → `شماره «{model.Id}»`
|
|
||||||
- Category → `«{model.Title}»`
|
|
||||||
- Products → `«{model.Title}»`
|
|
||||||
- DiscountCategories → `«{category?.Title}»` (lookup اضافه شد)
|
|
||||||
- DiscountProducts → `«{product?.Title}»` (lookup اضافه شد)
|
|
||||||
- PublicMessages → `«{message?.Title}»` (lookup اضافه شد)
|
|
||||||
|
|
||||||
### User Menu در AppBar
|
|
||||||
- `MudMenu` جایگزین متن ساده شماره موبایل شد
|
|
||||||
- آیتمها: نام کاربر (غیرفعال) + خروج
|
|
||||||
- آیکون `AccountCircle`
|
|
||||||
- خروج (`signout`) از NavMenu به AppBar منتقل شد
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۳.۵ — ادغام صفحات
|
|
||||||
|
|
||||||
### Dashboard Merge ← `Pages/Index.razor`
|
|
||||||
- **`Index.razor` + `SystemOverview.razor`** ادغام شدند
|
|
||||||
- Routes: `/` + `/dashboard/overview`
|
|
||||||
- بخشها:
|
|
||||||
- 6 کارت آمار CMS (کاربران، محصولات، پکیجها، دستهبندیها، سفارشها، مبلغ پرداختشده)
|
|
||||||
- آمار کمیسیون (هفته جاری، استخر، موجودیها، وضعیت محاسبه)
|
|
||||||
- آمار باشگاه (کل/فعال/غیرفعال)
|
|
||||||
- جدول آخرین ۵ سفارش پرداختشده
|
|
||||||
- ۶ دکمه Quick Action
|
|
||||||
- بارگذاری موازی با `Task.WhenAll` + `.ResponseAsync`
|
|
||||||
- `SystemOverview.razor` **حذف شد**
|
|
||||||
|
|
||||||
### DiscountShopHub ← `Pages/DiscountShop/DiscountShopHub.razor`
|
|
||||||
- Routes: `/discount-shop`, `/discount-orders`, `/discount-sales-reports`
|
|
||||||
- ۲ تب: DiscountOrdersMainPage + SalesReports
|
|
||||||
- انتخاب تب از URL
|
|
||||||
|
|
||||||
### ClubHub ← `Pages/Club/ClubHub.razor`
|
|
||||||
- Routes: `/club`, `/club/members`, `/club/statistics`
|
|
||||||
- ۲ تب: ClubMembers + Statistics
|
|
||||||
|
|
||||||
### BlogHub ← `Pages/Blog/BlogHub.razor`
|
|
||||||
- Routes: `/blog`, `/blog/posts`, `/blog/categories`, `/tags`
|
|
||||||
- ۳ تب: BlogPostManagementPage + BlogCategoryManagementPage + TagManagementPage
|
|
||||||
|
|
||||||
### SystemHub ← `Pages/SystemManagement/SystemHub.razor`
|
|
||||||
- Routes: `/system`, `/system/configuration`, `/system/worker-control`, `/system/health`
|
|
||||||
- ۳ تب: Configuration + WorkerControl + HealthDashboard
|
|
||||||
|
|
||||||
### ۱۰ صفحه — `@page` directive حذف شد
|
|
||||||
صفحاتی که به hub منتقل شدند دیگر route مستقل ندارند:
|
|
||||||
DiscountOrdersMainPage, SalesReports, ClubMembers, Statistics, BlogPostManagementPage, BlogCategoryManagementPage, TagManagementPage, Configuration, WorkerControl, HealthDashboard
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۴ — فیکسهای بیزینسی
|
|
||||||
|
|
||||||
### Dashboard آمار اصلاح شد
|
|
||||||
- **قبل**: آمار از ۱۰ رکورد اول محاسبه میشد (نادرست)
|
|
||||||
- **بعد**: از `metadata.TotalCount` و APIهای جداگانه استفاده میشود
|
|
||||||
|
|
||||||
### ManualPayments — تأیید/رد
|
|
||||||
- دکمههای Approve/Reject وقتی `Status==0` (در انتظار) نمایش داده میشوند
|
|
||||||
- Confirmation dialog قبل از اجرا
|
|
||||||
- از `ManualPaymentId` (نه `Id`) استفاده میشود
|
|
||||||
|
|
||||||
### UserOrder — فیلتر Cancelled
|
|
||||||
- `<MudSelectItem Value="@(5)">لغو شده</MudSelectItem>` اضافه شد
|
|
||||||
|
|
||||||
### WithdrawalRequests — بهبود کامل
|
|
||||||
- **Pager**: 10/25/50/100 → 20/50/100
|
|
||||||
- **`WithdrawalDetailsDialog.razor`** (جدید): نمایش کامل اطلاعات کاربر، درخواست، و بانکی
|
|
||||||
- **`RejectReasonDialog.razor`** (جدید): ورود دلیل رد با اعتبارسنجی
|
|
||||||
- ViewDetails: از Snackbar TODO به دیالوگ واقعی تغییر کرد
|
|
||||||
- RejectRequest: از دلیل هاردکد به دیالوگ custom تغییر کرد
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۵ — صفحات مفقود (CMS-Derived)
|
|
||||||
|
|
||||||
### WalletManagementPage ← `Pages/Wallet/WalletManagementPage.razor`
|
|
||||||
- Route: `/wallets`
|
|
||||||
- **تب ۱ — کیفپولها**: DataGrid با ServerData، فیلتر UserAutoComplete
|
|
||||||
- ستونها: شناسه، کاربر، موجودی اصلی، موجودی شبکه، مشاهده تغییرات
|
|
||||||
- نوع: `GetAllUserWalletByFilterResponseModel`
|
|
||||||
- **تب ۲ — تاریخچه تغییرات**: DataGrid با ServerData، فیلتر کاربر + نوع (افزایش/کاهش)
|
|
||||||
- ستونها: شناسه، کیفپول، نوع (چیپ رنگی)، تغییر موجودی، موجودی فعلی، تغییر شبکه، موجودی شبکه فعلی، شناسه مرجع، تاریخ
|
|
||||||
- نوع: `GetAllUserWalletChangeLogByFilterResponseModel`
|
|
||||||
- فیلدهای proto با typo: `ChangeNerworkValue`, `RefrenceId`
|
|
||||||
|
|
||||||
### UserContractPage ← `Pages/Contract/UserContractPage.razor`
|
|
||||||
- Route: `/contracts`
|
|
||||||
- DataGrid با ServerData، فیلتر UserAutoComplete
|
|
||||||
- ستونها: شناسه، کاربر، قرارداد، کد امضا، لینک PDF، جزئیات
|
|
||||||
- نوع: `GetAllUserContractByFilterResponseModel`
|
|
||||||
|
|
||||||
### ContractDetailsDialog ← `Pages/Contract/ContractDetailsDialog.razor`
|
|
||||||
- جدول ساده: شناسه، کاربر، قالب قرارداد، کد امضا، لینک دانلود PDF
|
|
||||||
|
|
||||||
### ClubFeaturesPage ← `Pages/Club/ClubFeaturesPage.razor`
|
|
||||||
- Route: `/club/features`
|
|
||||||
- **تب ۱ — فیچرهای تعریفشده**: کارتهای MudPaper با عنوان، توضیحات، وضعیت (فعال/غیرفعال)، ترتیب
|
|
||||||
- از `ConfigClient.GetClubFeaturesAsync`
|
|
||||||
- **تب ۲ — فیچرهای کاربران**: DataGrid با فیلتر کاربر، سوئیچ فعال/غیرفعال
|
|
||||||
- از `ClubClient.GetUserClubFeaturesAsync` + `ToggleUserClubFeatureAsync`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ نکات فنی مهم
|
|
||||||
|
|
||||||
### الگوهای Proto
|
|
||||||
- **فیلتر**: `new GetAllXxxByFilterFilter()` (سطح بالا، بدون `.Types.`)
|
|
||||||
- **پاسخ لیست**: `GetAllXxxByFilterResponseModel` (نه `GetXxxResponse`)
|
|
||||||
- **Typoها در proto**: `ChangeNerworkValue` و `RefrenceId` — باید دقیقاً همینها استفاده شوند
|
|
||||||
|
|
||||||
### _Imports.razor — سرویسهای Global
|
|
||||||
سرویسهای زیر از `_Imports.razor` تزریق میشوند و نباید در code-behind با `[Inject]` دوباره تعریف شوند:
|
|
||||||
- `NavigationManager Navigation`
|
|
||||||
- `ILocalStorageService LocalStorageService`
|
|
||||||
- `ISnackbar Snackbar`
|
|
||||||
- `IJSRuntime jsRuntime`
|
|
||||||
- `IDialogService DialogService`
|
|
||||||
- `AuthenticationStateProvider`
|
|
||||||
|
|
||||||
### MudBlazor محدودیتها
|
|
||||||
- `Variant.Flat` وجود ندارد → از `Variant.Text` استفاده شود
|
|
||||||
- `GutterSize` روی `MudGrid` deprecated است
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۴ (ادامه) — تکمیل فیکسهای بیزینسی
|
|
||||||
|
|
||||||
### UserSettings — حذف تبهای جعلی (2.5.5)
|
|
||||||
- **`UserSettings.razor`**: تب Notifications (۷ تاگل جعلی بدون بکاند) → placeholder «بهزودی فعال میشود» با آیکون NotificationsActive
|
|
||||||
- **`UserSettings.razor`**: تب Security (فرم تغییر رمز + 2FA بدون بکاند) → placeholder «بهزودی فعال میشود» با آیکون Lock
|
|
||||||
- **حذف کد مرده**: ~۱۵ متغیر notification/security + متدهای `SaveNotificationSettings()`, `SaveSecuritySettings()`, `ChangePassword()`
|
|
||||||
|
|
||||||
### HealthDashboard — حذف متریکهای Mock (2.5.6)
|
|
||||||
- **`HealthDashboard.razor`**: بخش System Resources (۴ کارت CPU=45.2%, Memory=62.8%, Disk=73.5%, Network) → یک کارت با پیام «مانیتورینگ منابع سیستم در نسخههای آینده با اتصال به Prometheus/Grafana فعال خواهد شد»
|
|
||||||
- **حذف کد مرده**: ۹ متغیر mock (`_cpuUsage`, `_memoryUsage`, etc.) + متد `GetResourceColor()`
|
|
||||||
|
|
||||||
### حذف cursor:pointer زائد (4.10)
|
|
||||||
- `Style="cursor:pointer;"` از **۱۷ فایل** حذف شد (MudButton/MudIconButton خودشان cursor:pointer دارند)
|
|
||||||
- شامل: ProductsMainPage, GalleryDialog, Image.razor (base component), RoleMainPage, UserOrderMainPage, PackageMainPage, etc.
|
|
||||||
|
|
||||||
### حذف Console.WriteLine (4.11)
|
|
||||||
- از **۱۱ فایل** حذف شد: DiscountProductService, DiscountCategoryService, NetworkTreeViewer, UserSettings, CategoryMainPage, UserOrderMainPage, Commission/Dashboard, DiscountProductsMainPage, DiscountCategoryMultiSelectCombo, UserRole/CreateDialog
|
|
||||||
- **`Commission/Dashboard.razor.cs`**: `using System.Text.Json` هم حذف شد (دیگر استفاده نمیشد)
|
|
||||||
|
|
||||||
### DiscountProducts — فیلتر دستهبندی (4.7)
|
|
||||||
- **`DiscountProductsMainPage.razor`**: `@inject IDiscountCategoryService` اضافه شد
|
|
||||||
- دستهبندیهای فعال از سرویس بارگذاری و در MudSelect نمایش داده میشوند
|
|
||||||
- جایگزینی `@* TODO: Load categories *@` با `@foreach` واقعی
|
|
||||||
|
|
||||||
### DiscountProducts — Items → ServerData (4.8)
|
|
||||||
- **`DiscountProductsMainPage.razor`**: تبدیل از `Items="@_products"` به `ServerData="LoadServerData"`
|
|
||||||
- متد `LoadServerData(GridState<T>)` اضافه شد با `PageNumber` و `PageSize` از state
|
|
||||||
- `Height="calc(100vh - 300px)"` + `FixedHeader="true"` اضافه شد
|
|
||||||
- Snackbar اطلاعرسانی اضافی در هر بارگذاری حذف شد (redundant)
|
|
||||||
|
|
||||||
### UserOrder — فعالسازی آمار (4.6)
|
|
||||||
- **`UserOrderMainPage.razor`**: بخش آمار (MudCard + MudChart) از حالت comment خارج شد
|
|
||||||
- نمایش تعداد سفارشها + مجموع مبلغ + نمودار Bar وضعیت ارسال
|
|
||||||
|
|
||||||
### UserSettings — persist با localStorage (4.9)
|
|
||||||
- تب General از قبل با localStorage کار میکرد ✅ (فقط تبهای جعلی حذف شدند)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## فاز ۴.۵ — Cross-Navigation
|
|
||||||
|
|
||||||
### لینک نام کاربر → پروفایل (4.5.1, 4.5.2)
|
|
||||||
- **`UserOrderMainPage.razor`**: ستون `UserFullName` از PropertyColumn به TemplateColumn تبدیل شد — MudLink به `/network/user-info/{UserId}`
|
|
||||||
- **`UserPayouts.razor`**: نام/شناسه کاربر به MudLink تبدیل شد → `/network/user-info/{UserId}`
|
|
||||||
- **`WithdrawalRequests.razor`**: نام کاربر به MudLink تبدیل شد → `/network/user-info/{UserId}`
|
|
||||||
|
|
||||||
### لینک محصول ↔ انبار (4.5.3, 4.5.4) — Skip
|
|
||||||
- صفحه جزئیات محصول وجود ندارد (فقط لیست + دیالوگ ویرایش)
|
|
||||||
- لینک cross-navigation بدون صفحه مقصد معنادار نیست
|
|
||||||
|
|
||||||
### Extract shared status helpers (3.5.6) — Skip
|
|
||||||
- بررسی نشان داد هر context مقادیر متفاوتی دارد:
|
|
||||||
- UserPayouts: status 1 = Success/پرداخت شده
|
|
||||||
- WithdrawalRequests: status 1 = Info/واریز شده
|
|
||||||
- PayoutDetailsDialog: فقط ۳ وضعیت (نه ۶)
|
|
||||||
- استخراج به helper مشترک باعث از دست رفتن معنای domain-specific میشود
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📈 آمار تغییرات
|
|
||||||
|
|
||||||
| معیار | تعداد |
|
|
||||||
|---|---|
|
|
||||||
| فایلهای جدید | 11 |
|
|
||||||
| فایلهای حذفشده | 1 (SystemOverview.razor) |
|
|
||||||
| فایلهای ویرایششده | ~65+ |
|
|
||||||
| DataGridهای آپدیتشده | 33 |
|
|
||||||
| Delete confirmation اصلاحشده | 11 |
|
|
||||||
| صفحات ادغامشده | 14 → 5 |
|
|
||||||
| خطاهای build حلشده | 9+ |
|
|
||||||
| Console.WriteLine حذفشده | 22+ (از ۱۱ فایل) |
|
|
||||||
| cursor:pointer حذفشده | 17 فایل |
|
|
||||||
| Cross-link اضافهشده | 3 صفحه (UserOrder, UserPayouts, WithdrawalRequests) |
|
|
||||||
|
|||||||
Reference in New Issue
Block a user