init project

This commit is contained in:
2021-02-23 09:51:50 +08:00
commit f7384b9afc
35 changed files with 938 additions and 0 deletions

View File

@@ -0,0 +1,14 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Commands
{
public class CreateLinkCommand : IRequest<bool>
{
}
}

View File

@@ -0,0 +1,18 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace QRCodeService.Application.Commands
{
public class CreateLinkCommandHandler : IRequestHandler<CreateLinkCommand, bool>
{
public Task<bool> Handle(CreateLinkCommand request, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Queries
{
public class GetLinkQueryHandler
{
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Queries
{
public interface ILinkQueries
{
Task<Link> GetLinkAsync(string shortCode);
}
}

View File

@@ -0,0 +1,32 @@
using MediatR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using MySqlConnector;
namespace QRCodeService.Application.Queries
{
public class LinkQueries : ILinkQueries
{
readonly string _connectionString;
public LinkQueries(string connectionString)
{
_connectionString = connectionString;
}
public async Task<Link> GetLinkAsync(string shortCode)
{
using(var connection = new MySqlConnection(_connectionString))
{
connection.Open();
var link = await connection.QueryAsync<Link>(
@"SELECT A FROM B WHERE ShortCode = @shortCode",new {shortCode });
return link.Single();
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Queries
{
public class Link
{
public string ShortCode { get; set; }
public string FullUrl { get; set; }
}
}

View File

@@ -0,0 +1,58 @@
using Domain.AggregateModel.LinkAggregate;
using Microsoft.AspNetCore.Mvc;
using QRCodeService.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
using Domain.AggregateModel.AppAggregate;
using Base62;
using QRCodeService.Extensions;
namespace QRCodeService.Controllers
{
/// <summary>
/// 生成二维码图片
/// </summary>
[Route("api/[controller]")]
[ApiController]
public class GenController:ControllerBase
{
readonly ILinkRepository linkRepository;
readonly IAppRepository appRepository;
public GenController(ILinkRepository linkRepository, IAppRepository appRepository)
{
this.linkRepository = linkRepository;
this.appRepository = appRepository;
}
[HttpPost]
public async Task<IActionResult> CreateLink(GenInputModel model)
{
var app = await appRepository.GetAsync(model.AppId);
if (app == null)
{
return BadRequest();
}
using(var md5 = MD5.Create())
{
var result = md5.ComputeHash(Encoding.UTF8.GetBytes($"{model.AppId}{model.SuffixUrl}{model.Time}{app.AppKey}"));
var sign = BitConverter.ToString(result);
if (sign != model.Sign)
{
return BadRequest();
}
}
var shortCode = $"{model.SuffixUrl}".ToMD5().ToBase62();
var link = new Link(app.BaseUrl, model.SuffixUrl,1);
linkRepository.Add(link);
await linkRepository.UnitOfWork.SaveEntitiesAsync();
return Ok(link.ShortCode);
}
}
}

View File

@@ -0,0 +1,34 @@
using Domain.AggregateModel.LinkAggregate;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Controllers
{
/// <summary>
/// 跳转url请求的地址
/// </summary>
[Route("{shortCode}")]
[ApiController]
public class GoController: ControllerBase
{
readonly ILinkRepository LinkRepository;
public GoController(ILinkRepository linkRepository)
{
LinkRepository = linkRepository;
}
[HttpGet]
public async Task<IActionResult> Get(string shortcode)
{
var link = await LinkRepository.GetAsync(shortcode);
if (link == null)
{
return NotFound();
}
return Redirect(link.FullUrl);
}
}
}

View File

@@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using QRCoder;
using System.IO;
namespace QRCodeService.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ImageController : ControllerBase
{
[Route("{shortCode}")]
public IActionResult Get(string shortCode)
{
var qrCodeGenerator = new QRCodeGenerator();
var data = qrCodeGenerator.CreateQrCode("www.baidu.com", QRCodeGenerator.ECCLevel.Q);
var qrCode = new QRCode(data);
using (var stream = new MemoryStream())
{
qrCode.GetGraphic(20).Save(stream, System.Drawing.Imaging.ImageFormat.Png);
return File(stream.ToArray(), "image/png", "qrcode.png");
}
}
}
}

View File

@@ -0,0 +1,35 @@
using Base62;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Controllers
{
[Route("[controller]/[action]")]
public class PlaygroundController:ControllerBase
{
public IActionResult GenShortCode(string url)
{
var codes = new string[2];
using (var md5 = MD5.Create())
{
var chunkSize = 8;
var result = md5.ComputeHash(Encoding.UTF8.GetBytes(url));
for (int i = 0; i < 2; i++)
{
var first = result.Take(chunkSize).ToArray();
//即超过30位的忽略处理
var res = BitConverter.ToInt64(first);
var code = res.ToBase62();
codes[i] = code;
result = result.Skip(chunkSize).ToArray();
}
return Ok(codes);
}
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Extensions
{
public static class StringExtension
{
public static byte[] ToMD5(this string value)
{
using (var md5 = MD5.Create())
{
var result = md5.ComputeHash(Encoding.UTF8.GetBytes(value));
return result;
}
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Models
{
public class GenInputModel
{
public int AppId { get; set; }
public string Time { get; set; }
public string SuffixUrl { get; set; }
public string Sign { get; set; }
}
}

26
QRCodeService/Program.cs Normal file
View File

@@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace QRCodeService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

View File

@@ -0,0 +1,31 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:58886",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"QRCodeService": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Base62-Net" Version="1.2.157201" />
<PackageReference Include="Dapper" Version="2.0.78" />
<PackageReference Include="FluentValidation.AspNetCore" Version="9.5.1" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="5.0.1" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.1" NoWarn="NU1605" />
<PackageReference Include="MySqlConnector" Version="1.2.0" />
<PackageReference Include="QRCoder" Version="1.4.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
</ItemGroup>
<ProjectExtensions><VisualStudio><UserProperties properties_4launchsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
</Project>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup>
<ActiveDebugProfile>QRCodeService</ActiveDebugProfile>
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath>
</PropertyGroup>
</Project>

56
QRCodeService/Startup.cs Normal file
View File

@@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace QRCodeService
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "QRCodeService", Version = "v1" });
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "QRCodeService v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}