diff --git a/Domain/AggregateModel/LinkAggregate/Link.cs b/Domain/AggregateModel/LinkAggregate/Link.cs
index d96533f..f261dd4 100644
--- a/Domain/AggregateModel/LinkAggregate/Link.cs
+++ b/Domain/AggregateModel/LinkAggregate/Link.cs
@@ -33,15 +33,14 @@ namespace Domain.AggregateModel.LinkAggregate
///
///
/// 分配的应用id
- 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));
}
///
diff --git a/QRCodeService/Application/Commands/CreateLinkCommandHandler.cs b/QRCodeService/Application/Commands/CreateLinkCommandHandler.cs
index 1a8da27..2cdde0f 100644
--- a/QRCodeService/Application/Commands/CreateLinkCommandHandler.cs
+++ b/QRCodeService/Application/Commands/CreateLinkCommandHandler.cs
@@ -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 logger;
readonly IAppRepository appRepository;
+ private readonly IShortCodeService shortCodeService;
readonly ILinkRepository linkRepository;
- public CreateLinkCommandHandler(ILinkRepository linkRepository, IAppRepository appRepository, ILogger logger)
+ public CreateLinkCommandHandler(IShortCodeService shortCodeService,ILinkRepository linkRepository, IAppRepository appRepository, ILogger 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;
diff --git a/QRCodeService/QRCodeService.csproj b/QRCodeService/QRCodeService.csproj
index 30f3b49..d9d359b 100644
--- a/QRCodeService/QRCodeService.csproj
+++ b/QRCodeService/QRCodeService.csproj
@@ -51,10 +51,6 @@
-
-
-
-
diff --git a/QRCodeService/Services/IShortCodeService.cs b/QRCodeService/Services/IShortCodeService.cs
new file mode 100644
index 0000000..3386377
--- /dev/null
+++ b/QRCodeService/Services/IShortCodeService.cs
@@ -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 GenShortCode(string url);
+ }
+}
diff --git a/QRCodeService/Services/ShortCodeService.cs b/QRCodeService/Services/ShortCodeService.cs
new file mode 100644
index 0000000..61cbee4
--- /dev/null
+++ b/QRCodeService/Services/ShortCodeService.cs
@@ -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 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;
+ }
+ }
+
+ }
+ ///
+ /// 计算短链接
+ ///
+ ///
+ /// 4(四分之一) 8(半) 16(全长)
+ ///
+ ///
+ 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());
+ }
+ }
+ }
+}
diff --git a/QRCodeService/Startup.cs b/QRCodeService/Startup.cs
index 650615e..d403f3a 100644
--- a/QRCodeService/Startup.cs
+++ b/QRCodeService/Startup.cs
@@ -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();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.