Skip to content

Commit

Permalink
Merge branch 'master' into feature/transacion_email_opt
Browse files Browse the repository at this point in the history
  • Loading branch information
Edward-BXS authored Sep 30, 2024
2 parents 159154d + 2857518 commit fe8557a
Show file tree
Hide file tree
Showing 11 changed files with 210 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ public class RegisterRequestDto : IValidatableObject

public string AccessToken { get; set; }
public ZkLoginInfoRequestDto ZkLoginInfo { get; set; }

public Dictionary<string, object> ExtraInfo { get; set; } = new();

public IEnumerable<ValidationResult> Validate(
ValidationContext validationContext)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace CAServer.Etos;

public class HolderExtraInfoCompletedEto
{
public string GrainId { get; set; }
public string Status { get; set; }
public string CaHash { get; set; }
public string CaAddress { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using CAServer.EnumType;

namespace CAServer.Etos;

public class HolderExtraInfoEto
{
public string GrainId { get; set; }
public AccountOperationType OperationType { get; set; }
public Dictionary<string,object> ExtraInfo { get; set; }
}
14 changes: 14 additions & 0 deletions src/CAServer.Application/CAAccount/CAAccountAppService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using CAServer.ContractService;
using CAServer.Device;
using CAServer.Dtos;
using CAServer.EnumType;
using CAServer.Etos;
using CAServer.Grains;
using CAServer.Grains.Grain.Account;
Expand Down Expand Up @@ -143,6 +144,7 @@ public async Task<AccountResultDto> RegisterRequestAsync(RegisterRequestDto inpu
registerCreateEto.IpAddress = _ipInfoAppService.GetRemoteIp(input.ReferralInfo?.Random);
await CheckAndResetReferralInfo(input.ReferralInfo, registerCreateEto.IpAddress);
await _distributedEventBus.PublishAsync(registerCreateEto);
await PublishExtraInfoAsync(registerCreateEto.GrainId, input.ExtraInfo);
return new AccountResultDto(registerDto.Id.ToString());
}

Expand Down Expand Up @@ -793,4 +795,16 @@ await _contractProvider.GetHolderInfoAsync(null, Hash.LoadFromHex(loginGuardianI
loginGuardianIdentifierHash, chainId, JsonConvert.SerializeObject(output));
return output?.CaHash?.ToHex();
}

private async Task PublishExtraInfoAsync(string grainId, Dictionary<string, object> extraInfo)
{
if (extraInfo.IsNullOrEmpty()) return;

await _distributedEventBus.PublishAsync(new HolderExtraInfoEto
{
GrainId = grainId,
OperationType = AccountOperationType.Register,
ExtraInfo = extraInfo
});
}
}
1 change: 1 addition & 0 deletions src/CAServer.Application/IpInfo/IIpInfoClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ namespace CAServer.IpInfo;
public interface IIpInfoClient
{
Task<IpInfoDto> GetIpInfoAsync(string ip);
Task<IpInfoDto> GetCountryInfoAsync(string ip);
}
25 changes: 24 additions & 1 deletion src/CAServer.Application/IpInfo/IpInfoClient.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using CAServer.Common;
using CAServer.Http;
using CAServer.Signature.Options;
using CAServer.Signature.Provider;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace CAServer.IpInfo;
Expand All @@ -14,16 +16,21 @@ public class IpInfoClient : IIpInfoClient
private readonly IOptionsMonitor<IpServiceSettingOptions> _ipServiceSetting;
private readonly IOptionsMonitor<SignatureServerOptions> _signatureOptions;
private readonly ISecretProvider _secretProvider;
private readonly IHttpClientProvider _httpClientProvider;
private readonly ILogger<IpInfoClient> _logger;


public IpInfoClient(
IOptionsMonitor<IpServiceSettingOptions> ipServiceSettingOption,
ISecretProvider secretProvider, IHttpProvider httpProvider,
IOptionsMonitor<SignatureServerOptions> signatureOptions)
IOptionsMonitor<SignatureServerOptions> signatureOptions, IHttpClientProvider httpClientProvider,
ILogger<IpInfoClient> logger)
{
_secretProvider = secretProvider;
_httpProvider = httpProvider;
_signatureOptions = signatureOptions;
_httpClientProvider = httpClientProvider;
_logger = logger;
_ipServiceSetting = ipServiceSettingOption;
}

Expand All @@ -36,4 +43,20 @@ public async Task<IpInfoDto> GetIpInfoAsync(string ip)
AssertHelper.IsTrue(response.Error == null, response.Error?.Info ?? "Get ip info failed {}", ip);
return response;
}

public async Task<IpInfoDto> GetCountryInfoAsync(string ip)
{
try
{
var requestUrl = $"{_ipServiceSetting.CurrentValue.BaseUrl.TrimEnd('/')}/{ip}";
requestUrl +=
$"?access_key={_ipServiceSetting.CurrentValue.HolderStatisticAccessKey}&language={_ipServiceSetting.CurrentValue.Language}";
return await _httpClientProvider.GetAsync<IpInfoDto>(requestUrl);
}
catch (Exception e)
{
_logger.LogError("get ip info error, ip:{ip}", ip);
return null;
}
}
}
1 change: 1 addition & 0 deletions src/CAServer.Application/IpInfo/IpServiceSettingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ public class IpServiceSettingOptions
public string AccessKey { get; set; }
public string Language { get; set; }
public int ExpirationDays { get; set; }
public string HolderStatisticAccessKey { get; set; }
}
28 changes: 28 additions & 0 deletions src/CAServer.Domain/Entities/Es/HolderStatisticIndex.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System;
using AElf.Indexing.Elasticsearch;
using CAServer.Account;
using Nest;

namespace CAServer.Entities.Es;

public class HolderStatisticIndex : CAServerEsEntity<string>, IIndexBuild
{
[Keyword] public override string Id { get; set; }
[Keyword] public string CaHash { get; set; }
[Keyword] public string CaAddress { get; set; }
[Keyword] public string IpAddress { get; set; }
[Keyword] public CountryInfo CountryInfo { get; set; }
[Keyword] public string ActivityId { get; set; }
[Keyword] public string Status { get; set; }
[Keyword] public string OperationType { get; set; }
[Keyword] public DateTime CreateTime { get; set; }
}

public class CountryInfo
{
[Keyword] public string CountryCode { get; set; }
[Keyword] public string CountryName { get; set; }
[Keyword] public string RegionCode { get; set; }
[Keyword] public string RegionName { get; set; }
[Keyword] public string City { get; set; }
}
8 changes: 8 additions & 0 deletions src/CAServer.EntityEventHandler.Core/CAAccountHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@ await _distributedEventBus.PublishAsync(new AccountRegisterCompletedEto
},
Context = Context
});

await _distributedEventBus.PublishAsync(new HolderExtraInfoCompletedEto
{
Status = GetAccountStatus(register.RegisterSuccess),
CaAddress = register.CaAddress,
CaHash = register.CaHash,
GrainId = register.GrainId
});
}

public async Task HandleEventAsync(SocialRecoveryEto eventData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using CAServer.Grains.Grain.Account;
using CAServer.Grains.Grain.Contacts;
using CAServer.Growth.Etos;
using CAServer.IpInfo;
using CAServer.Notify.Etos;
using CAServer.RedDot.Etos;
using CAServer.Security.Etos;
Expand Down Expand Up @@ -87,5 +88,7 @@ public CAServerEventHandlerAutoMapperProfile()
.ForMember(t => t.ClientType, m => m.MapFrom(f => f.ClientType.ToString()))
.ForMember(t => t.OperationType, m => m.MapFrom(f => f.OperationType.ToString()))
.ForMember(t => t.CreateTime, f => f.MapFrom(f => DateTime.UtcNow));

CreateMap<IpInfoDto, CountryInfo>();
}
}
109 changes: 109 additions & 0 deletions src/CAServer.EntityEventHandler.Core/HolderStatisticHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using AElf.Indexing.Elasticsearch;
using CAServer.Account;
using CAServer.Entities.Es;
using CAServer.Etos;
using CAServer.IpInfo;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.ObjectMapping;

namespace CAServer.EntityEventHandler.Core;

public class HolderStatisticHandler : IDistributedEventHandler<HolderExtraInfoEto>,
IDistributedEventHandler<HolderExtraInfoCompletedEto>, ITransientDependency
{
private readonly INESTRepository<HolderStatisticIndex, string> _holderStatisticRepository;
private readonly ILogger<HolderStatisticHandler> _logger;
private readonly IIpInfoClient _infoClient;
private readonly IObjectMapper _objectMapper;

private const string IpPattern =
@"^([0,1]?\d{1,2}|2([0-4][0-9]|5[0-5]))(\.([0,1]?\d{1,2}|2([0-4][0-9]|5[0-5]))){3}$";

private const string IpKey = "ip";
private const string ActivityIdKey = "activityId";

public HolderStatisticHandler(INESTRepository<HolderStatisticIndex, string> holderStatisticRepository,
ILogger<HolderStatisticHandler> logger, IIpInfoClient infoClient, IObjectMapper objectMapper)
{
_holderStatisticRepository = holderStatisticRepository;
_logger = logger;
_infoClient = infoClient;
_objectMapper = objectMapper;
}

public async Task HandleEventAsync(HolderExtraInfoEto eventData)
{
if (eventData.ExtraInfo.IsNullOrEmpty()) return;

var statisticIndex = new HolderStatisticIndex
{
Id = eventData.GrainId,
OperationType = eventData.OperationType.ToString(),
CreateTime = DateTime.UtcNow,
Status = AccountOperationStatus.Pending.ToString()
};

if (eventData.ExtraInfo.TryGetValue(ActivityIdKey, out var activityId))
{
statisticIndex.ActivityId = activityId.ToString();
}

if (eventData.ExtraInfo.TryGetValue(IpKey, out var ip))
{
statisticIndex.IpAddress = ip.ToString();
statisticIndex.CountryInfo = await GetCountryInfoAsync(ip.ToString());
}

await _holderStatisticRepository.AddOrUpdateAsync(statisticIndex);
_logger.LogInformation(
"save HolderExtraInfo success, grainId:{grainId},ip:{ip},country:{country},activityId:{activityId}",
statisticIndex.Id, statisticIndex.IpAddress ?? "-", statisticIndex.CountryInfo?.CountryName ?? "-",
statisticIndex.ActivityId ?? "-");
}

public async Task HandleEventAsync(HolderExtraInfoCompletedEto eventData)
{
var statisticIndex = await _holderStatisticRepository.GetAsync(eventData.GrainId);
if (statisticIndex == null) return;

statisticIndex.CaAddress = eventData.CaAddress;
statisticIndex.CaHash = eventData.CaHash;
statisticIndex.Status = eventData.Status;

await _holderStatisticRepository.AddOrUpdateAsync(statisticIndex);
_logger.LogInformation(
"save completed HolderExtraInfo success, grainId:{grainId},ip:{ip},country:{country},activityId:{activityId}",
statisticIndex.Id, statisticIndex.IpAddress ?? "-", statisticIndex.CountryInfo?.CountryName ?? "-",
statisticIndex.ActivityId ?? "-");
}

private async Task<CountryInfo> GetCountryInfoAsync(string ip)
{
if (!(new Regex(IpPattern).IsMatch(ip)))
{
return null;
}

var countryInfo = await _infoClient.GetCountryInfoAsync(ip);
if (countryInfo == null)
{
return null;
}

if (countryInfo.Error != null)
{
_logger.LogError("get ip info error, ip:{0}, error info:{1}", ip,
JsonConvert.SerializeObject(countryInfo.Error));
return null;
}

return _objectMapper.Map<IpInfoDto, CountryInfo>(countryInfo);
}
}

0 comments on commit fe8557a

Please sign in to comment.