Files
GreenHomeBack/src/GreenHome.Infrastructure/Services/Device/DeviceTokenService.cs

240 lines
8.5 KiB
C#

using GreenHome.Application;
using GreenHome.Infrastructure.Data;
using GreenHome.Sms.Ippanel;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace GreenHome.Infrastructure.Services.Device;
public sealed class DeviceTokenService : IDeviceTokenService
{
private readonly GreenHomeDbContext _dbContext;
private readonly ISmsService _smsService;
private readonly ILogger<DeviceTokenService> _logger;
public DeviceTokenService(
GreenHomeDbContext dbContext,
ISmsService smsService,
ILogger<DeviceTokenService> logger)
{
_dbContext = dbContext;
_smsService = smsService;
_logger = logger;
}
public async Task<GetUploadIntervalResponse> GetUploadIntervalAsync(
GetUploadIntervalRequest request,
CancellationToken cancellationToken)
{
try
{
Domain.DeviceSettings? settings = null;
if (request.DeviceId.HasValue)
{
settings = await _dbContext.DeviceSettings
.AsNoTracking()
.FirstOrDefaultAsync(ds => ds.DeviceId == request.DeviceId.Value, cancellationToken);
}
else if (!string.IsNullOrWhiteSpace(request.DevicePhoneNumber))
{
settings = await _dbContext.DeviceSettings
.AsNoTracking()
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
}
if (settings == null)
{
return new GetUploadIntervalResponse
{
Success = false,
Message = "دستگاه یافت نشد"
};
}
return new GetUploadIntervalResponse
{
Success = true,
UploadIntervalMin = settings.UploadIntervalMin
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Error getting upload interval for device");
return new GetUploadIntervalResponse
{
Success = false,
Message = "خطا در دریافت اطلاعات"
};
}
}
public async Task<RequestDeviceTokenResponse> RequestDeviceTokenAsync(
RequestDeviceTokenRequest request,
CancellationToken cancellationToken)
{
try
{
var settings = await _dbContext.DeviceSettings
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
if (settings == null)
{
return new RequestDeviceTokenResponse
{
Success = false,
Message = "دستگاه با این شماره تلفن یافت نشد"
};
}
var random = new Random();
var tokenCode = random.Next(10000, 99999).ToString();
var verificationCode = ((int.Parse(tokenCode) * 7 + 12345) % 100000).ToString("D5");
settings.TokenCode = tokenCode;
settings.VerificationCode = verificationCode;
settings.TokenExpiresAt = DateTime.UtcNow.AddMinutes(30);
settings.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
try
{
await _smsService.SendPatternSmsAsync(new PatternSmsRequest
{
Recipients = new List<string> { request.DevicePhoneNumber },
PatternCode = "gfukab9r0nca0pt",
Variables = new Dictionary<string, string>
{
{ "tel", "09192530212" },
{ "verifyCode", verificationCode }
}
}, cancellationToken);
}
catch (Exception smsEx)
{
_logger.LogError(smsEx, "Error sending token SMS to {PhoneNumber}", request.DevicePhoneNumber);
return new RequestDeviceTokenResponse
{
Success = false,
Message = "خطا در ارسال پیامک"
};
}
_logger.LogInformation("Token requested for device phone {PhoneNumber}", request.DevicePhoneNumber);
return new RequestDeviceTokenResponse
{
Success = true,
Message = "کد تایید با موفقیت ارسال شد",
TokenCode = $"0911925302120#{tokenCode}"
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Error requesting device token");
return new RequestDeviceTokenResponse
{
Success = false,
Message = "خطا در درخواست توکن"
};
}
}
public async Task<VerifyDeviceTokenResponse> VerifyDeviceTokenAsync(
VerifyDeviceTokenRequest request,
CancellationToken cancellationToken)
{
try
{
var settings = await _dbContext.DeviceSettings
.Include(ds => ds.Device)
.FirstOrDefaultAsync(ds => ds.DevicePhoneNumber == request.DevicePhoneNumber, cancellationToken);
if (settings == null)
{
return new VerifyDeviceTokenResponse
{
Success = false,
Message = "دستگاه با این شماره تلفن یافت نشد"
};
}
if (settings.TokenExpiresAt == null || settings.TokenExpiresAt < DateTime.UtcNow)
{
return new VerifyDeviceTokenResponse
{
Success = false,
Message = "کد تایید منقضی شده است"
};
}
if (settings.VerificationCode != request.VerificationCode)
{
return new VerifyDeviceTokenResponse
{
Success = false,
Message = "کد تایید نادرست است"
};
}
var rnd = new Random();
var deviceId = settings.Device.Id + "01";
var uploadInterval = rnd.Next(1, 9) + "" + settings.UploadIntervalMin;
var smsInterval = settings.MinimumSmsIntervalMinutes > 0 ? "1" + settings.MinimumSmsIntervalMinutes : "0" + rnd.Next(1, 9);
var sysNumber = rnd.Next(139, 97654);
var simType = rnd.Next(1, 9).ToString() + ((int?)settings.SimCardType)?.ToString() ?? "1";
try
{
await _smsService.SendPatternSmsAsync(new PatternSmsRequest
{
Recipients = new List<string> { request.DevicePhoneNumber },
PatternCode = "kx3kfqri7g09r02",
Variables = new Dictionary<string, string>
{
{ "deviceId", deviceId },
{ "uploadInterval", uploadInterval },
{ "smsInterval", smsInterval.ToString() },
{ "SysNumber", sysNumber.ToString() },
{ "SimType", simType }
}
}, cancellationToken);
}
catch (Exception smsEx)
{
_logger.LogError(smsEx, "Error sending settings SMS to {PhoneNumber}", request.DevicePhoneNumber);
return new VerifyDeviceTokenResponse
{
Success = false,
Message = "خطا در ارسال پیامک"
};
}
settings.TokenCode = null;
settings.VerificationCode = null;
settings.TokenExpiresAt = null;
settings.UpdatedAt = DateTime.UtcNow;
await _dbContext.SaveChangesAsync(cancellationToken);
_logger.LogInformation("Device token verified for {PhoneNumber}", request.DevicePhoneNumber);
return new VerifyDeviceTokenResponse
{
Success = true,
Message = "تنظیمات با موفقیت ارسال شد",
EncodedSettings = null
};
}
catch (Exception ex)
{
_logger.LogError(ex, "Error verifying device token");
return new VerifyDeviceTokenResponse
{
Success = false,
Message = "خطا در تایید توکن"
};
}
}
}