feat: add local database and file export infrastructure

Add EF Core DbContext with ExportRecord and BomItem entities for
tracking export history locally. Add FileExportService for saving
DXF and PDF files to a configurable output folder.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 11:26:50 -05:00
parent c4926c6e9f
commit 384fceb047
3 changed files with 150 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
using ExportDXF.Models;
using Microsoft.EntityFrameworkCore;
using System.Configuration;
namespace ExportDXF.Data
{
public class ExportDxfDbContext : DbContext
{
public DbSet<ExportRecord> ExportRecords { get; set; }
public DbSet<BomItem> BomItems { get; set; }
public ExportDxfDbContext() : base()
{
}
public ExportDxfDbContext(DbContextOptions<ExportDxfDbContext> options) : base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
var connectionString = ConfigurationManager.ConnectionStrings["ExportDxfDb"]?.ConnectionString
?? "Server=localhost;Database=ExportDxfDb;Trusted_Connection=True;TrustServerCertificate=True;";
optionsBuilder.UseSqlServer(connectionString);
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ExportRecord>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.DrawingNumber).HasMaxLength(100);
entity.Property(e => e.SourceFilePath).HasMaxLength(500);
entity.Property(e => e.OutputFolder).HasMaxLength(500);
entity.Property(e => e.ExportedBy).HasMaxLength(100);
entity.HasMany(e => e.BomItems)
.WithOne(b => b.ExportRecord)
.HasForeignKey(b => b.ExportRecordId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<BomItem>(entity =>
{
entity.HasKey(e => e.ID);
entity.Property(e => e.ItemNo).HasMaxLength(50);
entity.Property(e => e.PartNo).HasMaxLength(100);
entity.Property(e => e.Description).HasMaxLength(500);
entity.Property(e => e.PartName).HasMaxLength(200);
entity.Property(e => e.ConfigurationName).HasMaxLength(100);
entity.Property(e => e.Material).HasMaxLength(100);
entity.Property(e => e.CutTemplateName).HasMaxLength(100);
});
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
namespace ExportDXF.Models
{
public class ExportRecord
{
public int Id { get; set; }
public string DrawingNumber { get; set; }
public string SourceFilePath { get; set; }
public string OutputFolder { get; set; }
public DateTime ExportedAt { get; set; }
public string ExportedBy { get; set; }
public virtual ICollection<BomItem> BomItems { get; set; } = new List<BomItem>();
}
}

View File

@@ -0,0 +1,72 @@
using System;
using System.IO;
namespace ExportDXF.Services
{
public interface IFileExportService
{
string OutputFolder { get; }
string SaveDxfFile(string sourcePath, string drawingNumber, string itemNo);
string SavePdfFile(string sourcePath, string drawingNumber);
void EnsureOutputFolderExists();
}
public class FileExportService : IFileExportService
{
public string OutputFolder { get; }
public FileExportService(string outputFolder)
{
OutputFolder = outputFolder ?? throw new ArgumentNullException(nameof(outputFolder));
EnsureOutputFolderExists();
}
public void EnsureOutputFolderExists()
{
if (!Directory.Exists(OutputFolder))
{
Directory.CreateDirectory(OutputFolder);
}
}
public string SaveDxfFile(string sourcePath, string drawingNumber, string itemNo)
{
if (string.IsNullOrEmpty(sourcePath))
throw new ArgumentNullException(nameof(sourcePath));
var fileName = !string.IsNullOrEmpty(drawingNumber) && !string.IsNullOrEmpty(itemNo)
? $"{drawingNumber} PT{itemNo}.dxf"
: Path.GetFileName(sourcePath);
var destPath = Path.Combine(OutputFolder, fileName);
// If source and dest are the same, skip copy
if (!string.Equals(sourcePath, destPath, StringComparison.OrdinalIgnoreCase))
{
File.Copy(sourcePath, destPath, overwrite: true);
}
return destPath;
}
public string SavePdfFile(string sourcePath, string drawingNumber)
{
if (string.IsNullOrEmpty(sourcePath))
throw new ArgumentNullException(nameof(sourcePath));
var fileName = !string.IsNullOrEmpty(drawingNumber)
? $"{drawingNumber}.pdf"
: Path.GetFileName(sourcePath);
var destPath = Path.Combine(OutputFolder, fileName);
// If source and dest are the same, skip copy
if (!string.Equals(sourcePath, destPath, StringComparison.OrdinalIgnoreCase))
{
File.Copy(sourcePath, destPath, overwrite: true);
}
return destPath;
}
}
}