feat: add club membership contract signing and city services

This commit is contained in:
masoodafar-web
2025-12-18 00:44:44 +03:30
parent 63f05e0883
commit 4330ec3726
38 changed files with 1583 additions and 25 deletions
@@ -0,0 +1,23 @@
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.RequestClubContractOtp;
/// <summary>
/// Command برای درخواست OTP امضای قرارداد باشگاه مشتریان
/// </summary>
public record RequestClubContractOtpCommand : IRequest<RequestClubContractOtpResponseDto>
{
/// <summary>
/// شناسه یکتای امضا (GUID)
/// </summary>
public string SignGuid { get; init; }
}
/// <summary>
/// DTO پاسخ درخواست OTP
/// </summary>
public class RequestClubContractOtpResponseDto
{
public bool Success { get; set; }
public string Message { get; set; }
public int RemainingAttempts { get; set; }
public int RemainingSeconds { get; set; }
}
@@ -0,0 +1,80 @@
using System.Text;
using CMSMicroservice.Protobuf.Protos.OtpToken;
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.RequestClubContractOtp;
/// <summary>
/// Handler برای درخواست OTP امضای قرارداد باشگاه مشتریان
/// از سرویس OTP موجود در CMS استفاده می‌کند و پیامک ارسال می‌کند
/// </summary>
public class RequestClubContractOtpCommandHandler
: IRequestHandler<RequestClubContractOtpCommand, RequestClubContractOtpResponseDto>
{
private readonly IApplicationContractContext _context;
private readonly IKavenegarService _kavenegarService;
private readonly ICurrentUserService _currentUserService;
private const string OtpPurpose = "signClubContract";
public RequestClubContractOtpCommandHandler(
IApplicationContractContext context,
IKavenegarService kavenegarService,
ICurrentUserService currentUserService)
{
_context = context;
_kavenegarService = kavenegarService;
_currentUserService = currentUserService;
}
public async Task<RequestClubContractOtpResponseDto> Handle(
RequestClubContractOtpCommand request,
CancellationToken cancellationToken)
{
// دریافت شماره موبایل از توکن کاربر
var mobileNumber = _currentUserService.MobileNumber;
if (string.IsNullOrEmpty(mobileNumber))
{
return new RequestClubContractOtpResponseDto
{
Success = false,
Message = "شماره موبایل کاربر یافت نشد"
};
}
// فراخوانی سرویس OTP در CMS
var otpResponse = await _context.OtpToken.CreateNewOtpTokenAsync(
new CreateNewOtpTokenRequest
{
Mobile = mobileNumber,
Purpose = OtpPurpose
},
cancellationToken: cancellationToken);
// ارسال پیامک با کد OTP
if (otpResponse.Success && !string.IsNullOrWhiteSpace(otpResponse.Code))
{
var fullName = $"{_currentUserService.FirstName} {_currentUserService.LastName}".Trim();
await _kavenegarService.Send(
mobile: mobileNumber,
new StringBuilder("سلام ")
.Append(string.IsNullOrEmpty(fullName) ? "کاربر" : fullName)
.AppendLine(" عزیز")
.Append("کد یک بار مصرف برای تایید قرارداد باشگاه مشتریان: ")
.AppendLine(otpResponse.Code)
.AppendLine("شناسه امضاء: ")
.AppendLine(request.SignGuid)
.AppendLine("کارابازار")
.ToString());
}
return new RequestClubContractOtpResponseDto
{
Success = otpResponse.Success,
Message = otpResponse.Message,
RemainingAttempts = otpResponse.RemainingAttempts,
RemainingSeconds = otpResponse.RemainingSeconds
};
}
}
@@ -0,0 +1,11 @@
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.RequestClubContractOtp;
public class RequestClubContractOtpCommandValidator : AbstractValidator<RequestClubContractOtpCommand>
{
public RequestClubContractOtpCommandValidator()
{
RuleFor(x => x.SignGuid)
.NotEmpty()
.WithMessage("شناسه امضا الزامی است");
}
}