贾荣国
3 years ago
51 changed files with 6410 additions and 104 deletions
@ -0,0 +1,39 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace TestHost.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<WeatherForecastController> _logger; |
|||
|
|||
public WeatherForecastController(ILogger<WeatherForecastController> logger) |
|||
{ |
|||
_logger = logger; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public IEnumerable<WeatherForecast> 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(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,26 @@ |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace TestHost |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static void Main(string[] args) |
|||
{ |
|||
CreateHostBuilder(args).Build().Run(); |
|||
} |
|||
|
|||
public static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}).UseAutofac(); |
|||
} |
|||
} |
@ -0,0 +1,31 @@ |
|||
{ |
|||
"$schema": "http://json.schemastore.org/launchsettings.json", |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:33955", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"launchUrl": "swagger", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"TestHost": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": "true", |
|||
"launchBrowser": true, |
|||
"launchUrl": "swagger", |
|||
"applicationUrl": "http://localhost:5000", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,29 @@ |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.OpenApi.Models; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace TestHost |
|||
{ |
|||
public class Startup |
|||
{ |
|||
|
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
services.AddApplication<TestModule>(); |
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) |
|||
{ |
|||
app.InitializeApplication(); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.3" /> |
|||
<PackageReference Include="Volo.Abp.Core" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.Http.Client" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.Swashbuckle" Version="4.4.2" /> |
|||
|
|||
</ItemGroup> |
|||
|
|||
|
|||
</Project> |
@ -0,0 +1,47 @@ |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.OpenApi.Models; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace TestHost |
|||
{ |
|||
public class TestModule : AbpModule |
|||
|
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var services = context.Services; |
|||
|
|||
services.AddControllers(); |
|||
services.AddSwaggerGen(c => |
|||
{ |
|||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "TestHost", Version = "v1" }); |
|||
}); |
|||
|
|||
} |
|||
|
|||
public override void OnApplicationInitialization(ApplicationInitializationContext context) |
|||
{ |
|||
var app = context.GetApplicationBuilder(); |
|||
var env = context.GetEnvironment(); |
|||
|
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
app.UseSwagger(); |
|||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TestHost v1")); |
|||
} |
|||
|
|||
app.UseRouting(); |
|||
|
|||
app.UseAuthorization(); |
|||
|
|||
app.UseEndpoints(endpoints => |
|||
{ |
|||
endpoints.MapControllers(); |
|||
}); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace TestHost |
|||
{ |
|||
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; } |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
}, |
|||
"AllowedHosts": "*" |
|||
} |
@ -1,111 +1,131 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Win_in.Sfs.Scp.WebApi.Domain.Shared; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
|
|||
public class PartCreateDto : EntityDto,ICanTrace |
|||
{ |
|||
/// <summary>
|
|||
/// 代码(Code)
|
|||
/// </summary>
|
|||
[XmlElement("code")] |
|||
[Display(Name = "代码")] |
|||
public string Code { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 名称(Name)
|
|||
/// </summary>
|
|||
[XmlElement("name")] |
|||
[Display(Name = "名称")] |
|||
public string Name { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 描述(Desc1)
|
|||
/// </summary>
|
|||
[XmlElement("desc1")] |
|||
[Display(Name = "描述")] |
|||
public string Desc1 { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 描述2(Desc2)
|
|||
/// </summary>
|
|||
[XmlElement("desc2")] |
|||
[Display(Name = "描述2")] |
|||
public string Desc2 { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 状态(Status)
|
|||
/// </summary>
|
|||
[XmlElement("status")] |
|||
[Display(Name = "状态")] |
|||
public string Status { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 制造件(Can make)
|
|||
/// </summary>
|
|||
[XmlElement("isMakePart")] |
|||
[Display(Name = "制造件")] |
|||
public bool IsMakePart { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 采购件(Can buy)
|
|||
/// </summary>
|
|||
[XmlElement("isBuyPart")] |
|||
[Display(Name = "采购件")] |
|||
public bool IsBuyPart { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 计量单位(Uom)
|
|||
/// </summary>
|
|||
[XmlElement("uom")] |
|||
[Display(Name = "计量单位")] |
|||
public string Uom { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// ABC类(ABC Class)
|
|||
/// </summary>
|
|||
[XmlElement("abcClass")] |
|||
[Display(Name = "ABC类")] |
|||
public string AbcClass { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 产品类(Product Line)
|
|||
/// </summary>
|
|||
[XmlElement("productLine")] |
|||
[Display(Name = "产品类")] |
|||
public string ProductLine { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 类型(Type)
|
|||
/// </summary>
|
|||
[XmlElement("type")] |
|||
[Display(Name = "类型")] |
|||
public string Type { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 种类(Catalog)
|
|||
/// </summary>
|
|||
[XmlElement("catalog")] |
|||
[Display(Name = "种类")] |
|||
public string Catalog { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 分组(Group)
|
|||
/// </summary>
|
|||
[XmlElement("group")] |
|||
[Display(Name = "分组")] |
|||
public string Group { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 版本(version)
|
|||
/// </summary>
|
|||
[XmlElement("version")] |
|||
[Display(Name = "版本")] |
|||
public string Version { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 地点(Site)
|
|||
/// </summary>
|
|||
[XmlElement("site")] |
|||
[Display(Name = "地点")] |
|||
public string Site { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 公司(Company)
|
|||
/// </summary>
|
|||
[XmlElement("company")] |
|||
[Display(Name = "公司")] |
|||
public string Company { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// 跟踪编号(Trace ID)
|
|||
/// </summary>
|
|||
[XmlElement("traceId")] |
|||
[Display(Name = "跟踪编号")] |
|||
public Guid TraceId { get; set; } |
|||
|
|||
} |
@ -0,0 +1,22 @@ |
|||
using FluentValidation; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi; |
|||
|
|||
public class CreatePurchaseOrderDetailValidator : AbstractValidator<PurchaseOrderDetailDTO> |
|||
{ |
|||
public CreatePurchaseOrderDetailValidator() |
|||
{ |
|||
RuleFor(q => q.PoNumber).NotEmpty().MaximumLength(64); |
|||
RuleFor(q => q.PoLine).NotEmpty().MaximumLength(64); |
|||
RuleFor(q => q.PartCode).NotEmpty().MaximumLength(64); |
|||
RuleFor(q => q.Uom).NotEmpty().MaximumLength(64); |
|||
RuleFor(q => q.OrderQty).NotEmpty(); |
|||
RuleFor(q => q.StdPackQty).NotEmpty(); |
|||
RuleFor(q => q.SupplierPackConvertRate); |
|||
RuleFor(q => q.IsConsignment).NotEmpty(); |
|||
RuleFor(q => q.LineStatus).NotEmpty(); |
|||
RuleFor(q => q.Remark).MaximumLength(4096); |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,11 @@ |
|||
namespace Win_in.Sfs.Scp.WebApi |
|||
{ |
|||
public class RouteConsts |
|||
{ |
|||
public const string Part = "api/scp/part"; |
|||
public const string PurchaseOrder = "api/scp/po"; |
|||
public const string Receipt = "api/scp/receipt"; |
|||
public const string Supplier = "api/scp/supplier"; |
|||
public const string UnplannedReceipt = "api/scp/unplanned-receipt"; |
|||
} |
|||
} |
@ -1,12 +1,14 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Runtime.Serialization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Domain.Shared |
|||
{ |
|||
public class EntityDetailDtoBase<TKey> : CreationAuditedEntityDto<TKey> |
|||
[Serializable, DataContract] |
|||
public class EntityDetailDtoBase :IEntityDto |
|||
{ |
|||
|
|||
|
|||
} |
|||
} |
@ -1,12 +1,31 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using System.Runtime.Serialization; |
|||
using System.Xml.Serialization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.Domain.Shared |
|||
{ |
|||
public class EntityDtoBase<TKey> : CreationAuditedEntityDto<TKey>, ICanTrace |
|||
[Serializable,DataContract] |
|||
public class EntityDtoBase<TKey> :IEntityDto<TKey>, ICanTrace |
|||
{ |
|||
[DataMember] |
|||
public TKey Id { get; set; } |
|||
|
|||
[DataMember] |
|||
public DateTime CreationTime { get; set; } |
|||
|
|||
[DataMember] |
|||
public Guid? CreatorId { get; set; } |
|||
|
|||
|
|||
|
|||
/// <summary>
|
|||
/// 跟踪编号(Trace ID)
|
|||
/// </summary>
|
|||
[DataMember] |
|||
[Display(Name = "跟踪编号")] |
|||
public Guid TraceId { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,83 @@ |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Net.Http.Headers; |
|||
using System.Security.Claims; |
|||
using System.Text; |
|||
using System.Text.Encodings.Web; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace ApiBasicAuth.Security |
|||
{ |
|||
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> |
|||
{ |
|||
private readonly BasicAuthenticationOptions _basicOptions; |
|||
|
|||
public BasicAuthenticationHandler( |
|||
IOptions<BasicAuthenticationOptions> basicOptions, |
|||
IOptionsMonitor<AuthenticationSchemeOptions> options, |
|||
ILoggerFactory logger, |
|||
UrlEncoder encoder, |
|||
ISystemClock clock) |
|||
: base(options, logger, encoder, clock) |
|||
{ |
|||
_basicOptions = basicOptions.Value; |
|||
} |
|||
|
|||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync() |
|||
{ |
|||
if (!Request.Headers.ContainsKey("Authorization")) |
|||
{ |
|||
Response.Headers.Add("WWW-Authenticate", @"Basic realm='Secure Area'"); |
|||
return AuthenticateResult.Fail("Missing Authorization Header"); |
|||
} |
|||
User user = null; |
|||
try |
|||
{ |
|||
var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]); |
|||
var credentialBytes = Convert.FromBase64String(authHeader.Parameter); |
|||
var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2); |
|||
var username = credentials[0]; |
|||
var password = credentials[1]; |
|||
if (username.Equals(_basicOptions.Username) && password.Equals(_basicOptions.Password)) |
|||
{ |
|||
user = new User { Id = 1, Username = "admin", Birthday = DateTime.Now }; |
|||
} |
|||
} |
|||
catch |
|||
{ |
|||
// Base64×Ö·û´®½âÂëʧ°Ü
|
|||
return AuthenticateResult.Fail("Invalid Authorization Header"); |
|||
} |
|||
|
|||
if (user == null) |
|||
return AuthenticateResult.Fail("Invalid Username or Password"); |
|||
|
|||
var claims = new[] { |
|||
new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()), |
|||
new Claim(ClaimTypes.Name, user.Username), |
|||
}; |
|||
var identity = new ClaimsIdentity(claims, Scheme.Name); |
|||
var principal = new ClaimsPrincipal(identity); |
|||
var ticket = new AuthenticationTicket(principal, Scheme.Name); |
|||
|
|||
return AuthenticateResult.Success(ticket); |
|||
} |
|||
} |
|||
|
|||
public class BasicAuthenticationOptions |
|||
{ |
|||
public string Username { get; set; } = "admin"; |
|||
public string Password { get; set; } = "3edc$RFV"; |
|||
} |
|||
|
|||
public class User |
|||
{ |
|||
public int Id { get; set; } |
|||
public string Username { get; set; } |
|||
public DateTime Birthday { get; set; } |
|||
} |
|||
} |
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.Diagnostics.Eventing.Reader; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Headers; |
|||
using System.Net.Http.Json; |
|||
using System.Net.Mime; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using RestSharp; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost.Controllers |
|||
{ |
|||
[Authorize] |
|||
[Route(RouteConsts.Part)] |
|||
|
|||
public class PartController : ControllerBase |
|||
{ |
|||
private readonly IHttpClientInvoker<PartCreateDto, PartDTO> _httpClientInvoker; |
|||
|
|||
public PartController(IHttpClientInvoker<PartCreateDto,PartDTO> httpClientInvoker) |
|||
{ |
|||
_httpClientInvoker = httpClientInvoker; |
|||
} |
|||
/// <summary>
|
|||
/// 新增零件(Add part)
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost] |
|||
[Route("")] |
|||
[Consumes(MediaTypeNames.Application.Xml)] |
|||
[Produces(MediaTypeNames.Application.Xml)] |
|||
public virtual async Task<ActionResult<PartDTO>> CreateAsync([FromBody]PartCreateDto input) |
|||
{ |
|||
|
|||
var dto = await _httpClientInvoker.InvokeAsync(input, RouteConsts.Part); |
|||
|
|||
return Ok(dto); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
using System.Net.Mime; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost.Controllers |
|||
{ |
|||
[Route(RouteConsts.PurchaseOrder)] |
|||
|
|||
public class PurchaseOrderController : ControllerBase |
|||
{ |
|||
private readonly IHttpClientInvoker<PurchaseOrderCreateDTO, PurchaseOrderDTO> _httpClientInvoker; |
|||
|
|||
public PurchaseOrderController(IHttpClientInvoker<PurchaseOrderCreateDTO, PurchaseOrderDTO> httpClientInvoker) |
|||
{ |
|||
_httpClientInvoker = httpClientInvoker; |
|||
} |
|||
/// <summary>
|
|||
/// 新增采购订单(Add purchase order)
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost] |
|||
[Route("")] |
|||
[Consumes(MediaTypeNames.Application.Xml)] |
|||
[Produces(MediaTypeNames.Application.Xml)] |
|||
public virtual async Task<ActionResult<PurchaseOrderDTO>> CreateAsync([FromBody] PurchaseOrderCreateDTO input) |
|||
{ |
|||
|
|||
var dto = await _httpClientInvoker.InvokeAsync(input, RouteConsts.PurchaseOrder); |
|||
|
|||
return Ok(dto); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
using System.Net.Mime; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost.Controllers |
|||
{ |
|||
[Route(RouteConsts.Receipt)] |
|||
|
|||
public class ReceiptController : ControllerBase |
|||
{ |
|||
private readonly IHttpClientInvoker<ReceiptCreateDTO, ReceiptDTO> _httpClientInvoker; |
|||
|
|||
public ReceiptController(IHttpClientInvoker<ReceiptCreateDTO, ReceiptDTO> httpClientInvoker) |
|||
{ |
|||
_httpClientInvoker = httpClientInvoker; |
|||
} |
|||
/// <summary>
|
|||
/// 新增收货/退货单(Add receipt/return receipt)
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost] |
|||
[Route("")] |
|||
[Consumes(MediaTypeNames.Application.Xml)] |
|||
[Produces(MediaTypeNames.Application.Xml)] |
|||
public virtual async Task<ActionResult<ReceiptDTO>> CreateAsync([FromBody] ReceiptCreateDTO input) |
|||
{ |
|||
|
|||
var dto = await _httpClientInvoker.InvokeAsync(input, RouteConsts.Receipt); |
|||
|
|||
return Ok(dto); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
using System.Net.Mime; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost.Controllers |
|||
{ |
|||
[Route(RouteConsts.Supplier)] |
|||
|
|||
public class SupplierController : ControllerBase |
|||
{ |
|||
private readonly IHttpClientInvoker<SupplierCreateDTO, SupplierDTO> _httpClientInvoker; |
|||
|
|||
public SupplierController(IHttpClientInvoker<SupplierCreateDTO, SupplierDTO> httpClientInvoker) |
|||
{ |
|||
_httpClientInvoker = httpClientInvoker; |
|||
} |
|||
/// <summary>
|
|||
/// 新增供应商(Add supplier)
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost] |
|||
[Route("")] |
|||
[Consumes(MediaTypeNames.Application.Xml)] |
|||
[Produces(MediaTypeNames.Application.Xml)] |
|||
public virtual async Task<ActionResult<SupplierDTO>> CreateAsync([FromBody] SupplierCreateDTO input) |
|||
{ |
|||
|
|||
var dto = await _httpClientInvoker.InvokeAsync(input, RouteConsts.Supplier); |
|||
|
|||
return Ok(dto); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
using System.Net.Mime; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost.Controllers |
|||
{ |
|||
[Route(RouteConsts.UnplannedReceipt)] |
|||
public class UnplannedReceiptController : ControllerBase |
|||
{ |
|||
private readonly IHttpClientInvoker<UnplannedReceiptCreateDTO, UnplannedReceiptDTO> _httpClientInvoker; |
|||
|
|||
public UnplannedReceiptController(IHttpClientInvoker<UnplannedReceiptCreateDTO, UnplannedReceiptDTO> httpClientInvoker) |
|||
{ |
|||
_httpClientInvoker = httpClientInvoker; |
|||
} |
|||
/// <summary>
|
|||
/// 新增计划外入库单(Add unplanned receipt)
|
|||
/// </summary>
|
|||
/// <returns></returns>
|
|||
[HttpPost] |
|||
[Route("")] |
|||
[Consumes(MediaTypeNames.Application.Xml)] |
|||
[Produces(MediaTypeNames.Application.Xml)] |
|||
public virtual async Task<ActionResult<UnplannedReceiptDTO>> CreateAsync([FromBody] UnplannedReceiptCreateDTO input) |
|||
{ |
|||
|
|||
var dto = await _httpClientInvoker.InvokeAsync(input, RouteConsts.UnplannedReceipt); |
|||
|
|||
return Ok(dto); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
using System; |
|||
using System.Net.Http; |
|||
using System.Net.Http.Headers; |
|||
using System.Net.Http.Json; |
|||
using System.Runtime.Serialization; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Options; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost |
|||
{ |
|||
|
|||
public class HttpClientInvoker<TInput, TOutput> : IHttpClientInvoker<TInput, TOutput> |
|||
{ |
|||
private readonly IConfiguration _configuration; |
|||
|
|||
public HttpClientInvoker(IConfiguration configuration) |
|||
{ |
|||
_configuration = configuration; |
|||
} |
|||
|
|||
public async Task<TOutput> InvokeAsync(TInput input,string routeString) |
|||
{ |
|||
var baseUrl = _configuration["RemoteServices:Default:BaseUrl"]; |
|||
var client = new HttpClient(); |
|||
client.BaseAddress = new Uri(baseUrl); |
|||
client.DefaultRequestHeaders.Accept.Clear(); |
|||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); |
|||
var response = await client.PostAsJsonAsync(routeString, input); |
|||
response.EnsureSuccessStatusCode(); |
|||
|
|||
var dto = await response.Content.ReadFromJsonAsync<TOutput>(); |
|||
return dto; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,10 @@ |
|||
using System.Runtime.Serialization; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost |
|||
{ |
|||
public interface IHttpClientInvoker<TInput,TOutput> |
|||
{ |
|||
Task<TOutput> InvokeAsync(TInput input,string routeString); |
|||
} |
|||
} |
File diff suppressed because it is too large
@ -0,0 +1,59 @@ |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Microsoft.Extensions.Hosting; |
|||
using System; |
|||
using Serilog; |
|||
using Serilog.Events; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost |
|||
{ |
|||
public class Program |
|||
{ |
|||
public static int Main(string[] args) |
|||
{ |
|||
InitLogger(); |
|||
|
|||
try |
|||
{ |
|||
Log.Information("Starting Win_in.Sfs.Scp.WebApi.Xml.Host."); |
|||
CreateHostBuilder(args).Build().Run(); |
|||
return 0; |
|||
} |
|||
catch (Exception ex) |
|||
{ |
|||
Log.Fatal(ex, "Host terminated unexpectedly!"); |
|||
return 1; |
|||
} |
|||
finally |
|||
{ |
|||
Log.CloseAndFlush(); |
|||
} |
|||
} |
|||
|
|||
private static void InitLogger() |
|||
{ |
|||
Log.Logger = new LoggerConfiguration() |
|||
#if DEBUG
|
|||
.MinimumLevel.Debug() |
|||
#else
|
|||
.MinimumLevel.Information() |
|||
#endif
|
|||
.MinimumLevel.Override("Microsoft", LogEventLevel.Information) |
|||
.MinimumLevel.Override("Microsoft.EntityFrameworkCore", LogEventLevel.Warning) |
|||
.Enrich.FromLogContext() |
|||
.WriteTo.Async(c => c.File("Logs/logs.txt")) |
|||
#if DEBUG
|
|||
.WriteTo.Async(c => c.Console()) |
|||
#endif
|
|||
.CreateLogger(); |
|||
} |
|||
|
|||
internal static IHostBuilder CreateHostBuilder(string[] args) => |
|||
Host.CreateDefaultBuilder(args) |
|||
.ConfigureWebHostDefaults(webBuilder => |
|||
{ |
|||
webBuilder.UseStartup<Startup>(); |
|||
}) |
|||
.UseSerilog(); |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
{ |
|||
|
|||
"profiles": { |
|||
"Win_in.Sfs.Scp.WebApi.Xml.Host": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": "true", |
|||
"launchBrowser": true, |
|||
"launchUrl": "swagger", |
|||
"applicationUrl": "https://localhost:9977", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,75 @@ |
|||
using ApiBasicAuth.Security; |
|||
using Microsoft.AspNetCore.Authentication; |
|||
using Microsoft.AspNetCore.Builder; |
|||
using Microsoft.AspNetCore.Hosting; |
|||
using Microsoft.AspNetCore.Mvc.ModelBinding; |
|||
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.Hosting; |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.OpenApi.Models; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost |
|||
{ |
|||
public class Startup |
|||
{ |
|||
public void ConfigureServices(IServiceCollection services) |
|||
{ |
|||
// services.AddControllers()
|
|||
// .AddXmlDataContractSerializerFormatters();
|
|||
|
|||
var configuration = services.GetConfiguration(); |
|||
|
|||
services.AddControllers() |
|||
.AddMvcOptions(options => |
|||
{ |
|||
// options.ModelMetadataDetailsProviders.Add(
|
|||
// new ExcludeBindingMetadataProvider(typeof(System.Version)));
|
|||
// options.ModelMetadataDetailsProviders.Add(
|
|||
// new SuppressChildValidationMetadataProvider(typeof(System.Guid)));
|
|||
options.InputFormatters.Insert(0, new XDocumentInputFormatter()); |
|||
// options.OutputFormatters.Insert(0,new XDocumentOutputFormatter());
|
|||
}) |
|||
.AddXmlDataContractSerializerFormatters() |
|||
.AddXmlSerializerFormatters(); |
|||
|
|||
|
|||
// services.AddControllers();
|
|||
services.AddSwaggerGen(c => |
|||
{ |
|||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Win_in.Sfs.Scp.WebApi.Xml.Host", Version = "v1" }); |
|||
}); |
|||
|
|||
services.AddAuthentication("BasicAuthentication") |
|||
.AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null); |
|||
|
|||
services.Configure<BasicAuthenticationOptions>(configuration.GetSection("BasicAuthentication")); |
|||
|
|||
services.AddSingleton(typeof(IHttpClientInvoker<,>),typeof(HttpClientInvoker<,>)); |
|||
|
|||
|
|||
} |
|||
|
|||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) |
|||
{ |
|||
if (env.IsDevelopment()) |
|||
{ |
|||
app.UseDeveloperExceptionPage(); |
|||
} |
|||
|
|||
app.UseSwagger(); |
|||
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "Win_in.Sfs.Scp.WebApi.Xml.Host v1")); |
|||
|
|||
app.UseRouting(); |
|||
|
|||
app.UseAuthentication(); |
|||
app.UseAuthorization(); |
|||
|
|||
|
|||
app.UseEndpoints(endpoints => |
|||
{ |
|||
endpoints.MapControllers(); |
|||
}); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,27 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace>Win_in.Sfs.Scp.WebApi.XmlHost</RootNamespace> |
|||
|
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.3" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> |
|||
<PackageReference Include="Volo.Abp.Autofac" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" Version="4.4.2" /> |
|||
<PackageReference Include="Volo.Abp.Swashbuckle" Version="4.4.2" /> |
|||
</ItemGroup> |
|||
|
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.Application.Contracts\Win_in.Sfs.Scp.WebApi.Application.Contracts.csproj" /> |
|||
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.HttpApi.Client\Win_in.Sfs.Scp.WebApi.HttpApi.Client.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,21 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace>Win_in.Sfs.Scp.WebApi.XmlHost</RootNamespace> |
|||
|
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Formatters.Xml" Version="2.2.0" /> |
|||
<PackageReference Include="RestSharp" Version="107.0.3" /> |
|||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.1.3" /> |
|||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" /> |
|||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Win_in.Sfs.Scp.WebApi.Application.Contracts\Win_in.Sfs.Scp.WebApi.Application.Contracts.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
@ -0,0 +1,41 @@ |
|||
using System; |
|||
using System.IO; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using System.Xml; |
|||
using System.Xml.Linq; |
|||
using System.Xml.Serialization; |
|||
using Microsoft.AspNetCore.Mvc.ApiExplorer; |
|||
using Microsoft.AspNetCore.Mvc.Formatters; |
|||
|
|||
namespace Win_in.Sfs.Scp.WebApi.XmlHost |
|||
{ |
|||
public class XDocumentInputFormatter : InputFormatter, IInputFormatter, IApiRequestFormatMetadataProvider |
|||
{ |
|||
private Type currentType { get; set; } |
|||
public XDocumentInputFormatter() |
|||
{ |
|||
SupportedMediaTypes.Add("application/xml"); |
|||
} |
|||
|
|||
protected override bool CanReadType(Type type) |
|||
{ |
|||
currentType = type; |
|||
if (type.IsAssignableFrom(typeof(XDocument))) return true; |
|||
return base.CanReadType(type); |
|||
} |
|||
|
|||
|
|||
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context) |
|||
{ |
|||
// Use StreamReader to convert any encoding to UTF-16 (default C# and sql Server).
|
|||
using var streamReader = new StreamReader(context.HttpContext.Request.Body); |
|||
var xmlDoc = await XDocument.LoadAsync(streamReader, LoadOptions.None, CancellationToken.None); |
|||
var model = new XmlSerializer(currentType).Deserialize(xmlDoc.CreateReader()); |
|||
return await InputFormatterResult.SuccessAsync(model); |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
@ -0,0 +1,9 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft": "Warning", |
|||
"Microsoft.Hosting.Lifetime": "Information" |
|||
} |
|||
}, |
|||
"AllowedHosts": "*", |
|||
|
|||
"RemoteServices": { |
|||
"Default": { |
|||
"BaseUrl": "https://scp.iacchina.net:9988/" |
|||
} |
|||
}, |
|||
"BasicAuthentication": { |
|||
"Username": "admin", |
|||
"Password": "admin" |
|||
} |
|||
} |
Loading…
Reference in new issue