A szállítólevélhez csatolt fájl tartalma lekérhető a dróton
- Új SignalR endpoint (tag 69) a Files rekord tartalmához, a kliens beépített megjelenítőjének: a blob a wwwroot-on kívül él, az admin preview-endpoint pedig nop admin sütit vár, ami a MAUI kliensnek nincs. - FileStorageService.GetFileContentAsync: az útvonalat a tárolt FileSubPath-ból oldja fel, nem a hívó userId-jából. Az útvonal első szegmense a feltöltőé, ezért más admin alatt eddig nem lehetett megtalálni a fájlt; a kitömörítést a ".gz" utótag dönti el, nem az IsCompressed jelző.
This commit is contained in:
@@ -30,6 +30,7 @@ using Nop.Core.Domain.Orders;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Factories;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||
using Nop.Plugin.Misc.FruitBankPlugin.Services.FileStorage;
|
||||
using Nop.Services.Customers;
|
||||
using Nop.Services.Localization;
|
||||
using Nop.Web.Framework.Controllers;
|
||||
@@ -54,6 +55,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
IEkaerSettings ekaerSettings,
|
||||
INavCredentials navCredentials,
|
||||
ShippingCostService shippingCostService,
|
||||
FileStorageService fileStorageService,
|
||||
IEnumerable<IAcLogWriterBase> logWriters)
|
||||
: BasePluginController, IFruitBankDataControllerServer
|
||||
{
|
||||
@@ -1459,6 +1461,25 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||
return await ctx.ShippingDocuments.GetByIdAsync(shippingDocument.Id, shippingDocument.Shipping != null || shippingDocument.Partner != null);
|
||||
}
|
||||
|
||||
/// <summary>A szállítólevélhez csatolt fájl nyers tartalma, a kliens beépített megjelenítőjének.</summary>
|
||||
/// <remarks>
|
||||
/// A fájl a dróton jön, nem URL-en: a blob a wwwroot-on KÍVÜL él, a kiszolgáló admin-endpointja
|
||||
/// (<c>FileStorageController.PreviewFile</c>) pedig nop admin sütit vár, ami a MAUI kliensnek nincs.
|
||||
/// Ugyanez a hívás így weben és mobilon azonosan működik.
|
||||
/// <para>Egy üzenetben, darabolás nélkül — a mai szállítólevél-szkennek ezt bőven bírják. Ha egyszer
|
||||
/// nagyobb fájl kerül be, a darabolás külön munka.</para>
|
||||
/// </remarks>
|
||||
[SignalR(SignalRTags.GetShippingDocumentFileContent)]
|
||||
public async Task<byte[]> GetShippingDocumentFileContent(int filesId)
|
||||
{
|
||||
_logger.Detail($"GetShippingDocumentFileContent invoked; filesId: {filesId}");
|
||||
|
||||
var file = await ctx.Files.GetByIdAsync(filesId);
|
||||
if (file == null) return null;
|
||||
|
||||
return await fileStorageService.GetFileContentAsync(file);
|
||||
}
|
||||
|
||||
#region Adattisztító törlés (őrzött, fizikai)
|
||||
|
||||
// A visszatérés szándékosan string?: üres/null = mehet (illetve sikerült), egyébként az admin
|
||||
|
||||
@@ -358,6 +358,51 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Services.FileStorage
|
||||
return foundPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a file's content, located by the stored path instead of the original upload coordinates.
|
||||
/// <para>
|
||||
/// Deliberately not <see cref="GetFileByIdAsync"/>: that one rebuilds the path from the CALLING user's
|
||||
/// id, while the first path segment is the UPLOADING user's — so it cannot find a file another user
|
||||
/// uploaded. The same gap covers the hash-deduplicated file, whose blob stayed in the ORIGINAL entity's
|
||||
/// folder while the mapping points at a newer document.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <returns>The file bytes, or null when the blob cannot be located.</returns>
|
||||
public async Task<byte[]> GetFileContentAsync(Files fileEntity)
|
||||
{
|
||||
if (fileEntity == null) return null;
|
||||
|
||||
var relativePath = await ResolveStoragePathAsync(fileEntity);
|
||||
|
||||
if (string.IsNullOrWhiteSpace(relativePath))
|
||||
{
|
||||
Console.Error.WriteLine($"⚠️ File blob not found for Files.Id {fileEntity.Id} ('{fileEntity.FileName}{fileEntity.FileExtension}').");
|
||||
return null;
|
||||
}
|
||||
|
||||
// A ".gz" utótag dönt, nem a Files.IsCompressed jelző: az útvonal azt írja le, ami a lemezen VAN,
|
||||
// a jelző pedig azt, aminek a mentéskor lennie kellett volna. PDF-nél és képnél nincs tömörítés.
|
||||
var isGzipped = relativePath.EndsWith(".gz", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
using (var storedStream = await _storageProvider.GetFileAsync(relativePath))
|
||||
using (var buffer = new MemoryStream())
|
||||
{
|
||||
if (isGzipped)
|
||||
{
|
||||
using (var gzipStream = new GZipStream(storedStream, CompressionMode.Decompress, leaveOpen: true))
|
||||
{
|
||||
await gzipStream.CopyToAsync(buffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await storedStream.CopyToAsync(buffer);
|
||||
}
|
||||
|
||||
return buffer.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a file record and its blob without needing the original upload coordinates.
|
||||
/// <para>
|
||||
|
||||
Reference in New Issue
Block a user