update:优化二维码长度
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
13
QRCodeService/Services/IShortCodeService.cs
Normal file
13
QRCodeService/Services/IShortCodeService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
76
QRCodeService/Services/ShortCodeService.cs
Normal file
76
QRCodeService/Services/ShortCodeService.cs
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user