Files

118 lines
3.9 KiB
C#

using DongfangHydro.Dashboard.Api.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace DongfangHydro.Dashboard.Api.Importing;
public sealed record BomImportCommand(string FilePath, bool PurgeDemo, bool ValidateOnly, bool Force)
{
public static BomImportCommand? Parse(string[] args)
{
if (args.Length == 0 || !string.Equals(args[0], "import-bom", StringComparison.OrdinalIgnoreCase))
{
return null;
}
string? filePath = null;
var purgeDemo = false;
var validateOnly = false;
var force = false;
for (var index = 1; index < args.Length; index++)
{
switch (args[index])
{
case "--file":
if (index + 1 >= args.Length || args[index + 1].StartsWith("--", StringComparison.Ordinal))
{
throw new BomImportException("import-bom 的 --file 参数必须提供 Excel 路径。");
}
filePath = args[++index];
break;
case "--purge-demo":
purgeDemo = true;
break;
case "--validate-only":
validateOnly = true;
break;
case "--force":
force = true;
break;
default:
throw new BomImportException($"不支持的 import-bom 参数:{args[index]}。");
}
}
if (string.IsNullOrWhiteSpace(filePath))
{
throw new BomImportException("import-bom 必须提供 --file <xlsx路径>。");
}
return new BomImportCommand(filePath, purgeDemo, validateOnly, force);
}
}
public static class BomImportCommandRunner
{
public static async Task<object> RunAsync(
IServiceProvider services,
BomImportCommand command,
CancellationToken cancellationToken)
{
var fullPath = Path.GetFullPath(command.FilePath);
if (!File.Exists(fullPath))
{
throw new BomImportException($"Excel 文件不存在:{fullPath}");
}
BomImportDocument document;
await using (var stream = File.OpenRead(fullPath))
{
document = BomWorkbookParser.Parse(stream, Path.GetFileName(fullPath));
}
var levelCounts = document.BomNodes
.GroupBy(node => node.Level)
.OrderBy(group => group.Key)
.ToDictionary(group => group.Key, group => group.Count());
if (command.ValidateOnly)
{
return new BomValidationReport(
fullPath,
document.Metadata.SourceDocumentCode,
document.Metadata.WorkOrderCode,
document.Metadata.SourceFileHash,
document.BlockCount,
document.BomNodes.Count,
document.MaterialQuotas.Count,
levelCounts,
document.Warnings);
}
await using var scope = services.CreateAsyncScope();
var dbContext = scope.ServiceProvider.GetRequiredService<DashboardDbContext>();
if (dbContext.Database.IsRelational())
{
await dbContext.Database.MigrateAsync(cancellationToken);
}
else
{
await dbContext.Database.EnsureCreatedAsync(cancellationToken);
}
return await scope.ServiceProvider.GetRequiredService<BomImportService>()
.ImportAsync(document, command.PurgeDemo, cancellationToken, command.Force);
}
}
public sealed record BomValidationReport(
string FilePath,
string SourceDocumentCode,
string WorkOrderCode,
string SourceFileHash,
int Blocks,
int BomNodes,
int MaterialQuotas,
IReadOnlyDictionary<int, int> LevelCounts,
IReadOnlyList<string> Warnings);