fix: 运单列表 enrichment 改为顺序查询,避免 MySqlConnection 并发复用 #13

Merged
zzh merged 7 commits from test into master 2026-10-24 13:36:05 +08:00
5 changed files with 103 additions and 0 deletions
Showing only changes of commit 1cef872823 - Show all commits

View File

@ -0,0 +1,88 @@
using QuestPDF.Drawing;
namespace Oms.Application.Labeling.Hiprint;
/// <summary>
/// 面单 PDF 中文字体:QuestPDF 默认字体无 CJK,不注册会显示 □ / ?。
/// </summary>
public static class LabelPdfFontRegistrar
{
public const string FamilyName = "OmsLabelSans";
private static int _state; // 0=未试 1=成功 2=失败
private static string? _sourcePath;
/// <summary>
/// 确保已注册可用中文字体;成功返回 <see cref="FamilyName"/>,否则 null(仅西文)。
/// </summary>
public static string? EnsureRegistered()
{
var state = Volatile.Read(ref _state);
if (state == 1)
{
return FamilyName;
}
if (state == 2)
{
return null;
}
foreach (var path in EnumerateCandidates())
{
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
{
continue;
}
try
{
using var stream = File.OpenRead(path);
FontManager.RegisterFontWithCustomName(FamilyName, stream);
_sourcePath = path;
Interlocked.Exchange(ref _state, 1);
return FamilyName;
}
catch
{
// 试下一个候选
}
}
Interlocked.Exchange(ref _state, 2);
return null;
}
/// <summary>已成功注册时的字体文件路径(诊断用)。</summary>
public static string? RegisteredSourcePath => _sourcePath;
private static IEnumerable<string> EnumerateCandidates()
{
var fromEnv = Environment.GetEnvironmentVariable("OMS_LABEL_FONT");
if (!string.IsNullOrWhiteSpace(fromEnv))
{
yield return fromEnv.Trim();
}
var baseDir = AppContext.BaseDirectory;
yield return Path.Combine(baseDir, "Fonts", "NotoSansSC-Regular.otf");
yield return Path.Combine(baseDir, "Fonts", "NotoSansSC-Regular.ttf");
yield return Path.Combine(baseDir, "Fonts", "NotoSansCJKsc-Regular.otf");
// Windows
var winFonts = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
if (!string.IsNullOrWhiteSpace(winFonts))
{
yield return Path.Combine(winFonts, "msyh.ttc");
yield return Path.Combine(winFonts, "msyhbd.ttc");
yield return Path.Combine(winFonts, "simhei.ttf");
yield return Path.Combine(winFonts, "simsun.ttc");
}
// Debian/Ubuntu(Dockerfile 安装 fonts-noto-cjk)
yield return "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc";
yield return "/usr/share/fonts/opentype/noto/NotoSansCJKsc-Regular.otf";
yield return "/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc";
yield return "/usr/share/fonts/truetype/wqy/wqy-microhei.ttc";
}
}

View File

@ -23,6 +23,8 @@ public sealed class QuestPdfLabelRenderer(HiprintTemplateParser parser) : ILabel
CancellationToken cancellationToken = default)
{
EnsureLicense();
// SKU 名称等含中文;未注册 CJK 字体会输出 □
_ = LabelPdfFontRegistrar.EnsureRegistered();
cancellationToken.ThrowIfCancellationRequested();
if (printDataPages == null || printDataPages.Count == 0)
@ -90,6 +92,12 @@ public sealed class QuestPdfLabelRenderer(HiprintTemplateParser parser) : ILabel
.FontSize(text.FontSizePt)
.FontColor(ParseColor(text.ColorHex));
var fontFamily = LabelPdfFontRegistrar.EnsureRegistered();
if (!string.IsNullOrEmpty(fontFamily))
{
span.FontFamily(fontFamily);
}
if (text.Bold)
{
span.Bold();

View File

@ -61,6 +61,7 @@ public static class InboundBoxLabelPrintDataBuilder
["boxId"] = box.Id,
["boxSeqNo"] = box.BoxSeqNo,
["boxCount"] = pageCount,
["markBoxNo"] = box.MarkBoxNo,
["barcode"] = barcode,
@ -103,6 +104,7 @@ public static class InboundBoxLabelPrintDataBuilder
["remark"] = null,
["boxId"] = 1,
["boxSeqNo"] = "1",
["boxCount"] = 2,
["markBoxNo"] = "BOX-001",
["barcode"] = "BOX-001",
["warehouseName"] = "SZ-01",

View File

@ -85,6 +85,7 @@ public static class LabelFieldDictionary
Field("markReference", "唛头参考"),
Field("markBoxNo", "箱唛号"),
Field("boxSeqNo", "箱序号"),
Field("boxCount", "箱子总数"),
Field("barcode", "条码内容"),
Field("boxIndexText", "箱序页码"),
Field("skuSummary", "SKU 摘要"),

View File

@ -24,6 +24,10 @@ RUN dotnet publish "SimpleAdmin.Api.csproj" -c $BUILD_CONFIGURATION -o /app/publ
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
# 面单 QuestPDF 需 CJK 字体,否则中文 SKU 等渲染为 □
RUN apt-get update \
&& apt-get install -y --no-install-recommends fonts-noto-cjk \
&& rm -rf /var/lib/apt/lists/*
COPY --from=build /app/publish .
# Local 存储落盘 wwwroot;非 root 用户需可写 uploads(Provider=Cos 时可不依赖此目录)
RUN mkdir -p /app/wwwroot/uploads \