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

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.Hosting;
using Serilog;
using Serilog.Settings.Configuration;
namespace Win.Sfs.SettleAccount;
@ -13,21 +12,13 @@ public class Program
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.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;
//}
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true, reloadOnChange: true);
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())
.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.Threading.Tasks;
using ClosedXML.Excel;
using DocumentFormat.OpenXml;
using LinqToDB.Data;
using LinqToDB.EntityFrameworkCore;
using Magicodes.ExporterAndImporter.Core;
using Magicodes.ExporterAndImporter.Core.Extension;
@ -21,6 +23,7 @@ using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using RestSharp.Extensions;
using SettleAccount.Job.SignalR;
using SqlSugar;
@ -53,6 +56,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
private readonly IBlobContainer<MyFileContainer> _fileContainer;
private readonly IHubContext<PageHub> _hubContext;
private readonly ICurrentUser _currentUser;
private readonly ILogger<VmiAppService> _logger;
public VmiAppService(IConfiguration cfg,
IServiceProvider serviceProvider,
@ -61,7 +65,8 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
INormalEfCoreRepository<VmiLog, Guid> logRepository,
IBlobContainer<MyFileContainer> fileContainer,
IHubContext<PageHub> hubContext,
ICurrentUser currentUser)
ICurrentUser currentUser,
ILogger<VmiAppService> logger)
{
this._cfg = cfg;
this._guidGenerator = guidGenerator;
@ -71,6 +76,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
this._fileContainer = fileContainer;
this._hubContext = hubContext;
this._currentUser = currentUser;
this._logger = logger;
LinqToDBForEFTools.Initialize();
}
@ -260,7 +266,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
}
else
{
Debug.WriteLine($"{tableName}不存在");
this._logger.LogInformation($"{tableName}不存在");
}
}
}
@ -270,8 +276,12 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
if (tables.Any())
{
//生成 union all 的 SQL使用 FromSqlRaw 查询,如果没有分表则使用原始表
sql = $"select * from {tables.First()}";
tables.Skip(1).ForEach(o => sql += $" union all select * from ${o}");
sql = $"select * from {tables.First()} WITH(NOLOCK)";
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 filters = input.Filters.ToLambda<VmiLog>();
@ -333,21 +343,7 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options;
using var context = new SettleAccountDbContext(options);
context.Database.UseTransaction(transaction);
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;
log.ChangedTime = DateTime.Now;
Update(log);
context.Set<VmiLog>().Add(log);
context.Set<VmiMessage>().Add(new VmiMessage { Message = JsonSerializer.Serialize(log) });
context.SaveChanges();
@ -357,11 +353,29 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
catch (Exception ex)
{
transaction.Rollback();
Console.WriteLine(ex.ToString());
this._logger.LogError(ex.ToString());
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>
@ -369,6 +383,8 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
[HttpPost]
public async Task<IActionResult> Import(List<IFormFile> files)
{
var connectionString = this._serviceProvider.GetRequiredService<IConfiguration>().GetConnectionString("SettleAccountService");
using var connection = new SqlConnection(connectionString);
try
{
using var ms = new MemoryStream();
@ -381,11 +397,11 @@ public class VmiAppService : Controller, IApplicationService, IJobService, ITran
using var workbook = new XLWorkbook(new MemoryStream(data));
var ws = workbook.Worksheets.FirstOrDefault();
var header = ws.Row(1);
var errorIndex = ws.ColumnsUsed().Count();
var errorIndex = ws.ColumnsUsed().Count() + 1;
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);
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);
return new JsonResult(new { code = 400, message = "输入异常", fileName });
}
foreach (var item in list)
{
Adjust(item);
}
var options = new DbContextOptionsBuilder<SettleAccountDbContext>().UseSqlServer(connection).Options;
using var context = new SettleAccountDbContext(options);
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" });
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
throw;
this._logger.LogError(ex.ToString());
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));
var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty)
.Where(o => o.GetAttributes<ImporterHeaderAttribute>().Any())
.ToDictionary(o => o.GetAttribute<ImporterHeaderAttribute>().Name, o => o);
.Where(o => o.GetAttributes<ImporterHeaderAttribute>().Any() || o.GetAttributes<DisplayAttribute>().Any())
.ToDictionary(o => o.GetAttribute<ImporterHeaderAttribute>()?.Name ?? o.GetAttribute<DisplayAttribute>()?.Name, o => o);
var ws = workbook.Worksheets.FirstOrDefault();
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();
if (properties.TryGetValue(headerName, out var property))
{
var propertyType = property.PropertyType;
var value = cell.Value.ToString();
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)
{
Console.WriteLine(ex.ToString());
this._logger.LogError(ex.ToString());
throw;
}
}

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

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

Loading…
Cancel
Save