From d2f49add82704c60d41aa6ea4c0336a2050046b2 Mon Sep 17 00:00:00 2001 From: geht <2947093423@qq.com> Date: Tue, 12 May 2026 18:55:12 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=93=E5=8D=B0=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E7=AA=97=E5=8F=A3=E7=9A=84=E5=8F=82=E6=95=B0=E7=94=9F?= =?UTF-8?q?=E6=88=90=E9=80=BB=E8=BE=91=EF=BC=8C=E6=94=AF=E6=8C=81=E6=A0=B9?= =?UTF-8?q?=E6=8D=AE=E5=90=88=E5=B9=B6=E5=AD=97=E6=AE=B5=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9B=B8=E5=BA=94=E7=9A=84=20JSON=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=A2=9E=E5=BC=BA=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E7=9A=84=E7=81=B5=E6=B4=BB=E6=80=A7=E5=92=8C?= =?UTF-8?q?=E5=8F=AF=E5=AE=9A=E5=88=B6=E6=80=A7=E3=80=82=E5=90=8C=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E4=BF=AE=E5=A4=8D=E4=BA=86=E5=88=97=E7=BA=A7=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E9=80=BB=E8=BE=91=EF=BC=8C=E7=A1=AE=E4=BF=9D=E5=9C=A8?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=87=8D=E5=A4=8D=E9=94=AE=E6=97=B6=E4=B8=8D?= =?UTF-8?q?=E4=BC=9A=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Service/Print/NativePrintRenderService.cs | 10 ++- .../Views/Print/PrintPreviewWindow.xaml.cs | 68 ++++++++++++++++--- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/yy-admin-master/YY.Admin.Services/Service/Print/NativePrintRenderService.cs b/yy-admin-master/YY.Admin.Services/Service/Print/NativePrintRenderService.cs index 62dc0af..00ec733 100644 --- a/yy-admin-master/YY.Admin.Services/Service/Print/NativePrintRenderService.cs +++ b/yy-admin-master/YY.Admin.Services/Service/Print/NativePrintRenderService.cs @@ -1017,14 +1017,18 @@ public static class NativePrintRenderService var colList = columns.OfType().ToList(); if (mergeColumnKeys.Length > 0) { - var byKey = colList.ToDictionary( - c => ReadAsString(c["key"]) ?? string.Empty, - c => ReadAsString(c["bindField"]) ?? ReadAsString(c["field"]) ?? string.Empty); + // 用 GroupBy 兜底,避免重复 key 抛异常;按 mergeColumnKeys 给定顺序输出对应 bindField/field + var byKey = colList + .GroupBy(c => ReadAsString(c["key"]) ?? string.Empty) + .ToDictionary( + g => g.Key, + g => ReadAsString(g.First()["bindField"]) ?? ReadAsString(g.First()["field"]) ?? string.Empty); return mergeColumnKeys .Select(k => byKey.TryGetValue(k, out var f) ? f : string.Empty) .Where(f => !string.IsNullOrEmpty(f)) .ToList(); } + // 兼容老的列级 mergeByValue 开关 return colList .Where(c => string.Equals(ReadAsString(c["mergeByValue"]), "true", StringComparison.OrdinalIgnoreCase)) .Select(c => ReadAsString(c["bindField"]) ?? ReadAsString(c["field"]) ?? string.Empty) diff --git a/yy-admin-master/YY.Admin/Views/Print/PrintPreviewWindow.xaml.cs b/yy-admin-master/YY.Admin/Views/Print/PrintPreviewWindow.xaml.cs index f26a1e7..93983c1 100644 --- a/yy-admin-master/YY.Admin/Views/Print/PrintPreviewWindow.xaml.cs +++ b/yy-admin-master/YY.Admin/Views/Print/PrintPreviewWindow.xaml.cs @@ -109,6 +109,8 @@ public partial class PrintPreviewWindow : HandyControl.Controls.Window /// /// 根据模板绑定字段生成参数 JSON(便于用户直接编辑并预览)。 + /// 与 web 端 nativeMockData.ts 保持一致:识别 mergeColumnKeys 让同组相邻行字段值相同, + /// 以便在预览中触发 rowSpan 合并显示。 /// private static string BuildMockParamJson(string templateJson) { @@ -121,6 +123,7 @@ public partial class PrintPreviewWindow : HandyControl.Controls.Window var obj = new JsonObject(); var elements = root?["elements"]?.AsArray() ?? new JsonArray(); var fields = new HashSet(StringComparer.OrdinalIgnoreCase); + var rng = new Random(); foreach (var el in elements.OfType()) { @@ -130,28 +133,73 @@ public partial class PrintPreviewWindow : HandyControl.Controls.Window var source = (el["source"]?.ToString() ?? "mainTable").Trim(); if (!obj.ContainsKey(source)) { - var rows = new JsonArray(); var columns = el["columns"]?.AsArray() ?? new JsonArray(); - for (var i = 1; i <= 8; i++) + var colList = columns.OfType().ToList(); + + // 解析合并字段顺序:根据 mergeColumnKeys 按 column.key 映射到 bindField + var mergeKeys = (el["mergeColumnKeys"]?.AsArray() ?? new JsonArray()) + .Select(n => n?.ToString() ?? string.Empty) + .Where(s => !string.IsNullOrEmpty(s)) + .ToList(); + var strictGrouping = !string.Equals( + el["strictGrouping"]?.ToString() ?? "true", "false", + StringComparison.OrdinalIgnoreCase); + + var mergeFieldOrder = mergeKeys + .Select(k => colList.FirstOrDefault(c => string.Equals(c["key"]?.ToString() ?? string.Empty, k, StringComparison.Ordinal))) + .Where(c => c != null) + .Select(c => (c!["bindField"]?.ToString() ?? c!["field"]?.ToString() ?? string.Empty).Trim()) + .Where(s => !string.IsNullOrEmpty(s)) + .ToList(); + + var rows = new JsonArray(); + JsonObject? prevRow = null; + for (var i = 0; i < 8; i++) { var row = new JsonObject(); - foreach (var col in columns.OfType()) + foreach (var col in colList) { var field = (col["bindField"]?.ToString() ?? col["field"]?.ToString() ?? string.Empty).Trim(); if (string.IsNullOrWhiteSpace(field)) continue; var contentType = (col["contentType"]?.ToString() ?? "text").Trim().ToLowerInvariant(); + fields.Add(field); + + var mergeIndex = mergeFieldOrder.IndexOf(field); + var enableMerge = mergeIndex >= 0; + + if (enableMerge) + { + // 父级合并字段在 strictGrouping 下必须与前一行一致,才允许沿用前一行值 + var canFollowPrev = !strictGrouping || mergeIndex == 0 || (prevRow != null && + mergeFieldOrder.Take(mergeIndex).All(parent => + (prevRow[parent]?.ToString() ?? string.Empty) == (row[parent]?.ToString() ?? string.Empty))); + + if (i > 0 && prevRow != null && canFollowPrev && rng.NextDouble() < 0.5) + { + // 沿用前一行此字段值,从而触发合并 + var prevVal = prevRow[field]; + row[field] = prevVal != null ? JsonNode.Parse(prevVal.ToJsonString()) : (JsonNode?)$"{field}_合并组1"; + } + else + { + // 新合并组:随机 0-3 表示组编号 + row[field] = $"{field}_合并组{rng.Next(1, 5)}"; + } + continue; + } + row[field] = contentType switch { - "number" => i * 123.45, - "amount" => i * 24567.89, - "qrcode" => $"QR_{field}_{i}", - "barcode" => $"BAR_{field}_{i}", - "image" => $"https://picsum.photos/seed/{Uri.EscapeDataString(field + "_" + i)}/260/120", - _ => $"{field}_示例值_{i}" + "number" => (i + 1) * 123.45, + "amount" => (i + 1) * 24567.89, + "qrcode" => $"QR_{field}_{i + 1}", + "barcode" => $"BAR_{field}_{i + 1}", + "image" => $"https://picsum.photos/seed/{Uri.EscapeDataString(field + "_" + (i + 1))}/260/120", + _ => $"{field}_示例值_{i + 1}" }; - fields.Add(field); } rows.Add(row); + prevRow = row; } obj[source] = rows; }