贾荣国
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; |
||||
using System.ComponentModel.DataAnnotations; |
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Xml.Serialization; |
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
using Win_in.Sfs.Scp.WebApi.Domain.Shared; |
using Win_in.Sfs.Scp.WebApi.Domain.Shared; |
||||
|
|
||||
namespace Win_in.Sfs.Scp.WebApi; |
namespace Win_in.Sfs.Scp.WebApi; |
||||
|
|
||||
|
|
||||
public class PartCreateDto : EntityDto,ICanTrace |
public class PartCreateDto : EntityDto,ICanTrace |
||||
{ |
{ |
||||
/// <summary>
|
/// <summary>
|
||||
/// 代码(Code)
|
/// 代码(Code)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("code")] |
||||
[Display(Name = "代码")] |
[Display(Name = "代码")] |
||||
public string Code { get; set; } |
public string Code { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 名称(Name)
|
/// 名称(Name)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("name")] |
||||
[Display(Name = "名称")] |
[Display(Name = "名称")] |
||||
public string Name { get; set; } |
public string Name { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 描述(Desc1)
|
/// 描述(Desc1)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("desc1")] |
||||
[Display(Name = "描述")] |
[Display(Name = "描述")] |
||||
public string Desc1 { get; set; } |
public string Desc1 { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 描述2(Desc2)
|
/// 描述2(Desc2)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("desc2")] |
||||
[Display(Name = "描述2")] |
[Display(Name = "描述2")] |
||||
public string Desc2 { get; set; } |
public string Desc2 { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 状态(Status)
|
/// 状态(Status)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("status")] |
||||
[Display(Name = "状态")] |
[Display(Name = "状态")] |
||||
public string Status { get; set; } |
public string Status { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 制造件(Can make)
|
/// 制造件(Can make)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("isMakePart")] |
||||
[Display(Name = "制造件")] |
[Display(Name = "制造件")] |
||||
public bool IsMakePart { get; set; } |
public bool IsMakePart { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 采购件(Can buy)
|
/// 采购件(Can buy)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("isBuyPart")] |
||||
[Display(Name = "采购件")] |
[Display(Name = "采购件")] |
||||
public bool IsBuyPart { get; set; } |
public bool IsBuyPart { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 计量单位(Uom)
|
/// 计量单位(Uom)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("uom")] |
||||
[Display(Name = "计量单位")] |
[Display(Name = "计量单位")] |
||||
public string Uom { get; set; } |
public string Uom { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// ABC类(ABC Class)
|
/// ABC类(ABC Class)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("abcClass")] |
||||
[Display(Name = "ABC类")] |
[Display(Name = "ABC类")] |
||||
public string AbcClass { get; set; } |
public string AbcClass { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 产品类(Product Line)
|
/// 产品类(Product Line)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("productLine")] |
||||
[Display(Name = "产品类")] |
[Display(Name = "产品类")] |
||||
public string ProductLine { get; set; } |
public string ProductLine { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 类型(Type)
|
/// 类型(Type)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("type")] |
||||
[Display(Name = "类型")] |
[Display(Name = "类型")] |
||||
public string Type { get; set; } |
public string Type { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 种类(Catalog)
|
/// 种类(Catalog)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("catalog")] |
||||
[Display(Name = "种类")] |
[Display(Name = "种类")] |
||||
public string Catalog { get; set; } |
public string Catalog { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 分组(Group)
|
/// 分组(Group)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("group")] |
||||
[Display(Name = "分组")] |
[Display(Name = "分组")] |
||||
public string Group { get; set; } |
public string Group { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 版本(version)
|
/// 版本(version)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("version")] |
||||
[Display(Name = "版本")] |
[Display(Name = "版本")] |
||||
public string Version { get; set; } |
public string Version { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 地点(Site)
|
/// 地点(Site)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("site")] |
||||
[Display(Name = "地点")] |
[Display(Name = "地点")] |
||||
public string Site { get; set; } |
public string Site { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 公司(Company)
|
/// 公司(Company)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("company")] |
||||
[Display(Name = "公司")] |
[Display(Name = "公司")] |
||||
public string Company { get; set; } |
public string Company { get; set; } |
||||
|
|
||||
/// <summary>
|
/// <summary>
|
||||
/// 跟踪编号(Trace ID)
|
/// 跟踪编号(Trace ID)
|
||||
/// </summary>
|
/// </summary>
|
||||
|
[XmlElement("traceId")] |
||||
[Display(Name = "跟踪编号")] |
[Display(Name = "跟踪编号")] |
||||
public Guid TraceId { get; set; } |
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,11 +1,13 @@ |
|||||
using System; |
using System; |
||||
using System.ComponentModel.DataAnnotations; |
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Runtime.Serialization; |
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
using Volo.Abp.Domain.Entities.Auditing; |
using Volo.Abp.Domain.Entities.Auditing; |
||||
|
|
||||
namespace Win_in.Sfs.Scp.WebApi.Domain.Shared |
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; |
||||
using System.ComponentModel.DataAnnotations; |
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Runtime.Serialization; |
||||
|
using System.Xml.Serialization; |
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
using Volo.Abp.Domain.Entities.Auditing; |
using Volo.Abp.Domain.Entities.Auditing; |
||||
|
|
||||
namespace Win_in.Sfs.Scp.WebApi.Domain.Shared |
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; } |
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