Browse Source

初始化项目

GOIAggregation
shanji 2 years ago
parent
commit
6b9a4b9fa3
  1. 43
      SiNan.API.sln
  2. 30
      SiNan.API/Filters/ResultFilter.cs
  3. 55
      SiNan.API/Middlewares/ClientVersionValidationMiddleWare.cs
  4. 86
      SiNan.API/Middlewares/CustomExceptionMiddleWare.cs
  5. 14
      SiNan.API/NLog.config
  6. 147
      SiNan.API/Program.cs
  7. 0
      SiNan.API/Properties/launchSettings.json
  8. 30
      SiNan.API/SiNan.API.csproj
  9. 25
      SiNan.API/SiNan.API.sln
  10. 26
      SiNan.API/SiNan.API/Pages/Error.cshtml
  11. 27
      SiNan.API/SiNan.API/Pages/Error.cshtml.cs
  12. 10
      SiNan.API/SiNan.API/Pages/Index.cshtml
  13. 20
      SiNan.API/SiNan.API/Pages/Index.cshtml.cs
  14. 8
      SiNan.API/SiNan.API/Pages/Privacy.cshtml
  15. 19
      SiNan.API/SiNan.API/Pages/Privacy.cshtml.cs
  16. 51
      SiNan.API/SiNan.API/Pages/Shared/_Layout.cshtml
  17. 48
      SiNan.API/SiNan.API/Pages/Shared/_Layout.cshtml.css
  18. 2
      SiNan.API/SiNan.API/Pages/Shared/_ValidationScriptsPartial.cshtml
  19. 3
      SiNan.API/SiNan.API/Pages/_ViewImports.cshtml
  20. 3
      SiNan.API/SiNan.API/Pages/_ViewStart.cshtml
  21. 25
      SiNan.API/SiNan.API/Program.cs
  22. 9
      SiNan.API/SiNan.API/SiNan.API.csproj
  23. 9
      SiNan.API/SiNan.API/appsettings.json
  24. 0
      SiNan.API/appsettings.Development.json
  25. 14
      SiNan.API/appsettings.json
  26. 0
      SiNan.API/wwwroot/css/site.css
  27. 0
      SiNan.API/wwwroot/favicon.ico
  28. 0
      SiNan.API/wwwroot/js/site.js
  29. 0
      SiNan.API/wwwroot/lib/bootstrap/LICENSE
  30. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css
  31. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map
  32. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css
  33. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map
  34. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css
  35. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map
  36. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css
  37. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map
  38. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css
  39. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map
  40. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css
  41. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map
  42. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css
  43. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map
  44. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css
  45. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map
  46. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css
  47. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map
  48. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css
  49. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map
  50. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css
  51. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map
  52. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css
  53. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map
  54. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css
  55. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map
  56. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css
  57. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map
  58. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css
  59. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map
  60. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css
  61. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map
  62. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js
  63. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map
  64. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js
  65. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map
  66. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js
  67. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map
  68. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js
  69. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map
  70. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js
  71. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map
  72. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js
  73. 0
      SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map
  74. 0
      SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
  75. 0
      SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
  76. 0
      SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
  77. 0
      SiNan.API/wwwroot/lib/jquery-validation/LICENSE.md
  78. 0
      SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.js
  79. 0
      SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
  80. 0
      SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.js
  81. 0
      SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
  82. 0
      SiNan.API/wwwroot/lib/jquery/LICENSE.txt
  83. 0
      SiNan.API/wwwroot/lib/jquery/dist/jquery.js
  84. 0
      SiNan.API/wwwroot/lib/jquery/dist/jquery.min.js
  85. 0
      SiNan.API/wwwroot/lib/jquery/dist/jquery.min.map
  86. 11
      SiNan.Business/FreeSqlMultiDBManager.cs
  87. 24
      SiNan.Business/SiNan.Business.csproj
  88. 20
      SiNan.Business/TaskSchedulerManager.cs
  89. 29
      SiNan.Common/Extensions/ConverterExtensions.cs
  90. 12
      SiNan.Common/Extensions/CopyExtensions.cs
  91. 99
      SiNan.Common/Extensions/DateTimeExtension.cs
  92. 82
      SiNan.Common/Extensions/EncryptionExtension.cs
  93. 59
      SiNan.Common/Extensions/MapperExtension.cs
  94. 34
      SiNan.Common/Extensions/StartupExtension.cs
  95. 452
      SiNan.Common/Http/HttpDownloader.cs
  96. 117
      SiNan.Common/Http/RestAPIService.cs
  97. 34
      SiNan.Common/Models/ApiResponse.cs
  98. 18
      SiNan.Common/Models/BusinessException.cs
  99. 10
      SiNan.Common/Models/IDenpendency.cs
  100. 18
      SiNan.Common/SiNan.Common.csproj

43
SiNan.API.sln

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34024.191
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiNan.API", "SiNan.API\SiNan.API.csproj", "{33F844AA-8786-4294-8F5A-2E5ED03D56FF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiNan.Business", "SiNan.Business\SiNan.Business.csproj", "{D936217A-5B0C-4E88-B9BD-F97A3C2EA1D9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiNan.Model", "SiNan.Model\SiNan.Model.csproj", "{8524A12A-FE6B-49BC-866B-52CB53C8BD1F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiNan.Common", "SiNan.Common\SiNan.Common.csproj", "{521CB52C-EA2F-482D-AE07-EEF966552094}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Release|Any CPU.Build.0 = Release|Any CPU
{D936217A-5B0C-4E88-B9BD-F97A3C2EA1D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D936217A-5B0C-4E88-B9BD-F97A3C2EA1D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D936217A-5B0C-4E88-B9BD-F97A3C2EA1D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D936217A-5B0C-4E88-B9BD-F97A3C2EA1D9}.Release|Any CPU.Build.0 = Release|Any CPU
{8524A12A-FE6B-49BC-866B-52CB53C8BD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8524A12A-FE6B-49BC-866B-52CB53C8BD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8524A12A-FE6B-49BC-866B-52CB53C8BD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8524A12A-FE6B-49BC-866B-52CB53C8BD1F}.Release|Any CPU.Build.0 = Release|Any CPU
{521CB52C-EA2F-482D-AE07-EEF966552094}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{521CB52C-EA2F-482D-AE07-EEF966552094}.Debug|Any CPU.Build.0 = Debug|Any CPU
{521CB52C-EA2F-482D-AE07-EEF966552094}.Release|Any CPU.ActiveCfg = Release|Any CPU
{521CB52C-EA2F-482D-AE07-EEF966552094}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A3B189CF-4897-44E3-A2E2-BB445F7512FD}
EndGlobalSection
EndGlobal

30
SiNan.API/Filters/ResultFilter.cs

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using SiNan.Common.Models;
namespace SiNan.API.Filters
{
public class ResultFilter : IResultFilter
{
public void OnResultExecuted(ResultExecutedContext context)
{
}
public void OnResultExecuting(ResultExecutingContext context)
{
if (context.Result is ObjectResult)
{
var objectResult = context.Result as ObjectResult;
if (!(objectResult.Value is ApiResponse))
{
objectResult.Value = new ApiResponse() { Data = objectResult.Value };
}
}
else if (context.Result is EmptyResult)
{
context.Result = new ObjectResult(new ApiResponse());
}
}
}
}

55
SiNan.API/Middlewares/ClientVersionValidationMiddleWare.cs

@ -0,0 +1,55 @@
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using SiNan.Common.Models;
namespace SiNan.API.Middlewares
{
public class ClientVersionValidationMiddleWare
{
/// <summary>
/// 管道请求委托
/// </summary>
private RequestDelegate _next;
private IDictionary<string, int> apiVersionDictionary;
private IOptionsMonitor<List<ClientVersionValidationModel>> _monitor;
public ClientVersionValidationMiddleWare(RequestDelegate requestDelegate, IOptionsMonitor<List<ClientVersionValidationModel>> monitor)
{
_next = requestDelegate;
_monitor = monitor;
apiVersionDictionary = new Dictionary<string, int>();
}
public async Task Invoke(HttpContext context)
{
try
{
Console.WriteLine(context.Request.Path);
var apiRequirement = _monitor.CurrentValue.FirstOrDefault(x => x.Api.Equals(context.Request.Path, StringComparison.CurrentCultureIgnoreCase));
if (apiRequirement != null)
{
if (!context.Request.Headers.TryGetValue("ClientVersion", out StringValues clientVersionStr))
throw new BusinessException("缺少版本信息,请更新司南");
if (!int.TryParse(clientVersionStr, out int clientVersion))
throw new BusinessException("版本信息不正确,请更新司南");
if (clientVersion < apiRequirement.MinimumVersion)
throw new BusinessException("当前请求需更新司南");
}
await _next(context); //调用管道执行下一个中间件
}
catch
{
throw;
}
}
}
public class ClientVersionValidationModel
{
public string Api { get; set; }
public int MinimumVersion { get; set; }
}
}

86
SiNan.API/Middlewares/CustomExceptionMiddleWare.cs

@ -0,0 +1,86 @@
using Newtonsoft.Json;
using SiNan.Common.Log;
using SiNan.Common.Models;
using System.Text;
namespace SiNan.API.Middlewares
{
public class CustomExceptionMiddleWare
{
/// <summary>
/// 管道请求委托
/// </summary>
private RequestDelegate _next;
/// <summary>
/// 需要处理的状态码字典
/// </summary>
private IDictionary<int, string> _exceptionStatusCodeDic;
//private NLogManager nLogManager;
private NLogManager nLogManager;
public CustomExceptionMiddleWare(RequestDelegate next, NLogManager nLogManager)
{
_next = next;
//this.logger = logger;
this.nLogManager = nLogManager;
_exceptionStatusCodeDic = new Dictionary<int, string>
{
{ 401, "未授权的请求" },
{ 404, "找不到该资源" },
{ 403, "访问被拒绝" },
{ 500, "服务器发生意外的错误" },
{ 503, "服务不可用" }
//其余状态自行扩展
};
}
public async Task Invoke(HttpContext context)
{
try
{
await _next(context); //调用管道执行下一个中间件
}
catch (Exception ex)
{
if (ex is BusinessException)
{
var busEx = ex as BusinessException;
context.Response.StatusCode = 200; //业务异常时将Http状态码改为200
await ErrorHandle(context, busEx.Code, busEx.Message);
}
else
{
context.Response.Clear();
context.Response.StatusCode = 500; //发生未捕获的异常,手动设置状态码
//logger.Error(ex); //记录错误
nLogManager.Default().Error(ex);
}
}
finally
{
if (_exceptionStatusCodeDic.TryGetValue(context.Response.StatusCode, out string exMsg))
{
await ErrorHandle(context, context.Response.StatusCode, exMsg);
}
}
}
/// <summary>
/// 处理方式:返回Json格式
/// </summary>
/// <param name="context"></param>
/// <param name="code"></param>
/// <param name="exMsg"></param>
/// <returns></returns>
private async Task ErrorHandle(HttpContext context, int code, string exMsg)
{
var apiResponse = ApiResponse.Error(code, exMsg);
var serialzeStr = JsonConvert.SerializeObject(apiResponse);
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(serialzeStr, Encoding.UTF8);
}
}
}

14
SiNan.API/NLog.config

@ -0,0 +1,14 @@
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="errorFile" xsi:type="File" fileName="${basedir}/logs/${logger}/error/${shortdate}.txt"
layout="${longdate} | ${level:uppercase=false} ${newline}${message} ${newline}${onexception:${exception:format=tostring} ${newline}${stacktrace} ${newline}${newline}"
autoFlush="true"/>
<target name="infoFile" xsi:type="File" fileName="${basedir}/logs/${logger}/info/${shortdate}.txt"
layout="${longdate} | ${level:uppercase=false} ${newline}${message} ${newline}"
autoFlush="true"/>
</targets>
<rules>
<logger name="*" level="Error" writeTo="errorFile"/>
<logger name="*" level="Info" writeTo="infoFile" />
</rules>
</nlog>

147
SiNan.API/Program.cs

@ -0,0 +1,147 @@
using SiNan.API.Filters;
using SiNan.Business;
using SiNan.Common.Http;
using SiNan.Common.Log;
using Yitter.IdGenerator;
using Newtonsoft.Json.Serialization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.OpenApi.Models;
using System.Reflection;
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;
services.AddMemoryCache();
var idOption = new IdGeneratorOptions(1);
var idGenerator = new DefaultIdGenerator(idOption);
services.AddSingleton(typeof(IIdGenerator), idGenerator);
var fsql = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, configuration.GetConnectionString("BBWYCDB")).Build();
services.AddSingleton(typeof(IFreeSql), fsql);
var fsql2 = new FreeSql.FreeSqlBuilder().UseConnectionString(FreeSql.DataType.MySql, configuration.GetConnectionString("MDSDB")).Build();
services.AddSingleton(new FreeSqlMultiDBManager()
{
MDSfsql = fsql2,
BBWYCfsql = fsql
});
services.AddSingleton<NLogManager>();
services.AddSingleton<RestApiService>();
services.AddSingleton<TaskSchedulerManager>();
services.AddMemoryCache();
services.AddControllers();
services.AddHttpContextAccessor();
services.AddHttpClient();
services.AddHttpClient("gzip").ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler()
{
AutomaticDecompression = System.Net.DecompressionMethods.GZip
});
services.AddCors(options =>
{
options.AddPolicy("cors", p =>
{
p.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
});
});
services.AddControllers(c =>
{
c.Filters.Add<ResultFilter>();
c.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true;
}).AddNewtonsoftJson(setupAction =>
{
setupAction.SerializerSettings.ContractResolver = new DefaultContractResolver();
setupAction.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//setupAction.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
//setupAction.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Include;
});
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1.0.0",
Title = "司南API",
Description = "注意事项\r\n1.返回参数名称采用大驼峰命名\r\n2.ApiResponse为基础返回对象(Code,Data,Message),接口中所有的返回值均属于Data属性\r\n3.正常返回Code=200"
});
//JWT认证
c.AddSecurityDefinition(JwtBearerDefaults.AuthenticationScheme, new OpenApiSecurityScheme
{
Scheme = JwtBearerDefaults.AuthenticationScheme,
BearerFormat = "JWT",
Type = SecuritySchemeType.ApiKey,
Name = "Authorization",
In = ParameterLocation.Header,
Description = "Authorization:Bearer {your JWT token}<br/>",
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme{Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = JwtBearerDefaults.AuthenticationScheme
}
},
new string[] { }
}
});
var executingAssembly = Assembly.GetExecutingAssembly();
var assemblyNames = executingAssembly.GetReferencedAssemblies().Union(new AssemblyName[] { executingAssembly.GetName() }).ToArray();
Array.ForEach(assemblyNames, (assemblyName) =>
{
//var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlFile = $"{assemblyName.Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
if (!File.Exists(xmlPath))
return;
c.IncludeXmlComments(xmlPath, true);
});
});
var secret = configuration.GetSection("Secret").Value;
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, x =>
{
x.SaveToken = true;
x.RequireHttpsMetadata = false;
x.TokenValidationParameters = new TokenValidationParameters()
{
ClockSkew = TimeSpan.Zero,
ValidateIssuerSigningKey = true,
ValidateIssuer = false,
ValidateAudience = false,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret)),
//ValidIssuer = issuer,
//ValidAudience = audience,
//ValidateLifetime = true
};
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();

0
SiNan.API/SiNan.API/Properties/launchSettings.json → SiNan.API/Properties/launchSettings.json

30
SiNan.API/SiNan.API.csproj

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="FreeSql" Version="3.2.801" />
<PackageReference Include="FreeSql.Provider.MySql" Version="3.2.801" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.23" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.23" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SiNan.Business\SiNan.Business.csproj" />
<ProjectReference Include="..\SiNan.Common\SiNan.Common.csproj" />
<ProjectReference Include="..\SiNan.Model\SiNan.Model.csproj" />
</ItemGroup>
</Project>

25
SiNan.API/SiNan.API.sln

@ -1,25 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34024.191
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiNan.API", "SiNan.API\SiNan.API.csproj", "{33F844AA-8786-4294-8F5A-2E5ED03D56FF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{33F844AA-8786-4294-8F5A-2E5ED03D56FF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A3B189CF-4897-44E3-A2E2-BB445F7512FD}
EndGlobalSection
EndGlobal

26
SiNan.API/SiNan.API/Pages/Error.cshtml

@ -1,26 +0,0 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>

27
SiNan.API/SiNan.API/Pages/Error.cshtml.cs

@ -1,27 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Diagnostics;
namespace SiNan.API.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
[IgnoreAntiforgeryToken]
public class ErrorModel : PageModel
{
public string? RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}

10
SiNan.API/SiNan.API/Pages/Index.cshtml

@ -1,10 +0,0 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>

20
SiNan.API/SiNan.API/Pages/Index.cshtml.cs

@ -1,20 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SiNan.API.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

8
SiNan.API/SiNan.API/Pages/Privacy.cshtml

@ -1,8 +0,0 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>
<p>Use this page to detail your site's privacy policy.</p>

19
SiNan.API/SiNan.API/Pages/Privacy.cshtml.cs

@ -1,19 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace SiNan.API.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}

51
SiNan.API/SiNan.API/Pages/Shared/_Layout.cshtml

@ -1,51 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - SiNan.API</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
<link rel="stylesheet" href="~/SiNan.API.styles.css" asp-append-version="true" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-page="/Index">SiNan.API</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2023 - SiNan.API - <a asp-area="" asp-page="/Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@await RenderSectionAsync("Scripts", required: false)
</body>
</html>

48
SiNan.API/SiNan.API/Pages/Shared/_Layout.cshtml.css

@ -1,48 +0,0 @@
/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
for details on configuring this project to bundle and minify static web assets. */
a.navbar-brand {
white-space: normal;
text-align: center;
word-break: break-all;
}
a {
color: #0077cc;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.border-top {
border-top: 1px solid #e5e5e5;
}
.border-bottom {
border-bottom: 1px solid #e5e5e5;
}
.box-shadow {
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
}
button.accept-policy {
font-size: 1rem;
line-height: inherit;
}
.footer {
position: absolute;
bottom: 0;
width: 100%;
white-space: nowrap;
line-height: 60px;
}

2
SiNan.API/SiNan.API/Pages/Shared/_ValidationScriptsPartial.cshtml

@ -1,2 +0,0 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>

3
SiNan.API/SiNan.API/Pages/_ViewImports.cshtml

@ -1,3 +0,0 @@
@using SiNan.API
@namespace SiNan.API.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

3
SiNan.API/SiNan.API/Pages/_ViewStart.cshtml

@ -1,3 +0,0 @@
@{
Layout = "_Layout";
}

25
SiNan.API/SiNan.API/Program.cs

@ -1,25 +0,0 @@
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorPages();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.Run();

9
SiNan.API/SiNan.API/SiNan.API.csproj

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

9
SiNan.API/SiNan.API/appsettings.json

@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

0
SiNan.API/SiNan.API/appsettings.Development.json → SiNan.API/appsettings.Development.json

14
SiNan.API/appsettings.json

@ -0,0 +1,14 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
//"DB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy;charset=utf8;sslmode=none;"
"BBWYCDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=bbwy_test;charset=utf8;sslmode=none;",
"MDSDB": "data source=rm-bp1508okrh23710yfao.mysql.rds.aliyuncs.com;port=3306;user id=qyroot;password=kaicn1132+-;initial catalog=mds;charset=utf8;sslmode=none;"
}
}

0
SiNan.API/SiNan.API/wwwroot/css/site.css → SiNan.API/wwwroot/css/site.css

0
SiNan.API/SiNan.API/wwwroot/favicon.ico → SiNan.API/wwwroot/favicon.ico

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

0
SiNan.API/SiNan.API/wwwroot/js/site.js → SiNan.API/wwwroot/js/site.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/LICENSE → SiNan.API/wwwroot/lib/bootstrap/LICENSE

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-grid.rtl.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-reboot.rtl.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap-utilities.rtl.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map → SiNan.API/wwwroot/lib/bootstrap/dist/css/bootstrap.rtl.min.css.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.esm.min.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map → SiNan.API/wwwroot/lib/bootstrap/dist/js/bootstrap.min.js.map

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt → SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js → SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js → SiNan.API/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation/LICENSE.md → SiNan.API/wwwroot/lib/jquery-validation/LICENSE.md

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.js → SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.min.js → SiNan.API/wwwroot/lib/jquery-validation/dist/additional-methods.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.js → SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js → SiNan.API/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery/LICENSE.txt → SiNan.API/wwwroot/lib/jquery/LICENSE.txt

0
SiNan.API/SiNan.API/wwwroot/lib/jquery/dist/jquery.js → SiNan.API/wwwroot/lib/jquery/dist/jquery.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery/dist/jquery.min.js → SiNan.API/wwwroot/lib/jquery/dist/jquery.min.js

0
SiNan.API/SiNan.API/wwwroot/lib/jquery/dist/jquery.min.map → SiNan.API/wwwroot/lib/jquery/dist/jquery.min.map

11
SiNan.Business/FreeSqlMultiDBManager.cs

@ -0,0 +1,11 @@
namespace SiNan.Business
{
public class FreeSqlMultiDBManager
{
//public IFreeSql BBWYBfsql { get; set; }
public IFreeSql MDSfsql { get; set; }
public IFreeSql BBWYCfsql { get; set; }
}
}

24
SiNan.Business/SiNan.Business.csproj

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="FreeSql" Version="3.2.801" />
<PackageReference Include="FreeSql.Provider.MySql" Version="3.2.801" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SiNan.Common\SiNan.Common.csproj" />
<ProjectReference Include="..\SiNan.Model\SiNan.Model.csproj" />
</ItemGroup>
</Project>

20
SiNan.Business/TaskSchedulerManager.cs

@ -0,0 +1,20 @@
using System.Threading.Tasks.Schedulers;
namespace SiNan.Business
{
public class TaskSchedulerManager
{
public LimitedConcurrencyLevelTaskScheduler SyncProductTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler SyncOrderTaskScheduler { get; private set; }
public LimitedConcurrencyLevelTaskScheduler PurchaseOrderCallbackTaskScheduler { get; private set; }
public TaskSchedulerManager()
{
SyncOrderTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
PurchaseOrderCallbackTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
SyncProductTaskScheduler = new LimitedConcurrencyLevelTaskScheduler(10);
}
}
}

29
SiNan.Common/Extensions/ConverterExtensions.cs

@ -0,0 +1,29 @@
namespace SiNan.Common.Extensions
{
public static class ConverterExtensions
{
public static long? ToInt64(this object? o)
{
try
{
return Convert.ToInt64(o);
}
catch
{
return null;
}
}
public static int? ToInt32(this object? o)
{
try
{
return Convert.ToInt32(o);
}
catch
{
return null;
}
}
}
}

12
SiNan.Common/Extensions/CopyExtensions.cs

@ -0,0 +1,12 @@
using Newtonsoft.Json;
namespace SiNan.Common.Extensions
{
public static class CopyExtensions
{
public static T Copy<T>(this T p)
{
return JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(p));
}
}
}

99
SiNan.Common/Extensions/DateTimeExtension.cs

@ -0,0 +1,99 @@
using System.Runtime.InteropServices;
namespace SiNan.Common.Extensions
{
public static class DateTimeExtension
{
private static readonly DateTime beginTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
/// <summary>
/// 时间戳转时间
/// </summary>
/// <param name="timeStamp">时间</param>
/// <param name="len13">true:13, false:10</param>
/// <returns></returns>
[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);
}
/// <summary>
/// 时间转时间戳
/// </summary>
/// <param name="time">时间</param>
/// <param name="len13">true:13, false:10</param>
/// <returns></returns>
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);
}
/// <summary>
/// 将秒数转换为时分秒形式
/// </summary>
/// <param name="second"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 修改系统时间(需要管理员权限)
/// </summary>
/// <param name="date"></param>
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
}
}

82
SiNan.Common/Extensions/EncryptionExtension.cs

@ -0,0 +1,82 @@
using System.Security.Cryptography;
using System.Text;
namespace SiNan.Common.Extensions
{
public static class EncryptionExtension
{
public static string Md5Encrypt(this string originStr)
{
using (var md5 = MD5.Create())
{
return string.Join(string.Empty, md5.ComputeHash(Encoding.UTF8.GetBytes(originStr)).Select(x => x.ToString("x2")));
}
}
//AES加密 传入,要加密的串和, 解密key
public static string AESEncrypt(this string input)
{
var key = "dataplatform2019";
var ivStr = "1012132405963708";
var encryptKey = Encoding.UTF8.GetBytes(key);
var iv = Encoding.UTF8.GetBytes(ivStr); //偏移量,最小为16
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(encryptKey, iv))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor,
CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(input);
}
var decryptedContent = msEncrypt.ToArray();
return Convert.ToBase64String(decryptedContent);
}
}
}
}
public static string AESDecrypt(this string cipherText)
{
var fullCipher = Convert.FromBase64String(cipherText);
var ivStr = "1012132405963708";
var key = "dataplatform2019";
var iv = Encoding.UTF8.GetBytes(ivStr);
var decryptKey = Encoding.UTF8.GetBytes(key);
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(decryptKey, iv))
{
string result;
using (var msDecrypt = new MemoryStream(fullCipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
public static string Base64Encrypt(this string originStr)
{
return Convert.ToBase64String(Encoding.UTF8.GetBytes(originStr));
}
}
}

59
SiNan.Common/Extensions/MapperExtension.cs

@ -0,0 +1,59 @@
using AutoMapper;
using Microsoft.Extensions.DependencyInjection;
namespace SiNan.Common.Extensions
{
public static class MapperExtension
{
private static IMapper _mapper;
/// <summary>
/// 注册对象映射器
/// </summary>
/// <param name="services"></param>
/// <param name="profile"></param>
/// <returns></returns>
public static IServiceCollection AddMapper(this IServiceCollection services, Profile profile)
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile(profile);
});
_mapper = config.CreateMapper();
return services;
}
/// <summary>
/// 设置对象映射执行者
/// </summary>
/// <param name="mapper">映射执行者</param>
public static void SetMapper(IMapper mapper)
{
_mapper = mapper;
}
/// <summary>
/// 将对象映射为指定类型
/// </summary>
/// <typeparam name="TTarget">要映射的目标类型</typeparam>
/// <param name="source">源对象</param>
/// <returns>目标类型的对象</returns>
public static TTarget Map<TTarget>(this object source)
{
return _mapper.Map<TTarget>(source);
}
/// <summary>
/// 使用源类型的对象更新目标类型的对象
/// </summary>
/// <typeparam name="TSource">源类型</typeparam>
/// <typeparam name="TTarget">目标类型</typeparam>
/// <param name="source">源对象</param>
/// <param name="target">待更新的目标对象</param>
/// <returns>更新后的目标类型对象</returns>
public static TTarget Map<TSource, TTarget>(this TSource source, TTarget target)
{
return _mapper.Map(source, target);
}
}
}

34
SiNan.Common/Extensions/StartupExtension.cs

@ -0,0 +1,34 @@
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
namespace SiNan.Common.Extensions
{
public static class StartupExtension
{
public static void BatchRegisterServices(this IServiceCollection serviceCollection, Assembly[] assemblys, Type baseType, ServiceLifetime serviceLifetime = ServiceLifetime.Singleton, bool registerSelf = true)
{
List<Type> typeList = new List<Type>(); //所有符合注册条件的类集合
foreach (var assembly in assemblys)
{
var types = assembly.GetTypes().Where(t => t.IsClass && !t.IsSealed && !t.IsAbstract && baseType.IsAssignableFrom(t));
typeList.AddRange(types);
}
if (typeList.Count() == 0)
return;
foreach (var instanceType in typeList)
{
if (registerSelf)
{
serviceCollection.Add(new ServiceDescriptor(instanceType, instanceType, serviceLifetime));
continue;
}
var interfaces = instanceType.GetInterfaces();
if (interfaces != null && interfaces.Length > 0)
foreach (var interfaceType in interfaces)
serviceCollection.Add(new ServiceDescriptor(interfaceType, instanceType, serviceLifetime));
}
}
}
}

452
SiNan.Common/Http/HttpDownloader.cs

@ -0,0 +1,452 @@
using System.Net;
namespace SiNan.Common.Http
{
/// <summary>
/// Http下载器
/// </summary>
public class HttpDownloader
{
private IHttpClientFactory httpClientFactory;
public HttpDownloader(IHttpClientFactory httpClientFactory, DownloadSetting dwSetting = null)
{
this.httpClientFactory = httpClientFactory;
complateArgs = new DownloadCompletedEventArgs();
changeArgs = new DownloadProgressChangedEventArgs();
if (dwSetting == null)
dwSetting = new DownloadSetting();
downloadSetting = dwSetting;
buffer = new byte[downloadSetting.BufferSize];
}
~HttpDownloader()
{
this.buffer = null;
this.downloadSetting = null;
this.complateArgs.Error = null;
this.complateArgs = null;
this.changeArgs = null;
}
#region Property
/// <summary>
/// 下载进度变化参数
/// </summary>
private DownloadProgressChangedEventArgs changeArgs;
/// <summary>
/// 下载完成参数
/// </summary>
private DownloadCompletedEventArgs complateArgs;
/// <summary>
/// 下载参数配置类
/// </summary>
private DownloadSetting downloadSetting;
/// <summary>
/// 下载缓冲区
/// </summary>
private byte[] buffer;
#endregion
#region Delegate
public delegate void DownloadProgressChangedEventHandler(object sender, DownloadProgressChangedEventArgs e);
public delegate void DownloadCompletedEventHandler(object sender, DownloadCompletedEventArgs e);
public delegate void ReDownloadEventHandler(object sender, DownloadCompletedEventArgs e);
#endregion
#region Event
/// <summary>
/// 下载进度变化事件
/// </summary>
public event DownloadProgressChangedEventHandler OnDownloadProgressChanged;
/// <summary>
/// 下载完成事件
/// </summary>
public event DownloadCompletedEventHandler OnDownloadComplated;
/// <summary>
/// 自动重下事件
/// </summary>
public event ReDownloadEventHandler OnReDownload;
#endregion
#region Method
/// <summary>
/// 设置下载参数
/// </summary>
/// <param name="dwSetting"></param>
public void SetDownloadSetting(DownloadSetting dwSetting)
{
if (dwSetting != null)
downloadSetting = dwSetting;
}
private void DoProcessChangedEvent(DownloadProgressChangedEventArgs args)
{
OnDownloadProgressChanged?.Invoke(this, args);
}
private void DoCompletedEvent(DownloadCompletedEventArgs args)
{
OnDownloadComplated?.Invoke(this, args);
}
private void DoReDownloadEvent(DownloadCompletedEventArgs args)
{
OnReDownload?.Invoke(this, args);
}
private void ArgsInit()
{
changeArgs.Cancel = false;
complateArgs.Cancelled = false;
complateArgs.Error = null;
}
/// <summary>
/// 获取文件总大小
/// </summary>
/// <param name="url"></param>
/// <returns></returns>
public long GetTotalLength(string url)
{
long length = 0;
try
{
using (var httpClient = httpClientFactory.CreateClient())
{
var requestMessage = new HttpRequestMessage(HttpMethod.Head, url);
var httpResponse = httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead).Result;
if (httpResponse.IsSuccessStatusCode)
length = httpResponse.Content.Headers.ContentLength ?? 0;
}
//var req = (HttpWebRequest)WebRequest.Create(new Uri(url));
//req.Method = "HEAD";
//req.Timeout = 5000;
//var res = (HttpWebResponse)req.GetResponse();
//if (res.StatusCode == HttpStatusCode.OK)
//{
// length = res.ContentLength;
//}
//res.Close();
return length;
}
catch (WebException wex)
{
throw wex;
}
}
private bool DownloadFile(string url, string savePath, long startPosition, long totalSize)
{
long currentReadSize = 0; //当前已经读取的字节数
if (startPosition != 0)
currentReadSize = startPosition;
using (var httpClient = httpClientFactory.CreateClient())
{
try
{
httpClient.Timeout = new TimeSpan(0, 0, 20);
if (currentReadSize != 0 && currentReadSize == totalSize)
{
changeArgs.CurrentSize = changeArgs.TotalSize = totalSize;
return true;
}
if (currentReadSize != 0)
{
try
{
httpClient.DefaultRequestHeaders.Range = new System.Net.Http.Headers.RangeHeaderValue(currentReadSize, totalSize);
}
catch (Exception ex)
{
//http 416
currentReadSize = 0;
}
}
using (var response = httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).Result)
{
using (var responseStream = response.Content.ReadAsStreamAsync().Result)
{
changeArgs.TotalSize = totalSize;
using (var fs = new FileStream(savePath, currentReadSize == 0 ? FileMode.Create : FileMode.Append, FileAccess.Write))
{
//判断服务器是否支持断点续下
if (currentReadSize != 0 &&
response.StatusCode == HttpStatusCode.PartialContent &&
response.Content.Headers.ContentLength != totalSize)
fs.Seek(startPosition, SeekOrigin.Begin); //支持,从本地文件流末尾进行写入
else
currentReadSize = 0; //不支持,从本地文件流开始进行写入
if (buffer.Length != downloadSetting.BufferSize)
buffer = new byte[downloadSetting.BufferSize];
int size = responseStream.Read(buffer, 0, buffer.Length);
while (size != 0)
{
fs.Write(buffer, 0, size);
if (buffer.Length != downloadSetting.BufferSize)
buffer = new byte[downloadSetting.BufferSize];
size = responseStream.Read(buffer, 0, buffer.Length);
currentReadSize += size; //累计下载大小
//执行下载进度变化事件
changeArgs.CurrentSize = currentReadSize;
DoProcessChangedEvent(changeArgs);
//判断挂起状态
if (changeArgs.Cancel)
return true;
}
//执行下载进度变化事件
changeArgs.CurrentSize = changeArgs.TotalSize;
DoProcessChangedEvent(changeArgs);
fs.Flush(true);
}
//验证远程服务器文件字节数和本地文件字节数是否一致
long localFileSize = 0;
try
{
localFileSize = new FileInfo(savePath).Length;
}
catch (Exception ex)
{
localFileSize = changeArgs.CurrentSize;
}
if (totalSize != localFileSize)
{
complateArgs.Error = new Exception(string.Format("远程文件字节:[{0}]与本地文件字节:[{1}]不一致", totalSize, localFileSize));
}
}
}
}
catch (IOException ex)
{
complateArgs.Error = ex;
}
catch (WebException ex)
{
complateArgs.Error = ex;
}
catch (Exception ex)
{
complateArgs.Error = ex;
}
}
return complateArgs.Error == null;
}
public bool DownloadFile(string url, string saveFolderPath, string saveFileName, long? totalSize)
{
ArgsInit();
var result = false;
//验证文件夹
try
{
if (!Directory.Exists(saveFolderPath))
Directory.CreateDirectory(saveFolderPath);
}
catch (Exception ex)
{
complateArgs.Error = ex;
DoCompletedEvent(complateArgs);
return result;
}
if (totalSize == null || totalSize.Value == 0)
{
try
{
totalSize = GetTotalLength(url);
}
catch (Exception ex)
{
Console.WriteLine("获取远程服务器字节数失败 {0}", ex.Message);
complateArgs.Error = ex;
DoCompletedEvent(complateArgs);
return result;
}
}
string saveFilePath = Path.Combine(saveFolderPath, saveFileName);
long startPosition = 0;
for (var i = 1; i <= downloadSetting.TryCount; i++)
{
if (File.Exists(saveFilePath))
{
try
{
startPosition = new FileInfo(saveFilePath).Length;
}
catch
{
startPosition = 0;
}
}
result = DownloadFile(url, saveFilePath, startPosition, totalSize.Value);
if (result)
{
break;
}
else
{
if (i != downloadSetting.TryCount)
{
complateArgs.TryCount = i + 1;
DoReDownloadEvent(complateArgs);
Thread.Sleep(downloadSetting.SleepTime);
if (complateArgs.Cancelled)
break;
ArgsInit();
}
}
if (complateArgs.Cancelled)
break;
}
DoCompletedEvent(complateArgs);
return result;
}
public byte[] DwonloadBytes(string url)
{
ArgsInit();
using (var httpClient = httpClientFactory.CreateClient())
{
return httpClient.GetByteArrayAsync(url).Result;
}
}
/// <summary>
/// 取消/暂停下载
/// </summary>
public void CancelDownload()
{
this.changeArgs.Cancel = true;
this.complateArgs.Cancelled = true;
}
#endregion
}
/// <summary>
/// 下载进度变化参数
/// </summary>
public class DownloadProgressChangedEventArgs
{
public DownloadProgressChangedEventArgs()
{
ProgressPercentage = 0.0;
Cancel = false;
}
/// <summary>
/// 下载进度百分比
/// </summary>
public double ProgressPercentage;
private long currentSize;
/// <summary>
/// 当前下载总大小
/// </summary>
public long CurrentSize
{
get { return currentSize; }
set
{
currentSize = value;
this.ProgressPercentage = Math.Round((CurrentSize * 1.0 / TotalSize) * 100, 2);
}
}
/// <summary>
/// 文件总大小
/// </summary>
public long TotalSize;
/// <summary>
/// 取消状态
/// </summary>
public bool Cancel;
}
/// <summary>
/// 下载完成参数
/// </summary>
public class DownloadCompletedEventArgs
{
public DownloadCompletedEventArgs()
{
Cancelled = false;
Error = null;
}
/// <summary>
/// 下载异常
/// </summary>
public Exception Error;
/// <summary>
/// 重试次数
/// </summary>
public int TryCount;
/// <summary>
/// 下载操作是否被取消 【取消则为true;默认false】
/// </summary>
public bool Cancelled;
}
public class DownloadSetting
{
public DownloadSetting()
{
this.BufferSize = 1024 * 1024 * 1;
this.TryCount = 5;
this.SleepTime = 5000;
}
/// <summary>
///
/// </summary>
/// <param name="bufferSize"></param>
/// <param name="tryCount"></param>
/// <param name="sleepTime">毫秒</param>
public DownloadSetting(int bufferSize, int tryCount, int sleepTime)
{
this.BufferSize = bufferSize;
this.TryCount = tryCount;
this.SleepTime = sleepTime;
}
/// <summary>
/// 下载缓冲区大小
/// </summary>
public int BufferSize;
/// <summary>
/// 重试次数
/// </summary>
public int TryCount;
/// <summary>
/// 自动重下休眠时间, 毫秒
/// </summary>
public int SleepTime;
}
}

117
SiNan.Common/Http/RestAPIService.cs

@ -0,0 +1,117 @@
using Newtonsoft.Json;
using SiNan.Common.Extensions;
using System.Net;
using System.Net.Http.Headers;
using System.Text;
namespace SiNan.Common.Http
{
public class RestApiService
{
public const string ContentType_Json = "application/json";
public const string ContentType_Form = "application/x-www-form-urlencoded";
public TimeSpan TimeOut { get; set; } = new TimeSpan(0, 0, 40);
private IHttpClientFactory httpClientFactory;
public RestApiService(IHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
/// <summary>
/// 发送请求
/// </summary>
/// <param name="apiHost"></param>
/// <param name="apiPath"></param>
/// <param name="param"></param>
/// <param name="requestHeaders"></param>
/// <param name="httpMethod"></param>
/// <param name="contentType"></param>
/// <param name="paramPosition"></param>
/// <param name="enableRandomTimeStamp"></param>
/// <param name="getResponseHeader"></param>
/// <param name="httpCompletionOption"></param>
/// <param name="httpClientName"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public RestApiResult SendRequest(string apiHost,
string apiPath,
object param,
IDictionary<string, string> requestHeaders,
HttpMethod httpMethod,
string contentType = ContentType_Json,
ParamPosition paramPosition = ParamPosition.Body,
bool enableRandomTimeStamp = false,
bool getResponseHeader = false,
HttpCompletionOption httpCompletionOption = HttpCompletionOption.ResponseContentRead,
string httpClientName = "",
int timeOutSeconds = 0)
{
//Get和Delete强制使用QueryString形式传参
if (httpMethod == HttpMethod.Get)
paramPosition = ParamPosition.Query;
//拼接Url
var url = $"{apiHost}{(apiHost.EndsWith("/") ? string.Empty : (string.IsNullOrEmpty(apiPath) ? string.Empty : "/"))}{(apiPath.StartsWith("/") ? apiPath.Substring(1) : apiPath)}";
var isCombineParam = false;
if (paramPosition == ParamPosition.Query && param != null)
{
url = $"{url}{(param.ToString().StartsWith("?") ? string.Empty : "?")}{param}";
isCombineParam = true;
}
//使用时间戳绕过CDN
if (enableRandomTimeStamp)
url = $"{url}{(isCombineParam ? "&" : "?")}t={DateTime.Now.DateTimeToStamp()}";
using (var httpClient = string.IsNullOrEmpty(httpClientName) ? httpClientFactory.CreateClient() : httpClientFactory.CreateClient(httpClientName))
{
if (timeOutSeconds == 0)
httpClient.Timeout = TimeOut;
else
httpClient.Timeout = TimeSpan.FromSeconds(timeOutSeconds);
using (var request = new HttpRequestMessage(httpMethod, url))
{
if (requestHeaders != null && requestHeaders.Count > 0)
foreach (var key in requestHeaders.Keys)
request.Headers.Add(key, requestHeaders[key]);
if (paramPosition == ParamPosition.Body && param != null)
request.Content = new StringContent(contentType == ContentType_Json ? JsonConvert.SerializeObject(param) : param.ToString(), Encoding.UTF8, contentType);
using (var response = httpClient.SendAsync(request, httpCompletionOption).Result)
{
return new RestApiResult()
{
StatusCode = response.StatusCode,
Content = httpCompletionOption == HttpCompletionOption.ResponseContentRead ? response.Content.ReadAsStringAsync().Result :
string.Empty,
Headers = getResponseHeader ? response.Headers : null
};
}
}
}
}
}
public class RestApiResult
{
public HttpStatusCode StatusCode { get; set; }
public string Content { get; set; }
public HttpResponseHeaders Headers { get; set; }
}
/// <summary>
/// 参数传递位置
/// </summary>
public enum ParamPosition
{
Query,
Body
}
}

34
SiNan.Common/Models/ApiResponse.cs

@ -0,0 +1,34 @@
using System;
namespace SiNan.Common.Models
{
public class ApiResponse<T>
{
public bool Success { get { return Code == 200; } }
/// <summary>
/// 接口调用状态
/// </summary>
public int Code { get; set; } = 200;
/// <summary>
/// 返回消息
/// </summary>
public string Msg { get; set; }
/// <summary>
/// 数据内容
/// </summary>
public T Data { get; set; }
public static ApiResponse<T> Error(int code, string msg)
{
return new ApiResponse<T>() { Code = code, Msg = msg };
}
}
public class ApiResponse : ApiResponse<object>
{
}
}

18
SiNan.Common/Models/BusinessException.cs

@ -0,0 +1,18 @@
namespace SiNan.Common.Models
{
/// <summary>
/// 业务异常
/// </summary>
public class BusinessException : Exception
{
public BusinessException(string message) : base(message)
{
}
/// <summary>
/// 错误代码
/// </summary>
public int Code { get; set; }
}
}

10
SiNan.Common/Models/IDenpendency.cs

@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace SiNan.Common.Models
{
public interface IDenpendency
{
}
}

18
SiNan.Common/SiNan.Common.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="12.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.5" />
</ItemGroup>
</Project>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save