update:优化二维码长度

This commit is contained in:
2021-04-21 17:00:16 +08:00
parent 4cf18f0b83
commit 88ce4f7026
6 changed files with 103 additions and 11 deletions

View File

@@ -33,15 +33,14 @@ namespace Domain.AggregateModel.LinkAggregate
/// <param name="baseUrl"></param>
/// <param name="suffixUrl"></param>
/// <param name="appId">分配的应用id</param>
public Link(string baseUrl,string suffixUrl,int appId)
public Link(string baseUrl,string suffixUrl,string fullUrl,int appId,string shortCode)
{
BaseUrl = baseUrl;
SuffixUrl = suffixUrl;
FullUrl = new Uri(new Uri(baseUrl),suffixUrl).ToString();
FullUrl = fullUrl;
ShortCode = shortCode;
AppId = appId;
Time = DateTime.Now;
CalculateShortCode();
AddDomainEvent(new LinkCreatedDomainEvent(this));
}
/// <summary>

View File

@@ -3,6 +3,7 @@ using Domain.AggregateModel.LinkAggregate;
using Domain.Exceptions;
using MediatR;
using Microsoft.Extensions.Logging;
using QRCodeService.Services;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -17,10 +18,12 @@ namespace QRCodeService.Application.Commands
readonly ILogger<CreateLinkCommandHandler> logger;
readonly IAppRepository appRepository;
private readonly IShortCodeService shortCodeService;
readonly ILinkRepository linkRepository;
public CreateLinkCommandHandler(ILinkRepository linkRepository, IAppRepository appRepository, ILogger<CreateLinkCommandHandler> logger)
public CreateLinkCommandHandler(IShortCodeService shortCodeService,ILinkRepository linkRepository, IAppRepository appRepository, ILogger<CreateLinkCommandHandler> logger)
{
this.shortCodeService = shortCodeService;
this.linkRepository = linkRepository;
this.appRepository = appRepository;
this.logger = logger;
@@ -33,13 +36,15 @@ namespace QRCodeService.Application.Commands
{
throw new DomainException("app not found");
}
var link = new Link(app.BaseUrl, request.SuffixUrl, request.AppId);
var dbLink = await linkRepository.GetAsync(link.ShortCode);
var fullUrl = new Uri(new Uri(app.BaseUrl), request.SuffixUrl).ToString();
var shortCode = await shortCodeService.GenShortCode(fullUrl);
var dbLink = await linkRepository.GetAsync(shortCode);
if (dbLink != null)
{
logger.LogDebug("use exist link");
return dbLink;
}
var link = new Link(app.BaseUrl, request.SuffixUrl,fullUrl, request.AppId, shortCode);
link = linkRepository.Add(link);
await linkRepository.UnitOfWork.SaveEntitiesAsync();
return link;

View File

@@ -51,10 +51,6 @@
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Services
{
public interface IShortCodeService
{
Task<string> GenShortCode(string url);
}
}

View File

@@ -0,0 +1,76 @@
using Base62;
using Domain.AggregateModel.LinkAggregate;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Services
{
public class ShortCodeService : IShortCodeService
{
private readonly ILinkRepository linkRepository;
public ShortCodeService(ILinkRepository linkRepository)
{
this.linkRepository = linkRepository;
}
public async Task<string> GenShortCode(string url)
{
var full = 16;
var length = 4;
var idx = 0;
while (true)
{
var code = CalculateShortCode(url, length, idx);
var link = await linkRepository.GetAsync(code);
if (link == null || link.FullUrl == url)
{
return code;
}
idx++;
if (idx * length == full)
{
idx = 0;
length = 2 * length;
}
}
}
/// <summary>
/// 计算短链接
/// </summary>
/// <param name="url"></param>
/// <param name="length">4(四分之一) 8(半) 16(全长)</param>
/// <param name="index"></param>
/// <returns></returns>
private string CalculateShortCode(string url,int length,int index)
{
using (var md5 = MD5.Create())
{
var result = md5.ComputeHash(Encoding.UTF8.GetBytes(url));
if (length == 4)
{
return BitConverter.ToInt32(result, 4 * index).ToBase62();
}
if(length == 8)
{
return BitConverter.ToInt32(result, 8 * index).ToBase62();
}
if(length == 16)
{
return BitConverter.ToInt64(result, 0).ToBase62() + BitConverter.ToInt64(result, 8).ToBase62();
}
if(length > 16)
{
return BitConverter.ToInt64(result, 0).ToBase62() + BitConverter.ToInt64(result, 8).ToBase62() + length.ToBase62();
}
throw (new ArgumentOutOfRangeException());
}
}
}
}

View File

@@ -24,6 +24,7 @@ using QRCodeService.Application.Queries;
using QRCodeService.Application.Validations;
using QRCodeService.Infrastructure.Middlewares;
using QRCodeService.Options;
using QRCodeService.Services;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -90,6 +91,8 @@ namespace QRCodeService
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
});
services.AddTransient<IShortCodeService, ShortCodeService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.