feat: add FabWorks API client for ExportDXF
Add IFabWorksApiClient interface, FabWorksApiClient implementation, and DTO classes for communicating with the FabWorks API from the SolidWorks add-in. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
157
ExportDXF/ApiClient/FabWorksApiClient.cs
Normal file
157
ExportDXF/ApiClient/FabWorksApiClient.cs
Normal file
@@ -0,0 +1,157 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ExportDXF.ApiClient
|
||||
{
|
||||
public class FabWorksApiClient : IFabWorksApiClient
|
||||
{
|
||||
private readonly HttpClient _http;
|
||||
|
||||
public FabWorksApiClient(HttpClient httpClient)
|
||||
{
|
||||
_http = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
|
||||
}
|
||||
|
||||
public async Task<ApiExportDetail> CreateExportAsync(string drawingNumber, string equipmentNo, string drawingNo, string sourceFilePath, string outputFolder, string title = null)
|
||||
{
|
||||
var request = new ApiCreateExportRequest
|
||||
{
|
||||
DrawingNumber = drawingNumber,
|
||||
Title = title,
|
||||
EquipmentNo = equipmentNo,
|
||||
DrawingNo = drawingNo,
|
||||
SourceFilePath = sourceFilePath,
|
||||
OutputFolder = outputFolder
|
||||
};
|
||||
|
||||
var response = await _http.PostAsJsonAsync("api/exports", request);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiExportDetail>();
|
||||
}
|
||||
|
||||
public async Task<ApiExportDetail> GetExportBySourceFileAsync(string filePath)
|
||||
{
|
||||
var response = await _http.GetAsync($"api/exports/by-source?path={Uri.EscapeDataString(filePath)}");
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
return null;
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiExportDetail>();
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetDrawingNumbersAsync()
|
||||
{
|
||||
var response = await _http.GetAsync("api/exports/drawing-numbers");
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<List<string>>();
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetEquipmentNumbersAsync()
|
||||
{
|
||||
var response = await _http.GetAsync("api/exports/equipment-numbers");
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<List<string>>();
|
||||
}
|
||||
|
||||
public async Task<List<string>> GetDrawingNumbersByEquipmentAsync(string equipmentNo = null)
|
||||
{
|
||||
var url = "api/exports/drawing-numbers-by-equipment";
|
||||
if (!string.IsNullOrEmpty(equipmentNo))
|
||||
url += $"?equipmentNo={Uri.EscapeDataString(equipmentNo)}";
|
||||
|
||||
var response = await _http.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<List<string>>();
|
||||
}
|
||||
|
||||
public async Task<string> GetNextItemNumberAsync(string drawingNumber)
|
||||
{
|
||||
var response = await _http.GetAsync($"api/exports/next-item-number?drawingNumber={Uri.EscapeDataString(drawingNumber)}");
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public async Task UpdatePdfHashAsync(int exportId, string pdfContentHash)
|
||||
{
|
||||
var request = new ApiUpdatePdfHashRequest { PdfContentHash = pdfContentHash };
|
||||
var response = await _http.PatchAsJsonAsync($"api/exports/{exportId}/pdf-hash", request);
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
|
||||
public async Task<string> GetPreviousPdfHashAsync(string drawingNumber, int? excludeId = null)
|
||||
{
|
||||
var url = $"api/exports/previous-pdf-hash?drawingNumber={Uri.EscapeDataString(drawingNumber)}";
|
||||
if (excludeId.HasValue)
|
||||
url += $"&excludeId={excludeId.Value}";
|
||||
|
||||
var response = await _http.GetAsync(url);
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
return null;
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
}
|
||||
|
||||
public async Task<ApiBomItem> FindExistingBomItemAsync(int exportId, string partName, string configurationName)
|
||||
{
|
||||
var url = $"api/exports/{exportId}/bom-items/find?partName={Uri.EscapeDataString(partName ?? "")}&configurationName={Uri.EscapeDataString(configurationName ?? "")}";
|
||||
var response = await _http.GetAsync(url);
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
return null;
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiBomItem>();
|
||||
}
|
||||
|
||||
public async Task<ApiBomItem> CreateBomItemAsync(int exportId, ApiBomItem bomItem)
|
||||
{
|
||||
var response = await _http.PostAsJsonAsync($"api/exports/{exportId}/bom-items", bomItem);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiBomItem>();
|
||||
}
|
||||
|
||||
public async Task<ApiCutTemplate> GetPreviousCutTemplateAsync(string drawingNumber, string itemNo)
|
||||
{
|
||||
var response = await _http.GetAsync($"api/exports/previous-cut-template?drawingNumber={Uri.EscapeDataString(drawingNumber)}&itemNo={Uri.EscapeDataString(itemNo)}");
|
||||
if (response.StatusCode == HttpStatusCode.NotFound)
|
||||
return null;
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiCutTemplate>();
|
||||
}
|
||||
|
||||
public async Task<ApiFileUploadResponse> UploadDxfAsync(string localFilePath, string equipment, string drawingNo, string itemNo, string contentHash)
|
||||
{
|
||||
using var content = new MultipartFormDataContent();
|
||||
using var fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
|
||||
var fileContent = new StreamContent(fileStream);
|
||||
content.Add(fileContent, "file", Path.GetFileName(localFilePath));
|
||||
content.Add(new StringContent(equipment ?? ""), "equipment");
|
||||
content.Add(new StringContent(drawingNo ?? ""), "drawingNo");
|
||||
content.Add(new StringContent(itemNo ?? ""), "itemNo");
|
||||
content.Add(new StringContent(contentHash ?? ""), "contentHash");
|
||||
|
||||
var response = await _http.PostAsync("api/files/dxf", content);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiFileUploadResponse>();
|
||||
}
|
||||
|
||||
public async Task<ApiFileUploadResponse> UploadPdfAsync(string localFilePath, string equipment, string drawingNo, string contentHash, int? exportRecordId = null)
|
||||
{
|
||||
using var content = new MultipartFormDataContent();
|
||||
using var fileStream = new FileStream(localFilePath, FileMode.Open, FileAccess.Read);
|
||||
var fileContent = new StreamContent(fileStream);
|
||||
content.Add(fileContent, "file", Path.GetFileName(localFilePath));
|
||||
content.Add(new StringContent(equipment ?? ""), "equipment");
|
||||
content.Add(new StringContent(drawingNo ?? ""), "drawingNo");
|
||||
content.Add(new StringContent(contentHash ?? ""), "contentHash");
|
||||
if (exportRecordId.HasValue)
|
||||
content.Add(new StringContent(exportRecordId.Value.ToString()), "exportRecordId");
|
||||
|
||||
var response = await _http.PostAsync("api/files/pdf", content);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return await response.Content.ReadFromJsonAsync<ApiFileUploadResponse>();
|
||||
}
|
||||
}
|
||||
}
|
||||
85
ExportDXF/ApiClient/FabWorksApiDtos.cs
Normal file
85
ExportDXF/ApiClient/FabWorksApiDtos.cs
Normal file
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ExportDXF.ApiClient
|
||||
{
|
||||
public class ApiExportDetail
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string DrawingNumber { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string EquipmentNo { get; set; }
|
||||
public string DrawingNo { get; set; }
|
||||
public string SourceFilePath { get; set; }
|
||||
public string OutputFolder { get; set; }
|
||||
public DateTime ExportedAt { get; set; }
|
||||
public string ExportedBy { get; set; }
|
||||
public string PdfContentHash { get; set; }
|
||||
public List<ApiBomItem> BomItems { get; set; } = new();
|
||||
}
|
||||
|
||||
public class ApiBomItem
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public string ItemNo { get; set; }
|
||||
public string PartNo { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public int? Qty { get; set; }
|
||||
public int? TotalQty { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string PartName { get; set; }
|
||||
public string ConfigurationName { get; set; }
|
||||
public string Material { get; set; }
|
||||
public ApiCutTemplate CutTemplate { get; set; }
|
||||
public ApiFormProgram FormProgram { get; set; }
|
||||
}
|
||||
|
||||
public class ApiCutTemplate
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string DxfFilePath { get; set; }
|
||||
public string ContentHash { get; set; }
|
||||
public double? Thickness { get; set; }
|
||||
public double? KFactor { get; set; }
|
||||
public double? DefaultBendRadius { get; set; }
|
||||
}
|
||||
|
||||
public class ApiFormProgram
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string ProgramFilePath { get; set; }
|
||||
public string ContentHash { get; set; }
|
||||
public string ProgramName { get; set; }
|
||||
public double? Thickness { get; set; }
|
||||
public string MaterialType { get; set; }
|
||||
public double? KFactor { get; set; }
|
||||
public int BendCount { get; set; }
|
||||
public string UpperToolNames { get; set; }
|
||||
public string LowerToolNames { get; set; }
|
||||
public string SetupNotes { get; set; }
|
||||
}
|
||||
|
||||
public class ApiCreateExportRequest
|
||||
{
|
||||
public string DrawingNumber { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string EquipmentNo { get; set; }
|
||||
public string DrawingNo { get; set; }
|
||||
public string SourceFilePath { get; set; }
|
||||
public string OutputFolder { get; set; }
|
||||
}
|
||||
|
||||
public class ApiUpdatePdfHashRequest
|
||||
{
|
||||
public string PdfContentHash { get; set; }
|
||||
}
|
||||
|
||||
public class ApiFileUploadResponse
|
||||
{
|
||||
public string StoredFilePath { get; set; }
|
||||
public string ContentHash { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public bool WasUnchanged { get; set; }
|
||||
public bool IsNewFile { get; set; }
|
||||
}
|
||||
}
|
||||
22
ExportDXF/ApiClient/IFabWorksApiClient.cs
Normal file
22
ExportDXF/ApiClient/IFabWorksApiClient.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ExportDXF.ApiClient
|
||||
{
|
||||
public interface IFabWorksApiClient
|
||||
{
|
||||
Task<ApiExportDetail> CreateExportAsync(string drawingNumber, string equipmentNo, string drawingNo, string sourceFilePath, string outputFolder, string title = null);
|
||||
Task<ApiExportDetail> GetExportBySourceFileAsync(string filePath);
|
||||
Task<List<string>> GetDrawingNumbersAsync();
|
||||
Task<List<string>> GetEquipmentNumbersAsync();
|
||||
Task<List<string>> GetDrawingNumbersByEquipmentAsync(string equipmentNo = null);
|
||||
Task<string> GetNextItemNumberAsync(string drawingNumber);
|
||||
Task UpdatePdfHashAsync(int exportId, string pdfContentHash);
|
||||
Task<string> GetPreviousPdfHashAsync(string drawingNumber, int? excludeId = null);
|
||||
Task<ApiBomItem> FindExistingBomItemAsync(int exportId, string partName, string configurationName);
|
||||
Task<ApiBomItem> CreateBomItemAsync(int exportId, ApiBomItem bomItem);
|
||||
Task<ApiCutTemplate> GetPreviousCutTemplateAsync(string drawingNumber, string itemNo);
|
||||
Task<ApiFileUploadResponse> UploadDxfAsync(string localFilePath, string equipment, string drawingNo, string itemNo, string contentHash);
|
||||
Task<ApiFileUploadResponse> UploadPdfAsync(string localFilePath, string equipment, string drawingNo, string contentHash, int? exportRecordId = null);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user