From 88ce4f70266dfd097289b92b539eb1522112c6f2 Mon Sep 17 00:00:00 2001
From: zhangqi <2794379662@qq.com>
Date: Wed, 21 Apr 2021 17:00:16 +0800
Subject: [PATCH] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E4=BA=8C=E7=BB=B4?=
=?UTF-8?q?=E7=A0=81=E9=95=BF=E5=BA=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Domain/AggregateModel/LinkAggregate/Link.cs | 7 +-
.../Commands/CreateLinkCommandHandler.cs | 11 ++-
QRCodeService/QRCodeService.csproj | 4 -
QRCodeService/Services/IShortCodeService.cs | 13 ++++
QRCodeService/Services/ShortCodeService.cs | 76 +++++++++++++++++++
QRCodeService/Startup.cs | 3 +
6 files changed, 103 insertions(+), 11 deletions(-)
create mode 100644 QRCodeService/Services/IShortCodeService.cs
create mode 100644 QRCodeService/Services/ShortCodeService.cs
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.