admin/src/Oms.Application/Labeling/InboundBoxLabelPrintDataBuilder.cs
zzh 1cef872823
All checks were successful
Build and Deploy / deploy (push) Successful in 1m1s
fix: 箱唛增加箱子总数,QuestPDF 注册中文字体防乱码
入库箱唛字段 boxCount;渲染时嵌入 CJK 字体,镜像安装 fonts-noto-cjk。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-23 12:44:49 +08:00

160 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Globalization;
using Oms.Domain.WarehouseAggregate.Entities;
namespace Oms.Application.Labeling;
/// <summary>
/// 入库箱唛 PrintData(camelCase,与 hiprint 字段对齐;箱唛为主、SKU 为辅)。
/// </summary>
public static class InboundBoxLabelPrintDataBuilder
{
public static IReadOnlyDictionary<string, object?> Build(
CInboundNotice notice,
CInboundBox box,
IReadOnlyList<CInboundBoxLine> lines,
IReadOnlyDictionary<int, CSku> skuMap,
string? warehouseName = null,
string? customerName = null,
string? customerCode = null,
string? operatorName = null,
DateTime? printTime = null,
int pageIndex = 1,
int pageCount = 1)
{
var barcode = ResolveBarcode(notice.NoticeNo, box);
var skuLines = lines
.OrderBy(x => x.Id)
.Select(line =>
{
skuMap.TryGetValue(line.SkuId, out var sku);
var skuCode = FirstNonEmpty(line.SkuCode, sku?.SkuCode) ?? string.Empty;
var skuName = sku?.SkuName ?? string.Empty;
return new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
{
["skuCode"] = skuCode,
["skuName"] = skuName,
["qty"] = line.PlannedQty
};
})
.ToList();
var first = skuLines.FirstOrDefault();
var skuSummary = string.Join(
"\n",
skuLines.Select(x =>
{
var code = Convert.ToString(x.GetValueOrDefault("skuCode")) ?? string.Empty;
var name = Convert.ToString(x.GetValueOrDefault("skuName")) ?? string.Empty;
var qty = Convert.ToString(x.GetValueOrDefault("qty")) ?? "0";
return string.IsNullOrWhiteSpace(name)
? $"{code}×{qty}"
: $"{code} {name}×{qty}";
}));
return new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
{
["noticeNo"] = notice.NoticeNo,
["markReference"] = notice.MarkReference,
["inboundType"] = notice.InboundType,
["receiptStatus"] = notice.ReceiptStatus,
["remark"] = notice.Remark,
["boxId"] = box.Id,
["boxSeqNo"] = box.BoxSeqNo,
["boxCount"] = pageCount,
["markBoxNo"] = box.MarkBoxNo,
["barcode"] = barcode,
["warehouseName"] = warehouseName,
["customerCode"] = customerCode,
["customerName"] = customerName,
["weightG"] = box.WeightG,
["lengthCm"] = box.LengthCm,
["widthCm"] = box.WidthCm,
["heightCm"] = box.HeightCm,
["weightUnit"] = "G",
["dimUnit"] = "CM",
["skuSummary"] = skuSummary,
["skuCode"] = first?.GetValueOrDefault("skuCode"),
["skuName"] = first?.GetValueOrDefault("skuName"),
["skuQty"] = first?.GetValueOrDefault("qty"),
["items"] = skuLines,
["pageIndex"] = pageIndex,
["pageCount"] = pageCount,
["boxIndexText"] = $"{pageIndex}/{pageCount}",
["printTime"] = (printTime ?? DateTime.Now).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
["operatorName"] = operatorName
};
}
/// <summary>
/// 设计预览用 Mock PrintData。
/// </summary>
public static IReadOnlyDictionary<string, object?> BuildMock() =>
new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase)
{
["noticeNo"] = "IN202610220001",
["markReference"] = "SF1234567890",
["inboundType"] = "normal",
["receiptStatus"] = "forecasted",
["remark"] = null,
["boxId"] = 1,
["boxSeqNo"] = "1",
["boxCount"] = 2,
["markBoxNo"] = "BOX-001",
["barcode"] = "BOX-001",
["warehouseName"] = "SZ-01",
["customerCode"] = "AF0A1",
["customerName"] = "Demo Customer",
["weightG"] = 1200m,
["lengthCm"] = 30m,
["widthCm"] = 20m,
["heightCm"] = 15m,
["weightUnit"] = "G",
["dimUnit"] = "CM",
["skuSummary"] = "SKU001 T-Shirt×2\nSKU002 Pants×1",
["skuCode"] = "SKU001",
["skuName"] = "T-Shirt",
["skuQty"] = 2,
["items"] = new List<Dictionary<string, object?>>
{
new()
{
["skuCode"] = "SKU001",
["skuName"] = "T-Shirt",
["qty"] = 2
},
new()
{
["skuCode"] = "SKU002",
["skuName"] = "Pants",
["qty"] = 1
}
},
["pageIndex"] = 1,
["pageCount"] = 2,
["boxIndexText"] = "1/2",
["printTime"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture),
["operatorName"] = "preview"
};
public static string ResolveBarcode(string noticeNo, CInboundBox box)
{
if (!string.IsNullOrWhiteSpace(box.MarkBoxNo))
{
return box.MarkBoxNo.Trim();
}
var seq = string.IsNullOrWhiteSpace(box.BoxSeqNo) ? "1" : box.BoxSeqNo.Trim();
var no = string.IsNullOrWhiteSpace(noticeNo) ? "IN" : noticeNo.Trim();
return $"{no}-{seq}";
}
private static string? FirstNonEmpty(params string?[] values) =>
values.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x));
}