mahao 1 year ago
parent
commit
b9ed143c00
  1. 2
      code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/BaseServiceHostModule.cs
  2. 19
      code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/Program.cs
  3. 122
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAppService.cs
  4. 36
      code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAsyncBalanceService.cs

2
code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/BaseServiceHostModule.cs

@ -217,7 +217,7 @@ namespace BaseService
.ConventionalControllers .ConventionalControllers
.Create(typeof(BaseServiceApplicationModule).Assembly, opts .Create(typeof(BaseServiceApplicationModule).Assembly, opts
=> =>
{ opts.RootPath = "base"; }) { opts.RootPath = "base"; })
; ;
}); });
} }

19
code/src/Modules/SettleAccount/host/SettleAccount.HttpApi.Host/Program.cs

@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Serilog; using Serilog;
using Serilog.Settings.Configuration;
namespace Win.Sfs.SettleAccount; namespace Win.Sfs.SettleAccount;
@ -13,21 +12,13 @@ public class Program
{ {
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
.Build();
//try
//{
// new InfluxHelper(configuration).Start();
//}
//catch (Exception ex)
//{
// Console.Write("时序数据库启动失败");
// Console.Write(ex.ToString());
// //throw;
//}
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration, ConfigurationAssemblySource.AlwaysScanDllFiles) .WriteTo.Async(c => c.File("Logs/logs.txt"
, rollingInterval: RollingInterval.Day
, rollOnFileSizeLimit: true
, fileSizeLimitBytes: 30 * 1024 * 1024))
.WriteTo.Async(c => c.Console()) .WriteTo.Async(c => c.Console())
.CreateLogger(); .CreateLogger();

122
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAppService.cs

@ -11,6 +11,8 @@ using System.Reflection;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using ClosedXML.Excel; using ClosedXML.Excel;
using DocumentFormat.OpenXml;
using LinqToDB.Data;
using LinqToDB.EntityFrameworkCore; using LinqToDB.EntityFrameworkCore;
using Magicodes.ExporterAndImporter.Core; using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Extension; using Magicodes.ExporterAndImporter.Core.Extension;
@ -21,6 +23,7 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RestSharp.Extensions; using RestSharp.Extensions;
using SettleAccount.Job.SignalR; using SettleAccount.Job.SignalR;
using SqlSugar; using SqlSugar;
@ -53,6 +56,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
private readonly IBlobContainer<MyFileContainer> _fileContainer; private readonly IBlobContainer<MyFileContainer> _fileContainer;
private readonly IHubContext<PageHub> _hubContext; private readonly IHubContext<PageHub> _hubContext;
private readonly ICurrentUser _currentUser; private readonly ICurrentUser _currentUser;
private readonly ILogger<VmiAppService> _logger;
public VmiAppService(IConfiguration cfg, public VmiAppService(IConfiguration cfg,
IServiceProvider serviceProvider, IServiceProvider serviceProvider,
@ -61,7 +65,8 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
INormalEfCoreRepository<VmiLog, Guid> logRepository, INormalEfCoreRepository<VmiLog, Guid> logRepository,
IBlobContainer<MyFileContainer> fileContainer, IBlobContainer<MyFileContainer> fileContainer,
IHubContext<PageHub> hubContext, IHubContext<PageHub> hubContext,
ICurrentUser currentUser) ICurrentUser currentUser,
ILogger<VmiAppService> logger)
{ {
this._cfg = cfg; this._cfg = cfg;
this._guidGenerator = guidGenerator; this._guidGenerator = guidGenerator;
@ -71,6 +76,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
this._fileContainer = fileContainer; this._fileContainer = fileContainer;
this._hubContext = hubContext; this._hubContext = hubContext;
this._currentUser = currentUser; this._currentUser = currentUser;
this._logger = logger;
LinqToDBForEFTools.Initialize(); LinqToDBForEFTools.Initialize();
} }
@ -260,7 +266,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
} }
else else
{ {
Debug.WriteLine($"{tableName}不存在"); this._logger.LogInformation($"{tableName}不存在");
} }
} }
} }
@ -270,8 +276,12 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
if (tables.Any()) if (tables.Any())
{ {
//生成 union all 的 SQL使用 FromSqlRaw 查询,如果没有分表则使用原始表 //生成 union all 的 SQL使用 FromSqlRaw 查询,如果没有分表则使用原始表
sql = $"select * from {tables.First()}"; sql = $"select * from {tables.First()} WITH(NOLOCK)";
tables.Skip(1).ForEach(o => sql += $" union all select * from ${o}"); tables.Skip(1).ForEach(o => sql += $" union all select * from ${o} WITH(NOLOCK)");
}
else
{
sql = "select * from Set_VmiLog WITH(NOLOCK)";
} }
var query = string.IsNullOrEmpty(sql) ? db.Set<VmiLog>().AsQueryable() : db.Set<VmiLog>().FromSqlRaw(sql); var query = string.IsNullOrEmpty(sql) ? db.Set<VmiLog>().AsQueryable() : db.Set<VmiLog>().FromSqlRaw(sql);
var filters = input.Filters.ToLambda<VmiLog>(); var filters = input.Filters.ToLambda<VmiLog>();
@ -333,21 +343,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options; var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options;
using var context = new SettleAccountDbContext(options); using var context = new SettleAccountDbContext(options);
context.Database.UseTransaction(transaction); context.Database.UseTransaction(transaction);
log.ChangedTime = log.Id.ToDateTime().Value; Update(log);
if (log.ChangedQty >= decimal.Zero)
{
log.Qty = log.ChangedQty;
log.LogType = VmiLogType.Type500;
log.ChangedType = VmiType.In;
}
else
{
log.Qty = -log.Qty;
log.LogType = VmiLogType.Type600;
log.ChangedType = VmiType.Out;
}
log.ChangedBy = this._currentUser.UserName;
log.ChangedTime = DateTime.Now;
context.Set<VmiLog>().Add(log); context.Set<VmiLog>().Add(log);
context.Set<VmiMessage>().Add(new VmiMessage { Message = JsonSerializer.Serialize(log) }); context.Set<VmiMessage>().Add(new VmiMessage { Message = JsonSerializer.Serialize(log) });
context.SaveChanges(); context.SaveChanges();
@ -357,11 +353,29 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
catch (Exception ex) catch (Exception ex)
{ {
transaction.Rollback(); transaction.Rollback();
Console.WriteLine(ex.ToString()); this._logger.LogError(ex.ToString());
return new JsonResult(new { code = 400, data = ex.ToString(), message = ex.Message }); ; return new JsonResult(new { code = 400, data = ex.ToString(), message = ex.Message }); ;
} }
} }
private void Update(VmiLog log)
{
log.ChangedTime = log.Id.ToDateTime().Value;
if (log.ChangedQty >= decimal.Zero)
{
log.Qty = log.ChangedQty;
log.LogType = VmiLogType.Type500;
log.ChangedType = VmiType.In;
}
else
{
log.Qty = -log.Qty;
log.LogType = VmiLogType.Type600;
log.ChangedType = VmiType.Out;
}
log.ChangedBy = this._currentUser.UserName;
}
/// <summary> /// <summary>
/// 库存调整导入 /// 库存调整导入
/// </summary> /// </summary>
@ -369,6 +383,8 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
[HttpPost] [HttpPost]
public async Task<IActionResult> Import(List<IFormFile> files) public async Task<IActionResult> Import(List<IFormFile> files)
{ {
var connectionString = this._serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var connection = new SqlConnection(connectionString);
try try
{ {
using var ms = new MemoryStream(); using var ms = new MemoryStream();
@ -381,11 +397,11 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
using var workbook = new XLWorkbook(new MemoryStream(data)); using var workbook = new XLWorkbook(new MemoryStream(data));
var ws = workbook.Worksheets.FirstOrDefault(); var ws = workbook.Worksheets.FirstOrDefault();
var header = ws.Row(1); var header = ws.Row(1);
var errorIndex = ws.ColumnsUsed().Count(); var errorIndex = ws.ColumnsUsed().Count() + 1;
header.Cell(errorIndex).Value = "提示信息"; header.Cell(errorIndex).Value = "提示信息";
for (int i = 2; i < ws.RowsUsed().Count(); i++) for (int i = 0; i < ws.RowsUsed().Count() - 1; i++)
{ {
ws.Row(2).Cell(errorIndex).Value = string.Join(',', validationResults[i - 2].Select(o => o.ErrorMessage)); ws.Row(i + 2).Cell(errorIndex).Value = string.Join(',', validationResults[i].Select(o => o.ErrorMessage));
} }
SetStyle(ws); SetStyle(ws);
using var stream = new MemoryStream(); using var stream = new MemoryStream();
@ -395,16 +411,26 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
await this._fileContainer.SaveAsync(fileName, stream, true).ConfigureAwait(false); await this._fileContainer.SaveAsync(fileName, stream, true).ConfigureAwait(false);
return new JsonResult(new { code = 400, message = "输入异常", fileName }); return new JsonResult(new { code = 400, message = "输入异常", fileName });
} }
foreach (var item in list) var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options;
{ using var context = new SettleAccountDbContext(options);
Adjust(item); list.ForEach(Update);
} var messageList = list.Select(log => new VmiMessage { Message = JsonSerializer.Serialize(log) });
using var dc = context.CreateLinqToDBConnection();
dc.BeginTransaction();
var st = new Stopwatch();
st.Start();
this._logger.LogInformation("事务开始");
await dc.BulkCopyAsync(new BulkCopyOptions { TableName = "Set_VmiLog", MaxBatchSize = 1000 }, list).ConfigureAwait(false);
await dc.BulkCopyAsync(new BulkCopyOptions { TableName = "Set_VmiMessage", MaxBatchSize = 1000 }, messageList).ConfigureAwait(false);
dc.CommitTransaction();
st.Stop();
this._logger.LogInformation($"事务结束,耗时 ${st.ElapsedMilliseconds / 1000 / 60}分钟");
return new JsonResult(new { code = 200, message = "ok" }); return new JsonResult(new { code = 200, message = "ok" });
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString()); this._logger.LogError(ex.ToString());
throw; return new JsonResult(new { code = 500, data = ex.ToString(), message = ex.Message }); ;
} }
} }
@ -416,8 +442,8 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
{ {
using var workbook = new XLWorkbook(new MemoryStream(data)); using var workbook = new XLWorkbook(new MemoryStream(data));
var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty) var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty)
.Where(o => o.GetAttributes<ImporterHeaderAttribute>().Any()) .Where(o => o.GetAttributes<ImporterHeaderAttribute>().Any() || o.GetAttributes<DisplayAttribute>().Any())
.ToDictionary(o => o.GetAttribute<ImporterHeaderAttribute>().Name, o => o); .ToDictionary(o => o.GetAttribute<ImporterHeaderAttribute>()?.Name ?? o.GetAttribute<DisplayAttribute>()?.Name, o => o);
var ws = workbook.Worksheets.FirstOrDefault(); var ws = workbook.Worksheets.FirstOrDefault();
for (int rowIndex = 2; rowIndex <= ws.RowsUsed().Count(); rowIndex++) for (int rowIndex = 2; rowIndex <= ws.RowsUsed().Count(); rowIndex++)
@ -430,10 +456,38 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
var headerName = ws.Cell(1, columnIndex).Value.ToString().Trim(); var headerName = ws.Cell(1, columnIndex).Value.ToString().Trim();
if (properties.TryGetValue(headerName, out var property)) if (properties.TryGetValue(headerName, out var property))
{ {
var propertyType = property.PropertyType;
var value = cell.Value.ToString(); var value = cell.Value.ToString();
if (!string.IsNullOrEmpty(value)) if (!string.IsNullOrEmpty(value))
{ {//值非空
property.SetValue(model, Convert.ChangeType(value, property.PropertyType)); if (propertyType.IsValueType())
{//值类型
if (propertyType.IsGenericType() && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
{//可空值类型
propertyType = propertyType.GetGenericArguments()[0];//取原始类型
}
if (propertyType.IsEnum)
{//枚举
var enumValue = Enum.GetNames(propertyType)
.Select(o => new KeyValuePair<string, Enum>(o, (Enum)Enum.Parse(propertyType, o)))
.Where(o => o.Value.GetDisplayName() == value.ToString())
.Select(o => o.Value)
.FirstOrDefault();
property.SetValue(model, enumValue);
}
else if (propertyType == typeof(DateTime))
{
property.SetValue(model, DateTime.Parse(value));
}
else
{
property.SetValue(model, Convert.ChangeType(value, property.PropertyType));
}
}
else
{//引用类型
property.SetValue(model, Convert.ChangeType(value, property.PropertyType));
}
} }
} }
} }
@ -446,7 +500,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString()); this._logger.LogError(ex.ToString());
throw; throw;
} }
} }

36
code/src/Modules/SettleAccount/src/SettleAccount.Application/Entities/BQ/VmiAsyncBalanceService.cs

@ -1,13 +1,16 @@
using System; using System;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Linq.Dynamic.Core; using System.Linq.Dynamic.Core;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Magicodes.ExporterAndImporter.Core.Extension; using Magicodes.ExporterAndImporter.Core.Extension;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Omu.ValueInjecter; using Omu.ValueInjecter;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
@ -19,19 +22,37 @@ namespace Win.Sfs.SettleAccount.Entities.BQ;
/// <summary> /// <summary>
/// 异步更新库存 /// 异步更新库存
/// </summary> /// </summary>
public class VmiAsyncBalanceService : ApplicationService, IJobService, ITransientDependency [Route("[controller]/[action]")]
public class VmiAsyncBalanceService : Controller, IApplicationService, IJobService, ITransientDependency
{ {
private readonly IServiceProvider _serviceProvider; private readonly IServiceProvider _serviceProvider;
private readonly ILogger<VmiAsyncBalanceService> _logger;
public VmiAsyncBalanceService(IServiceProvider serviceProvider) public VmiAsyncBalanceService(IServiceProvider serviceProvider, ILogger<VmiAsyncBalanceService> logger)
{ {
this._serviceProvider = serviceProvider; this._serviceProvider = serviceProvider;
this._logger = logger;
} }
/// <summary>
/// 异步更新库存,手动测试
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<double> Test()
{
var now = DateTime.Now;
await Invoke(_serviceProvider).ConfigureAwait(false);
return (DateTime.Now - now).TotalMinutes;
}
[NonAction]
public async Task Invoke(IServiceProvider serviceProvider) public async Task Invoke(IServiceProvider serviceProvider)
{ {
for (var i = 0; i < 100; i++) for (var i = 0; i < 100; i++)
{ {
var sw = new Stopwatch();
sw.Start();
var connectionString = serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService"); var connectionString = serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var connection = new SqlConnection(connectionString); using var connection = new SqlConnection(connectionString);
connection.Open(); connection.Open();
@ -130,14 +151,15 @@ public class VmiAsyncBalanceService : ApplicationService, IJobService, ITransien
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine(ex.ToString()); this._logger.LogError(ex.ToString());
transaction.Rollback(); transaction.Rollback();
throw; throw;
} }
finally
{
sw.Stop();
this._logger.LogInformation($"结束,耗时 ${sw.ElapsedMilliseconds / 1000 / 60}分钟");
}
} }
} }
public async Task InvokeInternal(IServiceProvider serviceProvider)
{
}
} }

Loading…
Cancel
Save