From d2b257ed36fcaa3a1f7459933d57312fffcccaa6 Mon Sep 17 00:00:00 2001
From: shanj <18996038927@163.com>
Date: Mon, 14 Feb 2022 05:24:48 +0800
Subject: [PATCH] =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=AE=8C=E5=96=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.editorconfig | 7 +
Binance.TradeRobot.API.sln | 15 +-
.../Binance.TradeRobot.API.csproj | 7 +
.../Binance.TradeRobot.API.xml | 86 ++++
.../Controllers/BaseApiController.cs | 11 +
.../Controllers/UserController.cs | 79 +++
.../Controllers/WeatherForecastController.cs | 39 --
.../Extensions/StartupExtenions.cs | 51 +-
.../Properties/launchSettings.json | 4 +-
Binance.TradeRobot.API/Startup.cs | 61 ++-
Binance.TradeRobot.API/WeatherForecast.cs | 15 -
Binance.TradeRobot.API/appsettings.json | 7 +-
Binance.TradeRobot.Business/BaseBusiness.cs | 13 +
.../Binance.TradeRobot.Business.csproj | 3 +
.../Binance.TradeRobot.Business.xml | 8 +
Binance.TradeRobot.Business/UserBusiness.cs | 57 +++
.../Binance.TradeRobot.Common.csproj | 15 +
.../DI/BatchRegistrationAttribute.cs | 31 ++
.../Extensions/CryptographyExtension.cs | 48 ++
.../Extensions/DateTimeExtension.cs | 101 ++++
.../Extensions/EnumExtension.cs | 131 +++++
.../Extensions/MapperExtension.cs | 59 +++
.../Extensions/MathExtension.cs | 51 ++
.../Helpers/ClearMemoryHelper.cs | 27 ++
.../Helpers/ShellExecuteHelper.cs | 49 ++
.../Http/HttpDownloader.cs | 456 ++++++++++++++++++
.../Http/RestAPIService.cs | 93 ++++
.../Tasks/DelayTrigger.cs | 68 +++
.../LimitedConcurrencyLevelTaskScheduler.cs | 156 ++++++
.../Base/MappingProfiles.cs | 8 +
.../Binance.TradeRobot.Model.csproj | 7 +-
.../Binance.TradeRobot.Model.xml | 123 +++++
.../Dto/Request/User/LoginRequest.cs | 16 +
.../Dto/Response/User/LoginResponse.cs | 11 +
.../Dto/Response/User/UserResponse.cs | 6 +
35 files changed, 1821 insertions(+), 98 deletions(-)
create mode 100644 .editorconfig
create mode 100644 Binance.TradeRobot.API/Binance.TradeRobot.API.xml
create mode 100644 Binance.TradeRobot.API/Controllers/BaseApiController.cs
create mode 100644 Binance.TradeRobot.API/Controllers/UserController.cs
delete mode 100644 Binance.TradeRobot.API/Controllers/WeatherForecastController.cs
delete mode 100644 Binance.TradeRobot.API/WeatherForecast.cs
create mode 100644 Binance.TradeRobot.Business/BaseBusiness.cs
create mode 100644 Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
create mode 100644 Binance.TradeRobot.Business/UserBusiness.cs
create mode 100644 Binance.TradeRobot.Common/Binance.TradeRobot.Common.csproj
create mode 100644 Binance.TradeRobot.Common/DI/BatchRegistrationAttribute.cs
create mode 100644 Binance.TradeRobot.Common/Extensions/CryptographyExtension.cs
create mode 100644 Binance.TradeRobot.Common/Extensions/DateTimeExtension.cs
create mode 100644 Binance.TradeRobot.Common/Extensions/EnumExtension.cs
create mode 100644 Binance.TradeRobot.Common/Extensions/MapperExtension.cs
create mode 100644 Binance.TradeRobot.Common/Extensions/MathExtension.cs
create mode 100644 Binance.TradeRobot.Common/Helpers/ClearMemoryHelper.cs
create mode 100644 Binance.TradeRobot.Common/Helpers/ShellExecuteHelper.cs
create mode 100644 Binance.TradeRobot.Common/Http/HttpDownloader.cs
create mode 100644 Binance.TradeRobot.Common/Http/RestAPIService.cs
create mode 100644 Binance.TradeRobot.Common/Tasks/DelayTrigger.cs
create mode 100644 Binance.TradeRobot.Common/Tasks/LimitedConcurrencyLevelTaskScheduler.cs
create mode 100644 Binance.TradeRobot.Model/Base/MappingProfiles.cs
create mode 100644 Binance.TradeRobot.Model/Binance.TradeRobot.Model.xml
create mode 100644 Binance.TradeRobot.Model/Dto/Request/User/LoginRequest.cs
create mode 100644 Binance.TradeRobot.Model/Dto/Response/User/LoginResponse.cs
create mode 100644 Binance.TradeRobot.Model/Dto/Response/User/UserResponse.cs
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..0db2396
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,7 @@
+[*.cs]
+
+# CS8618: 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
+dotnet_diagnostic.CS8618.severity = none
+
+# CS1591: 缺少对公共可见类型或成员的 XML 注释
+dotnet_diagnostic.CS1591.severity = none
diff --git a/Binance.TradeRobot.API.sln b/Binance.TradeRobot.API.sln
index e492144..ae57b65 100644
--- a/Binance.TradeRobot.API.sln
+++ b/Binance.TradeRobot.API.sln
@@ -5,9 +5,16 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binance.TradeRobot.API", "Binance.TradeRobot.API\Binance.TradeRobot.API.csproj", "{D568610C-F70C-406F-AB41-C6E2B89B327F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Binance.TradeRobot.Model", "Binance.TradeRobot.Model\Binance.TradeRobot.Model.csproj", "{2E56BEBE-2330-41D8-AAB7-B6B5CC707BBB}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binance.TradeRobot.Model", "Binance.TradeRobot.Model\Binance.TradeRobot.Model.csproj", "{2E56BEBE-2330-41D8-AAB7-B6B5CC707BBB}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Binance.TradeRobot.Business", "Binance.TradeRobot.Business\Binance.TradeRobot.Business.csproj", "{74CD58F4-1AA3-4EE9-A68B-386C76CF2125}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Binance.TradeRobot.Business", "Binance.TradeRobot.Business\Binance.TradeRobot.Business.csproj", "{74CD58F4-1AA3-4EE9-A68B-386C76CF2125}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Binance.TradeRobot.Common", "Binance.TradeRobot.Common\Binance.TradeRobot.Common.csproj", "{C840DCF2-0E1E-4F9F-9EAA-5A4F80B51BD2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B55091A9-5FBF-486C-98D6-B7E4AF95D345}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -27,6 +34,10 @@ Global
{74CD58F4-1AA3-4EE9-A68B-386C76CF2125}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74CD58F4-1AA3-4EE9-A68B-386C76CF2125}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74CD58F4-1AA3-4EE9-A68B-386C76CF2125}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C840DCF2-0E1E-4F9F-9EAA-5A4F80B51BD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C840DCF2-0E1E-4F9F-9EAA-5A4F80B51BD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C840DCF2-0E1E-4F9F-9EAA-5A4F80B51BD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C840DCF2-0E1E-4F9F-9EAA-5A4F80B51BD2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Binance.TradeRobot.API/Binance.TradeRobot.API.csproj b/Binance.TradeRobot.API/Binance.TradeRobot.API.csproj
index a880a34..6025e8a 100644
--- a/Binance.TradeRobot.API/Binance.TradeRobot.API.csproj
+++ b/Binance.TradeRobot.API/Binance.TradeRobot.API.csproj
@@ -3,13 +3,19 @@
netcoreapp3.1
True
+ Binance.TradeRobot.API.xml
+
+
+
+
+
@@ -17,6 +23,7 @@
+
diff --git a/Binance.TradeRobot.API/Binance.TradeRobot.API.xml b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml
new file mode 100644
index 0000000..cc60b1f
--- /dev/null
+++ b/Binance.TradeRobot.API/Binance.TradeRobot.API.xml
@@ -0,0 +1,86 @@
+
+
+
+ Binance.TradeRobot.API
+
+
+
+
+ 用户登录
+
+
+
+
+
+
+ 获取用户列表
+
+
+
+
+ 获取用户资金变更记录
+
+
+
+
+ 获取用户盈亏记录
+
+
+
+
+ 追投
+
+
+
+
+ 提现
+
+
+
+
+ 转移资金
+
+
+
+
+ 管道请求委托
+
+
+
+
+ 需要处理的状态码字典
+
+
+
+
+
+
+
+
+
+
+
+ 处理方式:返回Json格式
+
+
+
+
+
+
+
+
+ 注册自定义异常中间件
+
+
+
+
+
+
+ 添加Swagger服务
+
+
+
+
+
+
+
diff --git a/Binance.TradeRobot.API/Controllers/BaseApiController.cs b/Binance.TradeRobot.API/Controllers/BaseApiController.cs
new file mode 100644
index 0000000..7cb4b3d
--- /dev/null
+++ b/Binance.TradeRobot.API/Controllers/BaseApiController.cs
@@ -0,0 +1,11 @@
+using Microsoft.AspNetCore.Mvc;
+
+namespace Binance.TradeRobot.API.Controllers
+{
+ [Produces("application/json")]
+ [Route("Api/[Controller]/[Action]")]
+ [ApiController]
+ public class BaseApiController : ControllerBase
+ {
+ }
+}
diff --git a/Binance.TradeRobot.API/Controllers/UserController.cs b/Binance.TradeRobot.API/Controllers/UserController.cs
new file mode 100644
index 0000000..9157db0
--- /dev/null
+++ b/Binance.TradeRobot.API/Controllers/UserController.cs
@@ -0,0 +1,79 @@
+using Binance.TradeRobot.Business;
+using Binance.TradeRobot.Model.Dto;
+using Microsoft.AspNetCore.Mvc;
+
+namespace Binance.TradeRobot.API.Controllers
+{
+ public class UserController : BaseApiController
+ {
+ private UserBusiness userBusiness;
+ public UserController(UserBusiness userBusiness)
+ {
+ this.userBusiness = userBusiness;
+ }
+
+ ///
+ /// 用户登录
+ ///
+ ///
+ ///
+ [HttpPost]
+ public LoginResponse Login([FromBody] LoginRequest loginRequest)
+ {
+ return userBusiness.Login(loginRequest);
+ }
+
+ ///
+ /// 获取用户列表
+ ///
+ [HttpGet]
+ public void GetUserList()
+ {
+
+ }
+
+ ///
+ /// 获取用户资金变更记录
+ ///
+ [HttpGet]
+ public void GetUserAccountFundChangeRecordList()
+ {
+
+ }
+
+ ///
+ /// 获取用户盈亏记录
+ ///
+ [HttpGet]
+ public void GetUserAccountProfitLossRecordList()
+ {
+ }
+
+ ///
+ /// 追投
+ ///
+ [HttpPost]
+ public void AddFunds()
+ {
+
+ }
+
+ ///
+ /// 提现
+ ///
+ [HttpPost]
+ public void ReduceFunds()
+ {
+
+ }
+
+ ///
+ /// 转移资金
+ ///
+ [HttpPost]
+ public void TransferFunds()
+ {
+
+ }
+ }
+}
diff --git a/Binance.TradeRobot.API/Controllers/WeatherForecastController.cs b/Binance.TradeRobot.API/Controllers/WeatherForecastController.cs
deleted file mode 100644
index 07ac644..0000000
--- a/Binance.TradeRobot.API/Controllers/WeatherForecastController.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Extensions.Logging;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace Binance.TradeRobot.API.Controllers
-{
- [ApiController]
- [Route("[controller]")]
- public class WeatherForecastController : ControllerBase
- {
- private static readonly string[] Summaries = new[]
- {
- "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
- };
-
- private readonly ILogger _logger;
-
- public WeatherForecastController(ILogger logger)
- {
- _logger = logger;
- }
-
- [HttpGet]
- public IEnumerable Get()
- {
- var rng = new Random();
- return Enumerable.Range(1, 5).Select(index => new WeatherForecast
- {
- Date = DateTime.Now.AddDays(index),
- TemperatureC = rng.Next(-20, 55),
- Summary = Summaries[rng.Next(Summaries.Length)]
- })
- .ToArray();
- }
- }
-}
diff --git a/Binance.TradeRobot.API/Extensions/StartupExtenions.cs b/Binance.TradeRobot.API/Extensions/StartupExtenions.cs
index 53d6a81..a923bdc 100644
--- a/Binance.TradeRobot.API/Extensions/StartupExtenions.cs
+++ b/Binance.TradeRobot.API/Extensions/StartupExtenions.cs
@@ -1,4 +1,5 @@
using Binance.TradeRobot.API.Middlewares;
+using Binance.TradeRobot.Common.DI;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
@@ -13,41 +14,33 @@ namespace Binance.TradeRobot.API.Extensions
{
public static class StartupExtenions
{
- ///
- /// 批量注册服务
- ///
- /// DI服务
- /// 需要批量注册的程序集集合
- /// 基础类/接口
- /// 服务生命周期
- ///
- public static IServiceCollection BatchRegisterService(this IServiceCollection services, Assembly[] assemblys, Type baseType, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton)
+ public static IServiceCollection BatchRegisterService(this IServiceCollection services, Assembly[] assemblys)
{
- List typeList = new List(); //所有符合注册条件的类集合
+ var registrationInterfaceTypes = new Dictionary(); //待注册集合
+ var registrationSelfTypes = new List();
+
foreach (var assembly in assemblys)
{
//筛选当前程序集下符合条件的类
- var types = assembly.GetTypes().Where(t => !t.IsInterface && !t.IsSealed && !t.IsAbstract && baseType.IsAssignableFrom(t));
- if (types != null && types.Count() > 0)
- typeList.AddRange(types);
- }
- if (typeList.Count() == 0)
- return services;
-
- var typeDic = new Dictionary(); //待注册集合
- foreach (var type in typeList)
- {
- var interfaces = type.GetInterfaces(); //获取接口
- typeDic.Add(type, interfaces);
- }
- if (typeDic.Keys.Count() > 0)
- {
- foreach (var instanceType in typeDic.Keys)
+ var types = assembly.GetTypes().Where(t => !t.IsInterface && !t.IsSealed && !t.IsAbstract && Attribute.IsDefined(t, typeof(BatchRegistrationAttribute)));
+ if (types == null && types.Count() == 0)
+ continue;
+ foreach (var type in types)
{
- foreach (var interfaceType in typeDic[instanceType])
+ var batchRegistrationAttribute = type.GetCustomAttribute(true);
+ if (batchRegistrationAttribute == null)
+ continue;
+
+ if (batchRegistrationAttribute.RegistrationType == RegistrationType.Self)
+ services.Add(new ServiceDescriptor(type, type, batchRegistrationAttribute.ServiceLifetime));
+ else if (batchRegistrationAttribute.RegistrationType == RegistrationType.Interface)
{
- //根据指定的生命周期进行注册
- services.Add(new ServiceDescriptor(interfaceType, instanceType, serviceLifetime));
+ var interfaces = type.GetInterfaces(); //获取接口
+ foreach (var interfaceType in interfaces)
+ {
+ //根据指定的生命周期进行注册
+ services.Add(new ServiceDescriptor(interfaceType, type, batchRegistrationAttribute.ServiceLifetime));
+ }
}
}
}
diff --git a/Binance.TradeRobot.API/Properties/launchSettings.json b/Binance.TradeRobot.API/Properties/launchSettings.json
index 19db158..f88824f 100644
--- a/Binance.TradeRobot.API/Properties/launchSettings.json
+++ b/Binance.TradeRobot.API/Properties/launchSettings.json
@@ -12,7 +12,7 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
- "launchUrl": "weatherforecast",
+ "launchUrl": "",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
@@ -20,7 +20,7 @@
"Binance.TradeRobot.API": {
"commandName": "Project",
"launchBrowser": true,
- "launchUrl": "weatherforecast",
+ "launchUrl": "",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
diff --git a/Binance.TradeRobot.API/Startup.cs b/Binance.TradeRobot.API/Startup.cs
index c0ee4a2..1f8ddf0 100644
--- a/Binance.TradeRobot.API/Startup.cs
+++ b/Binance.TradeRobot.API/Startup.cs
@@ -1,10 +1,21 @@
+using Binance.TradeRobot.API.Extensions;
using Binance.TradeRobot.API.Filters;
+using Binance.TradeRobot.Business;
+using Binance.TradeRobot.Common.Extensions;
+using Binance.TradeRobot.Common.Http;
+using Binance.TradeRobot.Model.Base;
+using HY.TradingRobot.Model.Base;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.IdentityModel.Tokens;
+using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
+using System.Reflection;
+using System.Text;
using Yitter.IdGenerator;
namespace Binance.TradeRobot.API
@@ -21,6 +32,9 @@ namespace Binance.TradeRobot.API
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
+ services.AddSingleton();
+ services.AddSingleton();
+
var fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.SqlServer, Configuration.GetConnectionString("DB")).Build();
services.AddSingleton(typeof(IFreeSql), fsql);
@@ -47,26 +61,61 @@ namespace Binance.TradeRobot.API
setupAction.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Include;
setupAction.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Include;
});
+ services.AddSwagger("ҰԶAPI");
+ services.BatchRegisterService(new Assembly[] { Assembly.Load("Binance.TradeRobot.Business") });
+ services.AddMapper(new MappingProfiles());
+ JsonConvert.DefaultSettings = () => new JsonSerializerSettings()
+ {
+ ContractResolver = new DefaultContractResolver(),
+ DateFormatString = "yyyy-MM-dd HH:mm:ss",
+ NullValueHandling = NullValueHandling.Include,
+ DefaultValueHandling = DefaultValueHandling.Include
+ };
+ services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, x =>
+ {
+ var jwtSecret = Configuration.GetSection("JwtConfig:Secret").Value;
+ var jwtIssuer = Configuration.GetSection("JwtConfig:Issuer").Value;
+ var jwtAudience = Configuration.GetSection("JwtConfig:Audience").Value;
+
+ x.SaveToken = true;
+ x.RequireHttpsMetadata = false;
+ x.TokenValidationParameters = new TokenValidationParameters()
+ {
+ ValidateIssuerSigningKey = true,
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret)),
+ ValidIssuer = jwtIssuer,
+ ValidAudience = jwtAudience,
+ ValidateLifetime = true
+ };
+ });
}
// 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(c => c.SerializeAsV2 = true)
+ .UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "Binance.TradeRobot.API");
+ c.RoutePrefix = string.Empty;
+ });
- app.UseHttpsRedirection();
+ app.UseCustomException();
- app.UseRouting();
+ //app.UseHttpsRedirection();
+ app.UseRouting();
+ app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
+
+ //websocket
}
}
}
diff --git a/Binance.TradeRobot.API/WeatherForecast.cs b/Binance.TradeRobot.API/WeatherForecast.cs
deleted file mode 100644
index 5bb17c6..0000000
--- a/Binance.TradeRobot.API/WeatherForecast.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-
-namespace Binance.TradeRobot.API
-{
- public class WeatherForecast
- {
- public DateTime Date { get; set; }
-
- public int TemperatureC { get; set; }
-
- public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
-
- public string Summary { get; set; }
- }
-}
diff --git a/Binance.TradeRobot.API/appsettings.json b/Binance.TradeRobot.API/appsettings.json
index c97a722..f52a8dd 100644
--- a/Binance.TradeRobot.API/appsettings.json
+++ b/Binance.TradeRobot.API/appsettings.json
@@ -9,6 +9,11 @@
"AllowedHosts": "*",
"ConnectionStrings": {
//"DB": "Data Source=192.168.201.44;Initial Catalog=HY.TradingRobot.DB;User ID=sa;Pwd=kaicn1132+-;"
- "DB": "Data Source=.;Initial Catalog=Binance.TradeRobot.DB;User ID=sa;Pwd=pc911103;"
+ "DB": "Data Source=.;Initial Catalog=Binance.TradeRobot.DB;User ID=sa;Pwd=pc911103;Encrypt=True; TrustServerCertificate=True;"
+ },
+ "JwtConfig": {
+ "Secret": "heyitraderobot11",
+ "Issuer": "heyi",
+ "Audience": "heyi"
}
}
diff --git a/Binance.TradeRobot.Business/BaseBusiness.cs b/Binance.TradeRobot.Business/BaseBusiness.cs
new file mode 100644
index 0000000..c9dcd0d
--- /dev/null
+++ b/Binance.TradeRobot.Business/BaseBusiness.cs
@@ -0,0 +1,13 @@
+namespace Binance.TradeRobot.Business
+{
+ public class BaseBusiness
+ {
+ protected IFreeSql fsql;
+ protected NLogManager logManager;
+ public BaseBusiness(IFreeSql fsql, NLogManager logManager)
+ {
+ this.fsql = fsql;
+ this.logManager = logManager;
+ }
+ }
+}
diff --git a/Binance.TradeRobot.Business/Binance.TradeRobot.Business.csproj b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.csproj
index 10ef69a..f46ef42 100644
--- a/Binance.TradeRobot.Business/Binance.TradeRobot.Business.csproj
+++ b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.csproj
@@ -3,6 +3,8 @@
netstandard2.1
enable
+ True
+ Binance.TradeRobot.Business.xml
@@ -13,6 +15,7 @@
+
diff --git a/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
new file mode 100644
index 0000000..4de0ee0
--- /dev/null
+++ b/Binance.TradeRobot.Business/Binance.TradeRobot.Business.xml
@@ -0,0 +1,8 @@
+
+
+
+ Binance.TradeRobot.Business
+
+
+
+
diff --git a/Binance.TradeRobot.Business/UserBusiness.cs b/Binance.TradeRobot.Business/UserBusiness.cs
new file mode 100644
index 0000000..1395819
--- /dev/null
+++ b/Binance.TradeRobot.Business/UserBusiness.cs
@@ -0,0 +1,57 @@
+using Binance.TradeRobot.Common.DI;
+using Binance.TradeRobot.Common.Extensions;
+using Binance.TradeRobot.Model.Base;
+using Binance.TradeRobot.Model.Db;
+using Binance.TradeRobot.Model.Dto;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
+using System.Text;
+
+namespace Binance.TradeRobot.Business
+{
+ [BatchRegistration(ServiceLifetime.Singleton, RegistrationType.Self)]
+ public class UserBusiness : BaseBusiness
+ {
+ private IConfiguration configuration;
+
+ public UserBusiness(IFreeSql fsql, NLogManager logManager, IConfiguration configuration) : base(fsql, logManager)
+ {
+ this.configuration = configuration;
+ }
+
+ public LoginResponse Login(LoginRequest loginRequest)
+ {
+ var pwd = loginRequest.Pwd.ToMD5();
+ var user = fsql.Select().Where(u => u.UserName == loginRequest.UserName && u.Pwd == pwd).ToOne();
+ if (user == null)
+ throw new BusinessException("用户名或密码错误");
+
+ #region 签发token
+ var claims = new List()
+ {
+ new Claim("Id",user.Id.ToString()),
+ new Claim("UserName",user.UserName),
+ };
+
+ var jwtSecret = configuration.GetSection("JwtConfig:Secret").Value;
+ var jwtIssuer = configuration.GetSection("JwtConfig:Issuer").Value;
+ var jwtAudience = configuration.GetSection("JwtConfig:Audience").Value;
+ var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret));
+ var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+ var jwtToken = new JwtSecurityToken(jwtIssuer, jwtAudience, claims, expires: DateTime.Now.AddDays(30), signingCredentials: credentials);
+ var token = new JwtSecurityTokenHandler().WriteToken(jwtToken);
+ #endregion
+ return new LoginResponse()
+ {
+ Id = user.Id,
+ UserName = user.UserName,
+ Token = token
+ };
+ }
+ }
+}
diff --git a/Binance.TradeRobot.Common/Binance.TradeRobot.Common.csproj b/Binance.TradeRobot.Common/Binance.TradeRobot.Common.csproj
new file mode 100644
index 0000000..4734353
--- /dev/null
+++ b/Binance.TradeRobot.Common/Binance.TradeRobot.Common.csproj
@@ -0,0 +1,15 @@
+
+
+
+ netstandard2.1
+ enable
+
+
+
+
+
+
+
+
+
+
diff --git a/Binance.TradeRobot.Common/DI/BatchRegistrationAttribute.cs b/Binance.TradeRobot.Common/DI/BatchRegistrationAttribute.cs
new file mode 100644
index 0000000..adbf8d8
--- /dev/null
+++ b/Binance.TradeRobot.Common/DI/BatchRegistrationAttribute.cs
@@ -0,0 +1,31 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+
+namespace Binance.TradeRobot.Common.DI
+{
+ [AttributeUsage(AttributeTargets.Class)]
+ public class BatchRegistrationAttribute : Attribute
+ {
+ public ServiceLifetime ServiceLifetime;
+ public RegistrationType RegistrationType;
+
+ ///
+ /// 批量注册特性
+ ///
+ /// 生命周期
+ /// 注册类型
+ public BatchRegistrationAttribute(ServiceLifetime serviceLifetime, RegistrationType registrationType)
+ {
+ this.ServiceLifetime = serviceLifetime;
+ this.RegistrationType = registrationType;
+ }
+ }
+
+ ///
+ /// 注册类型
+ ///
+ public enum RegistrationType
+ {
+ Interface, Self
+ }
+}
diff --git a/Binance.TradeRobot.Common/Extensions/CryptographyExtension.cs b/Binance.TradeRobot.Common/Extensions/CryptographyExtension.cs
new file mode 100644
index 0000000..98dffb8
--- /dev/null
+++ b/Binance.TradeRobot.Common/Extensions/CryptographyExtension.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Binance.TradeRobot.Common.Extensions
+{
+ public static class CryptographyExtension
+ {
+ public static string ToHmacSha256(this string str, string secret, bool toBase64 = true)
+ {
+ secret = secret ?? "";
+ byte[] keyByte = Encoding.UTF8.GetBytes(secret);
+ byte[] strBytes = Encoding.UTF8.GetBytes(str);
+ using (var hmacsha256 = new HMACSHA256(keyByte))
+ {
+ byte[] hashStr = hmacsha256.ComputeHash(strBytes);
+ if (toBase64)
+ return Convert.ToBase64String(hashStr);
+ else
+ {
+ StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < hashStr.Length; i++)
+ {
+ builder.Append(hashStr[i].ToString("x2"));
+ }
+ return builder.ToString();
+ }
+ }
+ }
+
+ public static string ToMD5(this string str, bool isUpper = false)
+ {
+ var format = isUpper ? "X2" : "x2";
+ //32位大写
+ using (var md5 = MD5.Create())
+ {
+ var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
+ StringBuilder builder = new StringBuilder();
+ // 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
+ for (int i = 0; i < data.Length; i++)
+ {
+ builder.Append(data[i].ToString(format));
+ }
+ return builder.ToString();
+ }
+ }
+ }
+}
diff --git a/Binance.TradeRobot.Common/Extensions/DateTimeExtension.cs b/Binance.TradeRobot.Common/Extensions/DateTimeExtension.cs
new file mode 100644
index 0000000..4458aac
--- /dev/null
+++ b/Binance.TradeRobot.Common/Extensions/DateTimeExtension.cs
@@ -0,0 +1,101 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Binance.TradeRobot.Common.Extensions
+{
+ public static class DateTimeExtension
+ {
+ private static readonly DateTime beginTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
+
+ ///
+ /// 时间戳转时间
+ ///
+ /// 时间
+ /// true:13, false:10
+ ///
+ [Obsolete]
+ public static DateTime StampToDateTime(this long timeStamp)
+ {
+ DateTime dt = TimeZone.CurrentTimeZone.ToLocalTime(beginTime);
+ return timeStamp.ToString().Length == 13 ? dt.AddMilliseconds(timeStamp) : dt.AddSeconds(timeStamp);
+ }
+
+ ///
+ /// 时间转时间戳
+ ///
+ /// 时间
+ /// true:13, false:10
+ ///
+ [Obsolete]
+ public static long DateTimeToStamp(this DateTime time, bool len13 = true)
+ {
+ TimeSpan ts = time.ToUniversalTime() - beginTime;
+ if (len13)
+ return Convert.ToInt64(ts.TotalMilliseconds);
+ else
+ return Convert.ToInt64(ts.TotalSeconds);
+ }
+
+ ///
+ /// 将秒数转换为时分秒形式
+ ///
+ ///
+ ///
+ public static string FormatToHHmmss(long second)
+ {
+ if (second < 60)
+ return $"00:00:{(second >= 10 ? $"{second}" : $"0{second}")}";
+ if (second < 3600)
+ {
+ var minute = second / 60;
+ var s = second % 60;
+ return $"00:{(minute >= 10 ? $"{minute}" : $"0{minute}")}:{(s >= 10 ? $"{s}" : $"0{s}")}";
+ }
+ else
+ {
+ var hour = second / 3600;
+ var minute = (second - (hour * 3600)) / 60;
+ var s = (second - ((hour * 3600) + minute * 60)) % 60;
+ return $"{(hour >= 10 ? $"{hour}" : $"0{hour}")}:{(minute >= 10 ? $"{minute}" : $"0{minute}")}:{(s >= 10 ? $"{s}" : $"0{s}")}";
+ }
+ }
+
+ #region SetLocalTime
+ [DllImport("Kernel32.dll")]
+ private static extern bool SetLocalTime(ref SYSTEMTIME lpSystemTime);
+
+ [StructLayout(LayoutKind.Sequential)]
+ private struct SYSTEMTIME
+ {
+ public ushort wYear;
+ public ushort wMonth;
+ public ushort wDayOfWeek;
+ public ushort wDay;
+ public ushort wHour;
+ public ushort wMinute;
+ public ushort wSecond;
+ public ushort wMilliseconds;
+ }
+
+ ///
+ /// 修改系统时间(需要管理员权限)
+ ///
+ ///
+ public static void SetSystemTime(DateTime date)
+ {
+ SYSTEMTIME lpTime = new SYSTEMTIME();
+ lpTime.wYear = Convert.ToUInt16(date.Year);
+ lpTime.wMonth = Convert.ToUInt16(date.Month);
+ lpTime.wDayOfWeek = Convert.ToUInt16(date.DayOfWeek);
+ lpTime.wDay = Convert.ToUInt16(date.Day);
+ DateTime time = date;
+ lpTime.wHour = Convert.ToUInt16(time.Hour);
+ lpTime.wMinute = Convert.ToUInt16(time.Minute);
+ lpTime.wSecond = Convert.ToUInt16(time.Second);
+ lpTime.wMilliseconds = Convert.ToUInt16(time.Millisecond);
+ var r = SetLocalTime(ref lpTime);
+ Console.WriteLine($"修改系统时间 {r}");
+ }
+ #endregion
+ }
+}
diff --git a/Binance.TradeRobot.Common/Extensions/EnumExtension.cs b/Binance.TradeRobot.Common/Extensions/EnumExtension.cs
new file mode 100644
index 0000000..58a0df1
--- /dev/null
+++ b/Binance.TradeRobot.Common/Extensions/EnumExtension.cs
@@ -0,0 +1,131 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+
+namespace Binance.TradeRobot.Common.Extensions
+{
+ public static class EnumExtension
+ {
+ ///
+ /// 从枚举中获取Description
+ ///
+ /// 需要获取枚举描述的枚举
+ /// 描述内容
+ public static string GetDescription(this System.Enum enumName)
+ {
+ var fieldInfo = enumName.GetType().GetField(enumName.ToString());
+ var attributes = GetDescriptAttr(fieldInfo);
+ string description;
+ if (attributes != null && attributes.Length > 0)
+ {
+ description = attributes[0].Description;
+ }
+ else
+ {
+ description = enumName.ToString();
+ }
+ return description;
+ }
+
+ ///
+ /// 根据 value 值获取Description
+ ///
+ ///
+ ///
+ ///
+ public static string GetDescription(this Type enumType, int value)
+ {
+ var Key = GetNameAndValue(enumType).FirstOrDefault(p => p.Value.Equals(value)).Key;
+ if (Key == null)
+ return null;
+
+ return Key.ToString();
+ }
+
+ ///
+ /// 获取字段Description
+ ///
+ /// FieldInfo
+ /// DescriptionAttribute[]
+ private static DescriptionAttribute[] GetDescriptAttr(FieldInfo fieldInfo)
+ {
+ if (fieldInfo != null)
+ {
+ return (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
+ }
+ return null;
+ }
+
+ ///
+ /// 获取枚举所有名称
+ ///
+ /// 枚举类型typeof(T)
+ /// 枚举名称列表
+ public static List GetEnumNamesList(this Type enumType)
+ {
+ return Enum.GetNames(enumType).ToList();
+ }
+
+ ///
+ /// 获取所有枚举对应的值
+ ///
+ /// 枚举类型typeof(T)
+ /// 枚举值列表
+ public static List GetEnumValuesList(this Type enumType)
+ {
+ var list = new List();
+ foreach (var value in System.Enum.GetValues(enumType))
+ {
+ list.Add(Convert.ToInt32(value));
+ }
+ return list;
+ }
+
+ ///
+ /// 获取枚举名以及对应的Description
+ ///
+ /// 枚举类型typeof(T)
+ /// 返回Dictionary ,Key为枚举名, Value为枚举对应的Description
+ public static Dictionary