feat: add club membership contract signing and city services
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract;
|
||||
|
||||
/// <summary>
|
||||
/// Command برای امضای قرارداد باشگاه مشتریان
|
||||
/// </summary>
|
||||
public record AcceptClubMembershipContractCommand : IRequest<AcceptClubMembershipContractResponseDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// کد OTP دریافتی
|
||||
/// </summary>
|
||||
public string OtpCode { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// شناسه یکتای امضا (GUID)
|
||||
/// </summary>
|
||||
public string SignGuid { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// محتوای HTML قرارداد
|
||||
/// </summary>
|
||||
public string ContractHtml { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DTO پاسخ امضای قرارداد
|
||||
/// </summary>
|
||||
public class AcceptClubMembershipContractResponseDto
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public string Message { get; set; }
|
||||
public long ContractId { get; set; }
|
||||
public string Token { get; set; }
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using CMSMicroservice.Protobuf.Protos.ClubMembership;
|
||||
|
||||
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract;
|
||||
|
||||
/// <summary>
|
||||
/// Handler برای امضای قرارداد باشگاه مشتریان
|
||||
/// 1. فراخوانی CMS برای ثبت قرارداد و فعالسازی باشگاه
|
||||
/// 2. دریافت توکن جدید با claims بهروز شده (IsClubMemberActive = true)
|
||||
/// </summary>
|
||||
public class AcceptClubMembershipContractCommandHandler
|
||||
: IRequestHandler<AcceptClubMembershipContractCommand, AcceptClubMembershipContractResponseDto>
|
||||
{
|
||||
private readonly IApplicationContractContext _context;
|
||||
private readonly ICurrentUserService _currentUserService;
|
||||
|
||||
public AcceptClubMembershipContractCommandHandler(
|
||||
IApplicationContractContext context,
|
||||
ICurrentUserService currentUserService)
|
||||
{
|
||||
_context = context;
|
||||
_currentUserService = currentUserService;
|
||||
}
|
||||
|
||||
public async Task<AcceptClubMembershipContractResponseDto> Handle(
|
||||
AcceptClubMembershipContractCommand request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var userId = _currentUserService.UserId
|
||||
?? throw new ForbiddenAccessException();
|
||||
|
||||
// 1. فراخوانی CMS برای ثبت قرارداد و فعالسازی باشگاه
|
||||
var cmsResponse = await _context.ClubMemberships.AcceptClubMembershipContractAsync(
|
||||
new AcceptClubMembershipContractRequest
|
||||
{
|
||||
UserId = userId,
|
||||
OtpCode = request.OtpCode,
|
||||
SignGuid = request.SignGuid,
|
||||
ContractHtml = request.ContractHtml
|
||||
},
|
||||
cancellationToken: cancellationToken);
|
||||
|
||||
if (!cmsResponse.Success)
|
||||
{
|
||||
return new AcceptClubMembershipContractResponseDto
|
||||
{
|
||||
Success = false,
|
||||
Message = cmsResponse.Message,
|
||||
ContractId = 0,
|
||||
Token = null
|
||||
};
|
||||
}
|
||||
|
||||
// 2. دریافت توکن جدید با claims بهروز شده
|
||||
string newToken = null;
|
||||
try
|
||||
{
|
||||
var tokenResponse = await _context.User.GetJwtTokenAsync(
|
||||
new CMSMicroservice.Protobuf.Protos.User.GetJwtTokenRequest
|
||||
{
|
||||
Id = userId
|
||||
},
|
||||
cancellationToken: cancellationToken);
|
||||
|
||||
newToken = tokenResponse?.Token;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// اگر دریافت توکن با خطا مواجه شد، عملیات اصلی موفق بوده
|
||||
// کاربر میتواند با login مجدد توکن جدید بگیرد
|
||||
}
|
||||
|
||||
return new AcceptClubMembershipContractResponseDto
|
||||
{
|
||||
Success = true,
|
||||
Message = cmsResponse.Message,
|
||||
ContractId = cmsResponse.ContractId,
|
||||
Token = newToken
|
||||
};
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.AcceptClubMembershipContract;
|
||||
|
||||
public class AcceptClubMembershipContractCommandValidator : AbstractValidator<AcceptClubMembershipContractCommand>
|
||||
{
|
||||
public AcceptClubMembershipContractCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.OtpCode)
|
||||
.NotEmpty()
|
||||
.WithMessage("کد تایید الزامی است")
|
||||
.Length(6)
|
||||
.WithMessage("کد تایید باید ۶ رقم باشد");
|
||||
|
||||
RuleFor(x => x.SignGuid)
|
||||
.NotEmpty()
|
||||
.WithMessage("شناسه امضا الزامی است");
|
||||
|
||||
RuleFor(x => x.ContractHtml)
|
||||
.NotEmpty()
|
||||
.WithMessage("محتوای قرارداد الزامی است");
|
||||
}
|
||||
}
|
||||
+23
@@ -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; }
|
||||
}
|
||||
+80
@@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
namespace FrontOffice.BFF.Application.ClubMembershipCQ.Commands.RequestClubContractOtp;
|
||||
|
||||
public class RequestClubContractOtpCommandValidator : AbstractValidator<RequestClubContractOtpCommand>
|
||||
{
|
||||
public RequestClubContractOtpCommandValidator()
|
||||
{
|
||||
RuleFor(x => x.SignGuid)
|
||||
.NotEmpty()
|
||||
.WithMessage("شناسه امضا الزامی است");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user