完成证书发放功能

This commit is contained in:
马梓彭 2026-04-16 12:51:29 +08:00
parent fc1d85449d
commit 41c55fafe0

View File

@ -475,6 +475,16 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
}
}
// 按照Y轴坐标进行升序排序,确保文本框显示顺序与Word文档视觉顺序一致
documentData.Paragraphs = documentData.Paragraphs
.OrderBy(p => p.PositionY ?? double.MaxValue) // 使用PositionY排序,没有位置的放在最后
.ThenBy(p => p.PositionX ?? double.MaxValue) // Y轴相同的情况下按X轴排序
.ToList();
// 记录排序后的顺序,便于调试
_logger.LogDebug("文本框排序完成,顺序: {Order}",
string.Join(" -> ", documentData.Paragraphs.Select((p, i) => $"[{i}]{p.Text}(Y={p.PositionY})")));
return documentData;
}
@ -782,7 +792,7 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
_logger.LogDebug("Drawing 对象原始 XML (前800字符): {Xml}", outerXml.Substring(0, Math.Min(800, outerXml.Length)));
// 方法1: 查找 simplePos 属性(通常用于绝对定位)
ExtractSimplePosition(outerXml, paragraphData);
// ExtractSimplePosition(outerXml, paragraphData);
// 方法2: 如果 simplePos 没有值,查找 positionOffset 元素
if (paragraphData.PositionX == null || paragraphData.PositionY == null)
@ -1061,12 +1071,22 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
.FitArea();
}
// 使用 Column 来放置所有内容,但使用 Translate 而非 Padding 定位
// 使用 Column 来放置所有内容,但禁用默认间距
page.Content().Column(column =>
{
// 根据段落信息进行定位(使用从Word文档提取的位置信息)
foreach (var paragraph in documentData.Paragraphs)
column.Spacing(0);
double? firstParagraphY = null;
double? firstParagraphOriginalY = null;
// 根据文本框数量确定X轴偏移量
float xOffset = documentData.Paragraphs.Count == 1 ? 140 : 100;
_logger.LogDebug("文本框数量: {Count}, X轴偏移量: {Offset}", documentData.Paragraphs.Count, xOffset);
// 根据段落信息进行定位(基于第一个元素重新计算,保持50单位统一间隔)
for (int i = 0; i < documentData.Paragraphs.Count; i++)
{
var paragraph = documentData.Paragraphs[i];
var fontSize = paragraph.FontSize ?? 14;
var isBold = paragraph.IsBold;
@ -1074,13 +1094,28 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
_logger.LogDebug("处理段落: Text={Text}, X={X}, Y={Y}, FontSize={FontSize}, Bold={IsBold}",
paragraph.Text, paragraph.PositionX, paragraph.PositionY, fontSize, isBold);
// 直接使用从Word文档提取的位置信息,并增加110个单位进行调整
float x = (float)(paragraph.PositionX ?? 50) + 90;
float y = (float)(paragraph.PositionY ?? 50) + 50;
// 直接使用从Word文档提取的X坐标,并增加条件性调整值
float x = (float)(paragraph.PositionX ?? 50) + xOffset;
float y;
if (i == 0)
{
// 第一个段落,保持原始位置+70偏移
firstParagraphY = paragraph.PositionY ?? 50;
firstParagraphOriginalY = firstParagraphY.Value;
y = (float)firstParagraphY + 70;
_logger.LogDebug("第一个段落,使用原始Y + 70偏移");
}
else
{
// 后续段落,相对于前一个段落,固定增加50单位
y = (float)(firstParagraphOriginalY + 70) + (i * 45);
_logger.LogDebug("第{Index}个段落,基于第一个段落 + {Offset}单位", i + 1, i * 50);
}
_logger.LogDebug("最终位置 - X={X}, Y={Y}", x, y);
// 使用 Translate 而非 Padding 来定位,避免流式布局累加导致分页
// 使用 Translate 来定位,配合 Spacing(0) 确保没有额外间隔
var textElement = column.Item().TranslateX(x).TranslateY(y).Text(paragraph.Text)
.FontSize((float)fontSize)
.FontColor(QuestPDF.Helpers.Colors.Black)