Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b26073c63 | |||
| 28e94d6137 | |||
| c6ee356cbd | |||
| 2d09a69be9 | |||
| 7cebb27171 | |||
| 68489a8374 | |||
| 330f0cae5a | |||
| b16f01b6e4 | |||
| 13f24d523b |
@@ -11,6 +11,7 @@
|
|||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||||
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.11" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.11" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.11" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.11" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.11" />
|
||||||
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.4.0" />
|
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.4.0" />
|
||||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.10" />
|
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.10" />
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using CMSMicroservice.Domain.Entities.Payment;
|
|||||||
using CMSMicroservice.Domain.Entities.Order;
|
using CMSMicroservice.Domain.Entities.Order;
|
||||||
using CMSMicroservice.Domain.Entities.DiscountShop;
|
using CMSMicroservice.Domain.Entities.DiscountShop;
|
||||||
using CMSMicroservice.Domain.Entities.Geography;
|
using CMSMicroservice.Domain.Entities.Geography;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace CMSMicroservice.Application.Common.Interfaces;
|
namespace CMSMicroservice.Application.Common.Interfaces;
|
||||||
|
|
||||||
@@ -60,5 +61,10 @@ public interface IApplicationDbContext
|
|||||||
DbSet<State> States { get; }
|
DbSet<State> States { get; }
|
||||||
DbSet<City> Cities { get; }
|
DbSet<City> Cities { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// دسترسی به DatabaseFacade برای اجرای raw SQL و Stored Procedures
|
||||||
|
/// </summary>
|
||||||
|
DatabaseFacade Database { get; }
|
||||||
|
|
||||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
|
Task<int> SaveChangesAsync(CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
+147
-113
@@ -1,144 +1,178 @@
|
|||||||
|
using System.Data;
|
||||||
|
using System.Data.Common;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkTree;
|
namespace CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkTree;
|
||||||
|
|
||||||
public class GetNetworkTreeQueryHandler : IRequestHandler<GetNetworkTreeQuery, NetworkTreeDto?>
|
public class GetNetworkTreeQueryHandler : IRequestHandler<GetNetworkTreeQuery, NetworkTreeDto?>
|
||||||
{
|
{
|
||||||
private readonly IApplicationDbContext _context;
|
private readonly IApplicationDbContext _context;
|
||||||
private readonly IWeekDefinitionRepository _weekDefinitionRepository;
|
private readonly ILogger<GetNetworkTreeQueryHandler> _logger;
|
||||||
|
|
||||||
public GetNetworkTreeQueryHandler(
|
public GetNetworkTreeQueryHandler(
|
||||||
IApplicationDbContext context,
|
IApplicationDbContext context,
|
||||||
IWeekDefinitionRepository weekDefinitionRepository)
|
ILogger<GetNetworkTreeQueryHandler> logger)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
_weekDefinitionRepository = weekDefinitionRepository;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<NetworkTreeDto?> Handle(GetNetworkTreeQuery request, CancellationToken cancellationToken)
|
public async Task<NetworkTreeDto?> Handle(GetNetworkTreeQuery request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var rootUser = await _context.Users
|
try
|
||||||
.AsNoTracking()
|
|
||||||
.FirstOrDefaultAsync(x => x.Id == request.UserId, cancellationToken);
|
|
||||||
|
|
||||||
if (rootUser == null)
|
|
||||||
{
|
{
|
||||||
return null;
|
// دریافت نتایج flat از Stored Procedure
|
||||||
}
|
var flatNodes = await ExecuteStoredProcedureAsync(request, cancellationToken);
|
||||||
|
|
||||||
var tree = await BuildTree(rootUser.Id, request.MaxDepth, 0, cancellationToken, request);
|
if (flatNodes == null || !flatNodes.Any())
|
||||||
return tree;
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// تبدیل نتایج flat به ساختار درختی
|
||||||
|
var tree = BuildTreeFromFlatNodes(flatNodes);
|
||||||
|
return tree;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "Error executing GetNetworkTree for UserId: {UserId}", request.UserId);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<NetworkTreeDto> BuildTree(long userId, int maxDepth, int currentDepth, CancellationToken cancellationToken, GetNetworkTreeQuery request)
|
/// <summary>
|
||||||
|
/// اجرای Stored Procedure و دریافت نتایج
|
||||||
|
/// </summary>
|
||||||
|
private async Task<List<NetworkTreeNodeDto>> ExecuteStoredProcedureAsync(
|
||||||
|
GetNetworkTreeQuery request,
|
||||||
|
CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
// دریافت کاربر با اطلاعات باشگاه مشتریان
|
var results = new List<NetworkTreeNodeDto>();
|
||||||
var user = await _context.Users
|
|
||||||
.Include(u => u.ClubMembership)
|
|
||||||
.AsNoTracking()
|
|
||||||
.FirstOrDefaultAsync(x => x.Id == userId, cancellationToken);
|
|
||||||
|
|
||||||
if (user == null)
|
var connection = _context.Database.GetDbConnection();
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
throw new NotFoundException(nameof(User), userId);
|
if (connection.State != ConnectionState.Open)
|
||||||
|
{
|
||||||
|
await connection.OpenAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var command = connection.CreateCommand();
|
||||||
|
command.CommandText = "[CMS].[GetNetworkTree]";
|
||||||
|
command.CommandType = CommandType.StoredProcedure;
|
||||||
|
command.CommandTimeout = 120; // 2 minutes timeout for large trees
|
||||||
|
|
||||||
|
// Parameters - use DbParameter for provider-agnostic code
|
||||||
|
var rootUserIdParam = command.CreateParameter();
|
||||||
|
rootUserIdParam.ParameterName = "@RootUserId";
|
||||||
|
rootUserIdParam.DbType = DbType.Int64;
|
||||||
|
rootUserIdParam.Value = request.UserId;
|
||||||
|
command.Parameters.Add(rootUserIdParam);
|
||||||
|
|
||||||
|
var maxDepthParam = command.CreateParameter();
|
||||||
|
maxDepthParam.ParameterName = "@MaxDepth";
|
||||||
|
maxDepthParam.DbType = DbType.Int32;
|
||||||
|
maxDepthParam.Value = request.MaxDepth > 0 ? request.MaxDepth : 100;
|
||||||
|
command.Parameters.Add(maxDepthParam);
|
||||||
|
|
||||||
|
var isClubActiveParam = command.CreateParameter();
|
||||||
|
isClubActiveParam.ParameterName = "@IsClubActive";
|
||||||
|
isClubActiveParam.DbType = DbType.Boolean;
|
||||||
|
isClubActiveParam.Value = request.IsClubActive.HasValue ? request.IsClubActive.Value : DBNull.Value;
|
||||||
|
command.Parameters.Add(isClubActiveParam);
|
||||||
|
|
||||||
|
var weekParam = command.CreateParameter();
|
||||||
|
weekParam.ParameterName = "@ActivationWeekDefinitionId";
|
||||||
|
weekParam.DbType = DbType.Int64;
|
||||||
|
weekParam.Value = request.ActivationWeekDefinitionId.HasValue ? request.ActivationWeekDefinitionId.Value : DBNull.Value;
|
||||||
|
command.Parameters.Add(weekParam);
|
||||||
|
|
||||||
|
using var reader = await command.ExecuteReaderAsync(cancellationToken);
|
||||||
|
|
||||||
|
while (await reader.ReadAsync(cancellationToken))
|
||||||
|
{
|
||||||
|
var node = new NetworkTreeNodeDto
|
||||||
|
{
|
||||||
|
UserId = reader.GetInt64(reader.GetOrdinal("UserId")),
|
||||||
|
Mobile = reader.IsDBNull(reader.GetOrdinal("Mobile")) ? null : reader.GetString(reader.GetOrdinal("Mobile")),
|
||||||
|
FirstName = reader.IsDBNull(reader.GetOrdinal("FirstName")) ? null : reader.GetString(reader.GetOrdinal("FirstName")),
|
||||||
|
LastName = reader.IsDBNull(reader.GetOrdinal("LastName")) ? null : reader.GetString(reader.GetOrdinal("LastName")),
|
||||||
|
LegPosition = reader.IsDBNull(reader.GetOrdinal("LegPosition")) ? null : reader.GetInt32(reader.GetOrdinal("LegPosition")),
|
||||||
|
ParentId = reader.IsDBNull(reader.GetOrdinal("ParentId")) ? null : reader.GetInt64(reader.GetOrdinal("ParentId")),
|
||||||
|
NetworkLevel = reader.GetInt32(reader.GetOrdinal("NetworkLevel")),
|
||||||
|
ClubActivatedAt = reader.IsDBNull(reader.GetOrdinal("ClubActivatedAt")) ? null : reader.GetDateTime(reader.GetOrdinal("ClubActivatedAt")),
|
||||||
|
IsClubActive = reader.GetBoolean(reader.GetOrdinal("IsClubActive")),
|
||||||
|
ActivationWeekDefinitionId = reader.IsDBNull(reader.GetOrdinal("ActivationWeekDefinitionId")) ? null : reader.GetInt64(reader.GetOrdinal("ActivationWeekDefinitionId")),
|
||||||
|
ActivationWeekDisplayName = reader.IsDBNull(reader.GetOrdinal("ActivationWeekDisplayName")) ? null : reader.GetString(reader.GetOrdinal("ActivationWeekDisplayName")),
|
||||||
|
IsActivatedInTargetWeek = reader.GetBoolean(reader.GetOrdinal("IsActivatedInTargetWeek")),
|
||||||
|
UserCreated = new DateTimeOffset(reader.GetDateTime(reader.GetOrdinal("UserCreated")))
|
||||||
|
};
|
||||||
|
|
||||||
|
results.Add(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Connection is managed by DbContext, don't close it here
|
||||||
}
|
}
|
||||||
|
|
||||||
// محاسبه شماره هفته فعالسازی
|
_logger.LogInformation("GetNetworkTree SP returned {Count} nodes for UserId: {UserId}", results.Count, request.UserId);
|
||||||
long? activationWeekDefinitionId = null;
|
return results;
|
||||||
string? activationWeekDisplayName = null;
|
}
|
||||||
bool isActivatedInTargetWeek = false;
|
|
||||||
|
|
||||||
if (user.ClubMembership?.ActivatedAt != null)
|
/// <summary>
|
||||||
|
/// تبدیل لیست flat به ساختار درختی
|
||||||
|
/// </summary>
|
||||||
|
private NetworkTreeDto? BuildTreeFromFlatNodes(List<NetworkTreeNodeDto> flatNodes)
|
||||||
|
{
|
||||||
|
if (!flatNodes.Any()) return null;
|
||||||
|
|
||||||
|
// Dictionary برای دسترسی سریع به نودها
|
||||||
|
var nodeDict = new Dictionary<long, NetworkTreeDto>();
|
||||||
|
|
||||||
|
// ایجاد همه نودها
|
||||||
|
foreach (var flatNode in flatNodes)
|
||||||
{
|
{
|
||||||
// activationWeekDefinitionId = CalculateWeekNumber(user.ClubMembership.ActivatedAt.Value);
|
nodeDict[flatNode.UserId] = new NetworkTreeDto
|
||||||
var week = _weekDefinitionRepository.GetWeekByDate(user.ClubMembership.ActivatedAt.Value);
|
|
||||||
activationWeekDefinitionId = week.Id;
|
|
||||||
activationWeekDisplayName = week.DisplayName;
|
|
||||||
|
|
||||||
// بررسی آیا در هفته هدف فعال شده است
|
|
||||||
if (request.ActivationWeekDefinitionId!=null)
|
|
||||||
{
|
{
|
||||||
isActivatedInTargetWeek = activationWeekDefinitionId == request.ActivationWeekDefinitionId;
|
UserId = flatNode.UserId,
|
||||||
|
Mobile = flatNode.Mobile,
|
||||||
|
FirstName = flatNode.FirstName,
|
||||||
|
LastName = flatNode.LastName,
|
||||||
|
LegPosition = flatNode.LegPosition.HasValue ? (NetworkLeg)flatNode.LegPosition.Value : null,
|
||||||
|
CurrentDepth = flatNode.NetworkLevel,
|
||||||
|
ClubActivatedAt = flatNode.ClubActivatedAt,
|
||||||
|
IsClubActive = flatNode.IsClubActive,
|
||||||
|
ActivationWeekDefinitionId = flatNode.ActivationWeekDefinitionId,
|
||||||
|
ActivationWeekDisplayName = flatNode.ActivationWeekDisplayName,
|
||||||
|
IsActivatedInTargetWeek = flatNode.IsActivatedInTargetWeek,
|
||||||
|
UserCreated = flatNode.UserCreated
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// برقراری ارتباط Parent-Child
|
||||||
|
foreach (var flatNode in flatNodes)
|
||||||
|
{
|
||||||
|
if (flatNode.ParentId.HasValue && nodeDict.ContainsKey(flatNode.ParentId.Value))
|
||||||
|
{
|
||||||
|
var parent = nodeDict[flatNode.ParentId.Value];
|
||||||
|
var child = nodeDict[flatNode.UserId];
|
||||||
|
|
||||||
|
// تعیین موقعیت چپ یا راست
|
||||||
|
if (flatNode.LegPosition == (int)NetworkLeg.Left)
|
||||||
|
{
|
||||||
|
parent.LeftChild = child;
|
||||||
|
}
|
||||||
|
else if (flatNode.LegPosition == (int)NetworkLeg.Right)
|
||||||
|
{
|
||||||
|
parent.RightChild = child;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var node = new NetworkTreeDto
|
// پیدا کردن ریشه (اولین نود با Level=0)
|
||||||
{
|
var rootNode = flatNodes.FirstOrDefault(n => n.NetworkLevel == 0);
|
||||||
UserId = user.Id,
|
return rootNode != null ? nodeDict[rootNode.UserId] : null;
|
||||||
Mobile = user.Mobile,
|
|
||||||
FirstName = user.FirstName,
|
|
||||||
LastName = user.LastName,
|
|
||||||
LegPosition = user.LegPosition,
|
|
||||||
CurrentDepth = currentDepth,
|
|
||||||
ClubActivatedAt = user.ClubMembership?.ActivatedAt,
|
|
||||||
IsClubActive = user.ClubMembership?.IsActive ?? false,
|
|
||||||
ActivationWeekDefinitionId = activationWeekDefinitionId,
|
|
||||||
ActivationWeekDisplayName = activationWeekDisplayName,
|
|
||||||
IsActivatedInTargetWeek = isActivatedInTargetWeek,
|
|
||||||
UserCreated = user.Created
|
|
||||||
};
|
|
||||||
|
|
||||||
// اگر به حداکثر عمق رسیدیم، دیگر فرزندان را نمیخوانیم
|
|
||||||
if (currentDepth >= maxDepth)
|
|
||||||
{
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
// پیدا کردن فرزندان (چپ و راست)
|
|
||||||
var children = await GetFilteredChildren(userId, request, cancellationToken);
|
|
||||||
|
|
||||||
var leftChild = children.FirstOrDefault(c => c.LegPosition == NetworkLeg.Left);
|
|
||||||
if (leftChild != null)
|
|
||||||
{
|
|
||||||
node.LeftChild = await BuildTree(leftChild.Id, maxDepth, currentDepth + 1, cancellationToken, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
var rightChild = children.FirstOrDefault(c => c.LegPosition == NetworkLeg.Right);
|
|
||||||
if (rightChild != null)
|
|
||||||
{
|
|
||||||
node.RightChild = await BuildTree(rightChild.Id, maxDepth, currentDepth + 1, cancellationToken, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// دریافت فرزندان با اعمال فیلترها
|
|
||||||
/// </summary>
|
|
||||||
private async Task<List<User>> GetFilteredChildren(long parentId, GetNetworkTreeQuery request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
var query = _context.Users
|
|
||||||
.Include(u => u.ClubMembership)
|
|
||||||
.AsNoTracking()
|
|
||||||
.Where(x => x.NetworkParentId == parentId);
|
|
||||||
|
|
||||||
// اعمال فیلتر IsClubActive
|
|
||||||
if (request.IsClubActive.HasValue)
|
|
||||||
{
|
|
||||||
query = query.Where(u =>
|
|
||||||
u.ClubMembership != null &&
|
|
||||||
u.ClubMembership.IsDeleted == false &&
|
|
||||||
u.ClubMembership.IsActive == request.IsClubActive.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await query.ToListAsync(cancellationToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// محاسبه شماره هفته از تاریخ
|
|
||||||
/// </summary>
|
|
||||||
// private long CalculateWeekNumber(DateTime date)
|
|
||||||
// {
|
|
||||||
// // First try to get from repository cache
|
|
||||||
// var weekDef = _weekDefinitionRepository.GetWeekByDate(date);
|
|
||||||
// if (weekDef != null)
|
|
||||||
// {
|
|
||||||
// return weekDef.Id;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Fallback: use repository's calculation method
|
|
||||||
// // return _weekDefinitionRepository.CalculateGregorianWeekNumber(date);
|
|
||||||
// return 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
namespace CMSMicroservice.Application.NetworkMembershipCQ.Queries.GetNetworkTree;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DTO برای نتیجه Flat از Stored Procedure
|
||||||
|
/// هر ردیف یک نود از درخت است
|
||||||
|
/// </summary>
|
||||||
|
public class NetworkTreeNodeDto
|
||||||
|
{
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public string? Mobile { get; set; }
|
||||||
|
public string? FirstName { get; set; }
|
||||||
|
public string? LastName { get; set; }
|
||||||
|
public int? LegPosition { get; set; }
|
||||||
|
public long? ParentId { get; set; }
|
||||||
|
public int NetworkLevel { get; set; }
|
||||||
|
public DateTime? ClubActivatedAt { get; set; }
|
||||||
|
public bool IsClubActive { get; set; }
|
||||||
|
public long? ActivationWeekDefinitionId { get; set; }
|
||||||
|
public string? ActivationWeekDisplayName { get; set; }
|
||||||
|
public bool IsActivatedInTargetWeek { get; set; }
|
||||||
|
public DateTimeOffset UserCreated { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// نام کامل کاربر
|
||||||
|
/// </summary>
|
||||||
|
public string FullName => $"{FirstName} {LastName}".Trim();
|
||||||
|
}
|
||||||
@@ -93,8 +93,7 @@ public class ChatikaAccountActivationJob
|
|||||||
ucf.ClubFeatureId == (long)ClubFeatureType.Chatika &&
|
ucf.ClubFeatureId == (long)ClubFeatureType.Chatika &&
|
||||||
ucf.ClubMembership.IsActive &&
|
ucf.ClubMembership.IsActive &&
|
||||||
!ucf.IsDeleted &&
|
!ucf.IsDeleted &&
|
||||||
ucf.IsActive &&
|
!ucf.IsActive) // حساب هنوز ساخته نشده
|
||||||
(ucf.Notes == null || ucf.Notes == "")) // حساب هنوز ساخته نشده
|
|
||||||
.ToListAsync(cancellationToken);
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
if (!pendingUsers.Any())
|
if (!pendingUsers.Any())
|
||||||
@@ -118,7 +117,7 @@ public class ChatikaAccountActivationJob
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// بررسی تکراری نبودن (Double-check)
|
// بررسی تکراری نبودن (Double-check)
|
||||||
if (!string.IsNullOrEmpty(userFeature.Notes))
|
if (userFeature.IsActive)
|
||||||
{
|
{
|
||||||
_logger.LogDebug(
|
_logger.LogDebug(
|
||||||
"⏭️ Skipping user {UserId} - already processed",
|
"⏭️ Skipping user {UserId} - already processed",
|
||||||
|
|||||||
@@ -39,12 +39,17 @@ public class DayaLoanCheckWorker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// پیدا کردن کاربرانی که اعتبار دایا را دریافت نکردهاند
|
|
||||||
|
// پیدا کردن کاربرانی که:
|
||||||
|
// 1. اعتبار دایا را دریافت نکردهاند
|
||||||
|
// 2. کد ملی دارند
|
||||||
|
// 3. قبلاً شماره قرارداد نگرفتهاند
|
||||||
var pendingUsers = await _context.Users
|
var pendingUsers = await _context.Users
|
||||||
.Where(u =>
|
.Where(u =>
|
||||||
u.HasReceivedDayaCredit == false &&
|
u.HasReceivedDayaCredit == false &&
|
||||||
u.NationalCode != null &&
|
u.NationalCode != null &&
|
||||||
u.NationalCode != "")
|
u.NationalCode != ""
|
||||||
|
)
|
||||||
.Select(u => new { u.Id, u.NationalCode })
|
.Select(u => new { u.Id, u.NationalCode })
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"UseRealPaymentGateway": false,
|
||||||
|
"JwtSecurityKey": "TvlZVx5TJaHs8e9HgUdGzhGP2CIidoI444nAj+8+g7c=",
|
||||||
|
"JwtIssuer": "https://localhost",
|
||||||
|
"JwtAudience": "https://localhost",
|
||||||
|
"JwtExpiryInDays": 5,
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Data Source=45.149.79.127,31433; Initial Catalog=KBS;User ID=sa;Password=YourStrong@Passw0rd;Connection Timeout=300000;MultipleActiveResultSets=True;Encrypt=False",
|
||||||
|
"providerName": "System.Data.SqlClient"
|
||||||
|
},
|
||||||
|
"Otp": {
|
||||||
|
"Secret": "K2w8k1h1mH2Qz1kqWk0c8kQ2Pq8q9H1eE2nqN1qQ8x7M="
|
||||||
|
},
|
||||||
|
"Monitoring": {
|
||||||
|
"SentryEnabled": false,
|
||||||
|
"SentryDsn": "",
|
||||||
|
"SlackEnabled": false,
|
||||||
|
"SlackWebhookUrl": "",
|
||||||
|
"EmailAlertsEnabled": false,
|
||||||
|
"AdminEmails": [
|
||||||
|
"admin@example.com"
|
||||||
|
],
|
||||||
|
"SmsNotificationsEnabled": false,
|
||||||
|
"SmsApiKey": "",
|
||||||
|
"SmsGatewayUrl": ""
|
||||||
|
},
|
||||||
|
"Email": {
|
||||||
|
"Enabled": true,
|
||||||
|
"SmtpHost": "smtp.gmail.com",
|
||||||
|
"SmtpPort": 587,
|
||||||
|
"SmtpUsername": "your-email@gmail.com",
|
||||||
|
"SmtpPassword": "your-app-password",
|
||||||
|
"FromEmail": "noreply@foursat.com",
|
||||||
|
"FromName": "FourSat CMS",
|
||||||
|
"EnableSsl": true
|
||||||
|
},
|
||||||
|
"Sms": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Provider": "Kavenegar",
|
||||||
|
"KavenegarApiKey": "YOUR_KAVENEGAR_API_KEY",
|
||||||
|
"Sender": "10008663"
|
||||||
|
},
|
||||||
|
"DayaPayment": {
|
||||||
|
"BaseUrl": "https://api.daya.ir",
|
||||||
|
"ApiKey": "YOUR_DAYA_API_KEY"
|
||||||
|
},
|
||||||
|
"DayaApi": {
|
||||||
|
"UseMock": false,
|
||||||
|
"BaseAddress": "https://Dayadiamond.ir",
|
||||||
|
"MerchantPermissionKey": "56146364$04sXjethI5WxhItR1Q9xnmFdJzl2BB8Bclsq8dAy7YVSZp3vtt-wP7ivrcCvmKLq",
|
||||||
|
"CacheDurationMinutes": 20
|
||||||
|
},
|
||||||
|
"Chatika": {
|
||||||
|
"Enabled": true,
|
||||||
|
"BaseUrl": "https://api.chatika.ir",
|
||||||
|
"ApiKey": "tIukvL8dnV4cB3yVWcCD9Xyfbj8rBxm5wPt2mLyJCgTsBBoMTWjt6mFEqQwpw-er"
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"Kestrel": {
|
||||||
|
"EndpointDefaults": {
|
||||||
|
"Protocols": "Http2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Authentication": {
|
||||||
|
"Authority": "https://ids.domain.com/",
|
||||||
|
"Audience": "domain_api"
|
||||||
|
},
|
||||||
|
"Seq": {
|
||||||
|
"ServerUrl": "https://seq.afrino.co",
|
||||||
|
"ApiKey": "oxpvpUzU1pZxMS4s3Fqq"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
"JwtAudience": "https://localhost",
|
"JwtAudience": "https://localhost",
|
||||||
"JwtExpiryInDays": 5,
|
"JwtExpiryInDays": 5,
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Data Source=45.149.79.127,31433; Initial Catalog=KBS;User ID=sa;Password=YourStrong@Passw0rd;Connection Timeout=300000;MultipleActiveResultSets=True;Encrypt=False",
|
"DefaultConnection": "",
|
||||||
"providerName": "System.Data.SqlClient"
|
"providerName": "System.Data.SqlClient"
|
||||||
},
|
},
|
||||||
"Otp": {
|
"Otp": {
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
"CacheDurationMinutes": 20
|
"CacheDurationMinutes": 20
|
||||||
},
|
},
|
||||||
"Chatika": {
|
"Chatika": {
|
||||||
"Enabled": false,
|
"Enabled": true,
|
||||||
"BaseUrl": "https://api.chatika.ir",
|
"BaseUrl": "https://api.chatika.ir",
|
||||||
"ApiKey": "tIukvL8dnV4cB3yVWcCD9Xyfbj8rBxm5wPt2mLyJCgTsBBoMTWjt6mFEqQwpw-er"
|
"ApiKey": "tIukvL8dnV4cB3yVWcCD9Xyfbj8rBxm5wPt2mLyJCgTsBBoMTWjt6mFEqQwpw-er"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user