feat: Enhance CMS Microservice with SystemConstants and SmsTemplates
- Added SystemConstants class to centralize hardcoded values for club configuration, commission configuration, and package amounts. - Introduced SmsTemplates class to manage SMS message templates for various user notifications. - Implemented automatic SMS sending for Daya Loan approval notifications. - Updated BackOffice UI to include App Version management features. - Fixed mapping issues in Mapster profiles for improved data handling. - Updated changelog and documentation to reflect recent changes and configurations.
This commit is contained in:
@@ -0,0 +1,329 @@
|
||||
# 📝 Changelog - ۷ دی ۱۴۰۴ (27 December 2025)
|
||||
|
||||
> **Session**: بهینهسازیهای Mapping + SystemConstants + SMS Templates + AppVersion UI
|
||||
|
||||
---
|
||||
|
||||
## 🎯 خلاصه Session
|
||||
|
||||
این session شامل موارد زیر بود:
|
||||
1. **SystemConstants** - انتقال مقادیر ثابت از hardcode به کلاس مرکزی
|
||||
2. **SMS Templates** - متمرکز کردن همه قالبهای پیامک
|
||||
3. **SMS for Daya Loan** - ارسال پیامک هنگام تأیید وام دایا
|
||||
4. **AppVersion UI** - تکمیل صفحه مدیریت نسخه در BackOffice
|
||||
5. **Mapping Fixes** - رفع مشکلات Mapster
|
||||
|
||||
---
|
||||
|
||||
## ✨ تغییرات
|
||||
|
||||
### 1. 💰 SystemConstants - مقادیر ثابت ✅
|
||||
|
||||
**فایل**: `CMSMicroservice.Domain/Common/SystemConstants.cs`
|
||||
|
||||
```csharp
|
||||
public static class SystemConstants
|
||||
{
|
||||
// Club Configuration
|
||||
public const decimal ClubJoiningPercentage = 0.35m; // 35% کمیسیون پیوستن به باشگاه
|
||||
public const decimal ClubActivationThreshold = 0.5m; // 50% آستانه فعالسازی
|
||||
|
||||
// Commission Configuration
|
||||
public const int MaxCalculationAttempts = 3; // حداکثر تلاش محاسبه
|
||||
public const int DefaultCommissionPoolDays = 7; // روزهای استخر کمیسیون
|
||||
|
||||
// Package Amounts
|
||||
public const long GoldenPackageAmount = 56_000_000; // 56 میلیون - پکیج طلایی
|
||||
public const long DayaLoanAmount = 56_000_000; // 56 میلیون - وام دایا
|
||||
}
|
||||
```
|
||||
|
||||
**Handlers آپدیت شده**:
|
||||
| Handler | تغییر |
|
||||
|---------|-------|
|
||||
| `ProcessDayaLoanApprovalCommandHandler` | استفاده از `SystemConstants.DayaLoanAmount` |
|
||||
| `ValidateGoldenPackagePurchaseQueryHandler` | استفاده از `SystemConstants.GoldenPackageAmount` |
|
||||
| سایر handlers با 56_000_000 | همه به ثابت تبدیل شدند |
|
||||
|
||||
---
|
||||
|
||||
### 2. 📱 SmsTemplates - قالبهای متمرکز پیامک ✅
|
||||
|
||||
**فایل جدید**: `CMSMicroservice.Domain/Common/SmsTemplates.cs`
|
||||
|
||||
```csharp
|
||||
public static class SmsTemplates
|
||||
{
|
||||
private static string GetUserName(string? firstName)
|
||||
=> string.IsNullOrWhiteSpace(firstName) ? "کاربر" : firstName;
|
||||
|
||||
public static string DayaLoanReceived(string? firstName, long amount)
|
||||
=> $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال وام دایا به کیف پول شما واریز شد. کارابازار";
|
||||
|
||||
public static string ClubActivated(string? firstName)
|
||||
=> $"{GetUserName(firstName)} عزیز، حساب باشگاه شما فعال شد. کارابازار";
|
||||
|
||||
public static string PackagePurchased(string? firstName, string packageName)
|
||||
=> $"{GetUserName(firstName)} عزیز، پکیج {packageName} با موفقیت خریداری شد. کارابازار";
|
||||
|
||||
public static string CommissionDeposited(string? firstName, long amount)
|
||||
=> $"{GetUserName(firstName)} عزیز، مبلغ {amount:N0} ریال کمیسیون به کیف پول شما واریز شد. کارابازار";
|
||||
|
||||
public static string WithdrawalSuccess(string? firstName, long amount)
|
||||
=> $"{GetUserName(firstName)} عزیز، درخواست برداشت {amount:N0} ریال با موفقیت انجام شد. کارابازار";
|
||||
|
||||
public static string NetworkJoined(string? firstName, string referrerName)
|
||||
=> $"{GetUserName(firstName)} عزیز، به شبکه {referrerName} پیوستید. کارابازار";
|
||||
|
||||
public static string NewDownline(string? firstName, string newMemberName)
|
||||
=> $"{GetUserName(firstName)} عزیز، {newMemberName} به زیرمجموعه شما اضافه شد. کارابازار";
|
||||
|
||||
public static string OtpCode(string code)
|
||||
=> $"کد تأیید شما: {code}\nکارابازار";
|
||||
|
||||
public static string Welcome(string? firstName)
|
||||
=> $"{GetUserName(firstName)} عزیز، به کارابازار خوش آمدید!";
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 📲 ارسال SMS هنگام تأیید وام دایا ✅
|
||||
|
||||
**فایل**: `CMSMicroservice.Application/FinancialCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs`
|
||||
|
||||
**تغییرات**:
|
||||
```csharp
|
||||
public class ProcessDayaLoanApprovalCommandHandler : IRequestHandler<ProcessDayaLoanApprovalCommand, Unit>
|
||||
{
|
||||
private readonly IKavenegarService _smsService; // جدید
|
||||
private readonly ILogger<ProcessDayaLoanApprovalCommandHandler> _logger; // جدید
|
||||
|
||||
// بعد از واریز موفق به کیف پول
|
||||
private async Task SendDayaLoanSmsAsync(User user)
|
||||
{
|
||||
try
|
||||
{
|
||||
var message = SmsTemplates.DayaLoanReceived(
|
||||
user.FirstName,
|
||||
SystemConstants.DayaLoanAmount);
|
||||
|
||||
await _smsService.SendAsync(user.PhoneNumber, message);
|
||||
_logger.LogInformation("Daya loan SMS sent to user {UserId}", user.Id);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to send Daya loan SMS to user {UserId}", user.Id);
|
||||
// خطای SMS مانع عملیات اصلی نمیشود
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 🖥️ BackOffice - صفحه مدیریت نسخه اپلیکیشن ✅
|
||||
|
||||
#### 4.1 اضافه شدن به منو
|
||||
|
||||
**فایل**: `BackOffice/Shared/NavMenu.razor`
|
||||
|
||||
```razor
|
||||
@if (CanViewSettings)
|
||||
{
|
||||
<MudNavLink Match="NavLinkMatch.Prefix"
|
||||
Href="/settings/app-versions"
|
||||
Icon="@Icons.Material.Filled.PhoneAndroid">
|
||||
نسخه اپلیکیشنها
|
||||
</MudNavLink>
|
||||
}
|
||||
```
|
||||
|
||||
**Permission**: `settings.view`
|
||||
|
||||
#### 4.2 دکمه افزودن نسخه جدید
|
||||
|
||||
**فایل**: `BackOffice/Pages/Settings/AppVersions.razor`
|
||||
|
||||
```razor
|
||||
<MudButton Variant="Variant.Filled"
|
||||
Color="Color.Primary"
|
||||
StartIcon="@Icons.Material.Filled.Add"
|
||||
OnClick="@OpenCreateDialog">
|
||||
افزودن نسخه جدید
|
||||
</MudButton>
|
||||
```
|
||||
|
||||
#### 4.3 Dialog با حالت جدید/ویرایش
|
||||
|
||||
**فایل**: `BackOffice/Pages/Settings/Components/AppVersionEditDialog.razor`
|
||||
|
||||
```razor
|
||||
[Parameter]
|
||||
public bool IsNew { get; set; } = false;
|
||||
|
||||
@if (IsNew)
|
||||
{
|
||||
<MudSelect @bind-Value="Model.AppName"
|
||||
Label="نام اپلیکیشن"
|
||||
Required="true">
|
||||
<MudSelectItem Value="@("KaraBazarApp")">کارابازار</MudSelectItem>
|
||||
<MudSelectItem Value="@("KaraBazarAdminApp")">ادمین کارابازار</MudSelectItem>
|
||||
</MudSelect>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudTextField @bind-Value="Model.AppName"
|
||||
ReadOnly="true" Disabled="true" />
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.4 آیکون و رنگ اپلیکیشنها
|
||||
|
||||
```csharp
|
||||
private string GetAppIcon(string appName) => appName switch
|
||||
{
|
||||
"KaraBazarApp" => Icons.Material.Filled.ShoppingCart,
|
||||
"KaraBazarAdminApp" => Icons.Material.Filled.AdminPanelSettings,
|
||||
_ => Icons.Material.Filled.PhoneAndroid
|
||||
};
|
||||
|
||||
private Color GetAppColor(string appName) => appName switch
|
||||
{
|
||||
"KaraBazarApp" => Color.Primary,
|
||||
"KaraBazarAdminApp" => Color.Secondary,
|
||||
_ => Color.Default
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 🔧 Mapping Fixes ✅
|
||||
|
||||
#### 5.1 CMS - AppVersionProfile
|
||||
|
||||
**فایل جدید**: `CMSMicroservice.WebApi/Common/Mappings/AppVersionProfile.cs`
|
||||
|
||||
```csharp
|
||||
public class AppVersionProfile : IRegister
|
||||
{
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
// Map List<AppVersionItemDto> to GetAllAppVersionsResponse
|
||||
config.NewConfig<List<AppVersionItemDto>, GetAllAppVersionsResponse>()
|
||||
.MapWith(src => CreateResponse(src));
|
||||
|
||||
// Map AppVersionItemDto to AppVersionItem (proto message)
|
||||
config.NewConfig<AppVersionItemDto, AppVersionItem>()
|
||||
.Map(dest => dest.Id, src => src.Id)
|
||||
.Map(dest => dest.AppName, src => src.AppName)
|
||||
// ... other mappings
|
||||
}
|
||||
|
||||
private static GetAllAppVersionsResponse CreateResponse(List<AppVersionItemDto> items)
|
||||
{
|
||||
var response = new GetAllAppVersionsResponse();
|
||||
foreach (var item in items)
|
||||
{
|
||||
response.Items.Add(item.Adapt<AppVersionItem>());
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.2 BackOffice.BFF - CommissionProfile
|
||||
|
||||
**فایل**: `BackOffice.BFF.Application/Common/Mappings/CommissionProfile.cs`
|
||||
|
||||
```csharp
|
||||
// CMS GetAllWeeklyPoolsResponse -> GetAllWeeklyPoolsResponseDto
|
||||
config.NewConfig<GetAllWeeklyPoolsResponse, GetAllWeeklyPoolsResponseDto>()
|
||||
.MapWith(src => new GetAllWeeklyPoolsResponseDto
|
||||
{
|
||||
MetaData = new MetaDataDto
|
||||
{
|
||||
TotalCount = (int)src.MetaData.TotalCount,
|
||||
PageSize = (int)src.MetaData.PageSize,
|
||||
CurrentPage = (int)src.MetaData.CurrentPage,
|
||||
TotalPages = (int)src.MetaData.TotalPage
|
||||
},
|
||||
Models = src.Models.Select(m => new WeeklyCommissionPoolDto
|
||||
{
|
||||
Id = m.Id,
|
||||
WeekDefinitionId = m.WeekDefinitionId,
|
||||
// ... other mappings
|
||||
}).ToList()
|
||||
});
|
||||
```
|
||||
|
||||
#### 5.3 BackOffice.BFF - GeneralMapping (Unit to Empty)
|
||||
|
||||
**فایل**: `BackOffice.BFF.WebApi/Common/Mappings/GeneralMapping.cs`
|
||||
|
||||
```csharp
|
||||
// MediatR Unit to Google.Protobuf.Empty
|
||||
config.NewConfig<MediatR.Unit, Google.Protobuf.WellKnownTypes.Empty>()
|
||||
.MapWith(_ => new Google.Protobuf.WellKnownTypes.Empty());
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 فایلهای تغییر یافته
|
||||
|
||||
### CMS
|
||||
| فایل | نوع تغییر |
|
||||
|------|-----------|
|
||||
| `Domain/Common/SystemConstants.cs` | Modified - اضافه شدن GoldenPackageAmount, DayaLoanAmount |
|
||||
| `Domain/Common/SmsTemplates.cs` | **New** - قالبهای پیامک |
|
||||
| `Application/.../ProcessDayaLoanApprovalCommandHandler.cs` | Modified - اضافه شدن SMS |
|
||||
| `WebApi/Common/Mappings/AppVersionProfile.cs` | **New** - Mapster profile |
|
||||
|
||||
### BackOffice.BFF
|
||||
| فایل | نوع تغییر |
|
||||
|------|-----------|
|
||||
| `Application/Common/Mappings/CommissionProfile.cs` | Modified - اضافه شدن GetAllWeeklyPools mapping |
|
||||
| `WebApi/Common/Mappings/GeneralMapping.cs` | Modified - اضافه شدن Unit to Empty |
|
||||
|
||||
### BackOffice
|
||||
| فایل | نوع تغییر |
|
||||
|------|-----------|
|
||||
| `Shared/NavMenu.razor` | Modified - اضافه شدن لینک app-versions |
|
||||
| `Pages/Settings/AppVersions.razor` | Modified - دکمه افزودن + OpenCreateDialog |
|
||||
| `Pages/Settings/Components/AppVersionEditDialog.razor` | Modified - پارامتر IsNew + Select |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Build Status
|
||||
|
||||
```bash
|
||||
# CMS
|
||||
dotnet build CMSMicroservice.WebApi/CMSMicroservice.WebApi.csproj
|
||||
# Build succeeded. 0 Error(s)
|
||||
|
||||
# BackOffice.BFF
|
||||
dotnet build BackOffice.BFF.WebApi/BackOffice.BFF.WebApi.csproj
|
||||
# Build succeeded. 0 Error(s)
|
||||
|
||||
# BackOffice
|
||||
dotnet build BackOffice/BackOffice.csproj
|
||||
# Build succeeded. 0 Error(s)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 آمار Session
|
||||
|
||||
| متریک | مقدار |
|
||||
|-------|-------|
|
||||
| فایلهای جدید | 2 |
|
||||
| فایلهای تغییر یافته | 8 |
|
||||
| خطوط کد اضافه شده | ~300 |
|
||||
| باگهای Mapping رفع شده | 3 |
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Related Changelogs
|
||||
|
||||
- [CHANGELOG-2025-12-26.md](CHANGELOG-2025-12-26.md) - App Version Management + ReferralCode in Tree
|
||||
- [CHANGELOG-2025-12-25.md](CHANGELOG-2025-12-25.md) - درخت شبکه BackOffice
|
||||
Reference in New Issue
Block a user