diff --git a/docker-compose.yml b/docker-compose.yml index 521bd47..18ebb27 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -16,6 +16,7 @@ services: - ASPNETCORE_URLS=http://*:80 volumes: # 注意: Linux 下 区分大小写 + - ./App_Data:/app/App_Data # - ./appsettings.json:/app/appsettings.json // 无法使用 docker-compose 此方法 挂载单个文件, 使用下方挂载单个文件 - type: bind source: ./appsettings.json diff --git a/src/Afdian.Server/Afdian.Server.csproj b/src/Afdian.Server/Afdian.Server.csproj index 21e7442..b0949bf 100644 --- a/src/Afdian.Server/Afdian.Server.csproj +++ b/src/Afdian.Server/Afdian.Server.csproj @@ -12,6 +12,7 @@ + @@ -26,7 +27,6 @@ - @@ -34,6 +34,9 @@ Always + + Always + diff --git a/src/Afdian.Server/App_Data/afdian.sqlite b/src/Afdian.Server/App_Data/afdian.sqlite new file mode 100644 index 0000000..a961974 Binary files /dev/null and b/src/Afdian.Server/App_Data/afdian.sqlite differ diff --git a/src/Afdian.Server/Configuration/AfdianConfiguration.cs b/src/Afdian.Server/Configuration/AfdianConfiguration.cs index 4ac6d25..e913658 100644 --- a/src/Afdian.Server/Configuration/AfdianConfiguration.cs +++ b/src/Afdian.Server/Configuration/AfdianConfiguration.cs @@ -2,6 +2,9 @@ { public class AfdianConfiguration { + /// + /// afdian Webhook 路径效验 vToken + /// public string VToken { get; set; } public string UserId { get; set; } diff --git a/src/Afdian.Server/Controllers/BadgeController.cs b/src/Afdian.Server/Controllers/BadgeController.cs index 9506239..d860af6 100644 --- a/src/Afdian.Server/Controllers/BadgeController.cs +++ b/src/Afdian.Server/Controllers/BadgeController.cs @@ -1,8 +1,11 @@ using Afdian.Sdk; using Afdian.Server.Configuration; +using Afdian.Server.RequestModels; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; +using Afdian.Server.Models; +using System.Linq; namespace Afdian.Server.Controllers { @@ -14,10 +17,14 @@ public class BadgeController : ControllerBase private readonly ILogger _logger; + private readonly ApplicationDbContext _applicationDbContext; + #region Ctor - public BadgeController(IOptionsMonitor afdianConfigurationOptionsMonitor, ILogger logger) + public BadgeController(IOptionsMonitor afdianConfigurationOptionsMonitor, ApplicationDbContext applicationDbContext, + ILogger logger) { this.AfdianConfiguration = afdianConfigurationOptionsMonitor.CurrentValue; + _applicationDbContext = applicationDbContext; _logger = logger; } #endregion @@ -25,7 +32,7 @@ public BadgeController(IOptionsMonitor afdianConfigurationO #region Actions [Route("/badge.svg")] - [HttpGet, HttpPost] + [HttpGet] public async Task Badge([FromQuery] string badgeToken) { badgeToken = System.Net.WebUtility.UrlDecode(badgeToken); @@ -42,18 +49,44 @@ public async Task Badge([FromQuery] string badgeToken) } [Route("/{id}/badge.svg")] - [HttpGet, HttpPost] - public async Task Badge([FromRoute] int id) + [HttpGet] + public async Task Badge([FromRoute] int id, [FromQuery] BadgeRequestModel badgeRequestModel) { // TODO: 根据 id 查询数据库 - string userId = ""; - string token = ""; + Badge badge = _applicationDbContext.Badge?.FirstOrDefault(m => m.Id == id); + if (badge == null) + { + return NotFound(); + } + string userId = badge.UserId; + string token = badge.Token; return await Task.FromResult(MakeBadgeSvg(userId, token)); } + [HttpPost] + public async Task Create(string userId, string token) + { + AfdianClient afdianClient = new AfdianClient(userId, token); + var jsonStr = await afdianClient.PingAsync(); + if (!jsonStr.Contains("200")) + { + return Content("不合法的 user_id, token"); + } + Badge badge = new Badge() + { + CreateTime = DateTime.Now, + UserId = userId, + Token = token + }; + await _applicationDbContext.Badge.AddAsync(badge); + await _applicationDbContext.SaveChangesAsync(); + + return Content(badge.Id.ToString()); + } + [Route("/{userId}/{token}/badge.svg")] - [HttpGet, HttpPost] + [HttpGet] public async Task Badge([FromRoute] string userId, [FromRoute] string token) { // 注意: 不要给 将 planId 放入参数列表, 否则变成必需项 @@ -92,7 +125,7 @@ private ContentResult MakeBadgeSvg(string userId, string token, string planId = svgStr = svgStr.Replace("{{count}}", sponsorCount.ToString()).Replace("{{countTextLength}}", countTextLength.ToString()); return Content(svgStr, "image/svg+xml;charset=utf-8"); - } + } #endregion diff --git a/src/Afdian.Server/Controllers/HomeController.cs b/src/Afdian.Server/Controllers/HomeController.cs deleted file mode 100644 index dd2aafc..0000000 --- a/src/Afdian.Server/Controllers/HomeController.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; - -namespace Afdian.Server.Controllers -{ - [Route("/")] - public class HomeController : Controller - { - [Route("")] - [HttpGet] - public ActionResult Index() - { - return File("index.html", "text/html"); - } - } -} diff --git a/src/Afdian.Server/Models/ApplicationDbContext.cs b/src/Afdian.Server/Models/ApplicationDbContext.cs new file mode 100644 index 0000000..6d820e9 --- /dev/null +++ b/src/Afdian.Server/Models/ApplicationDbContext.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; + +namespace Afdian.Server.Models +{ + public class ApplicationDbContext : DbContext + { + public ApplicationDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + // Customize the ASP.NET Identity model and override the defaults if needed. + // For example, you can rename the ASP.NET Identity table names and more. + // Add your customizations after calling base.OnModelCreating(builder); + } + + public virtual DbSet Badge { get; set; } + + } +} diff --git a/src/Afdian.Server/Models/Badge.cs b/src/Afdian.Server/Models/Badge.cs new file mode 100644 index 0000000..995449d --- /dev/null +++ b/src/Afdian.Server/Models/Badge.cs @@ -0,0 +1,18 @@ +using System.ComponentModel.DataAnnotations; + +namespace Afdian.Server.Models +{ + public class Badge + { + [Key] + public int Id { get; set; } + + public string UserId { get; set; } + + public string Token { get; set; } + + public DateTime CreateTime { get; set; } + + public string Ip { get; set; } + } +} diff --git a/src/Afdian.Server/RequestModels/BadgeRequestModel.cs b/src/Afdian.Server/RequestModels/BadgeRequestModel.cs new file mode 100644 index 0000000..6c3510e --- /dev/null +++ b/src/Afdian.Server/RequestModels/BadgeRequestModel.cs @@ -0,0 +1,15 @@ + +using Microsoft.AspNetCore.Mvc; + +namespace Afdian.Server.RequestModels +{ + /// + /// 模型绑定: https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/model-binding?view=aspnetcore-6.0 + /// + public class BadgeRequestModel + { + public string PlanId { get; set; } = ""; + + + } +} diff --git a/src/Afdian.Server/Startup.cs b/src/Afdian.Server/Startup.cs index ed9abc2..f3791fe 100644 --- a/src/Afdian.Server/Startup.cs +++ b/src/Afdian.Server/Startup.cs @@ -1,5 +1,6 @@ using Afdian.Server.Configuration; using Afdian.Server.Services; +using Microsoft.EntityFrameworkCore; using Telegram.Bot; namespace Afdian.Server @@ -57,6 +58,10 @@ public void ConfigureServices(IServiceCollection services) // https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/formatting?view=aspnetcore-5.0#add-newtonsoftjson-based-json-format-support services.AddControllers() .AddNewtonsoftJson(); + + string connectionString = Configuration.GetConnectionString("DefaultConnection"); + services.AddDbContext(options=> + options.UseSqlite(connectionString)); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) @@ -72,10 +77,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseRouting(); app.UseCors(); - app.UseAuthorization(); - + app.UseDefaultFiles(); app.UseStaticFiles(); + app.UseAuthorization(); + app.UseEndpoints(endpoints => { // Configure custom endpoint per Telegram API recommendations: diff --git a/src/Afdian.Server/appsettings.Development.json b/src/Afdian.Server/appsettings.Development.json index e9c6726..9c8b4d6 100644 --- a/src/Afdian.Server/appsettings.Development.json +++ b/src/Afdian.Server/appsettings.Development.json @@ -5,6 +5,9 @@ "Microsoft.AspNetCore": "Warning" } }, + "ConnectionStrings": { + "DefaultConnection": "Data Source=App_Data/afdian.sqlite;" + }, "AfdianConfiguration": { "VToken": "abc", "UserId": "eqe", diff --git a/src/Afdian.Server/appsettings.json b/src/Afdian.Server/appsettings.json index ca05e70..7b679f8 100644 --- a/src/Afdian.Server/appsettings.json +++ b/src/Afdian.Server/appsettings.json @@ -6,6 +6,9 @@ } }, "AllowedHosts": "*", + "ConnectionStrings": { + "DefaultConnection": "Data Source=App_Data/afdian.sqlite;" + }, "AfdianConfiguration": { "VToken": "{VToken}", "UserId": "{UserId}", diff --git a/src/Afdian.Server/wwwroot/index.html b/src/Afdian.Server/wwwroot/index.html index 543dd25..b2d9310 100644 --- a/src/Afdian.Server/wwwroot/index.html +++ b/src/Afdian.Server/wwwroot/index.html @@ -2,9 +2,32 @@ - + Afdian.Server | Afdian.Sdk | 爱发电 非官方 .NET SDK + + + + -
Hello World!
+
+
+
+
+
+ + +
+
+ + +
+ +
+
+
+
+ + + \ No newline at end of file diff --git a/src/Afdian.Server/wwwroot/js/main.js b/src/Afdian.Server/wwwroot/js/main.js new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/src/Afdian.Server/wwwroot/js/main.js @@ -0,0 +1 @@ + \ No newline at end of file