|
|
@@ -3296,7 +3296,7 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
|
|
|
public int 人数 { get; set; }
|
|
|
|
|
|
- public string 收款日期 { get; set; }
|
|
|
+ // public string 收款日期 { get; set; }
|
|
|
};
|
|
|
|
|
|
[HttpPost]
|
|
|
@@ -3366,8 +3366,10 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
营业颔 = x.GroupSales,
|
|
|
出访日期 = x.VisitDate.ToString("yyyy-MM-dd"),
|
|
|
人数 = x.VisitPNumber,
|
|
|
- 收款日期 = x.CollectionDays.ToString("yyyy-MM-dd")
|
|
|
- }).ToList();
|
|
|
+ // 收款日期 = x.CollectionDays.ToString("yyyy-MM-dd")
|
|
|
+ })
|
|
|
+ .OrderBy(x => x.序号)
|
|
|
+ .ToList();
|
|
|
|
|
|
var url = this.MarkdownToWord(new
|
|
|
List<WordContentItem>{
|
|
|
@@ -3385,10 +3387,10 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
}
|
|
|
}, $"{user_entity.CnName}_{data.Year}年{data.Month.ToString("00")}月绩效分析");
|
|
|
|
|
|
- return Ok(new
|
|
|
- {
|
|
|
- url
|
|
|
- });
|
|
|
+ jw.Data = new { url };
|
|
|
+ jw.Code = 200;
|
|
|
+ jw.Msg = "操作成功!";
|
|
|
+ return Ok(jw);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
@@ -3555,6 +3557,9 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
// Markdown转换管道
|
|
|
var pipeline = new Markdig.MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
|
|
|
|
|
|
+ // 用于记录每次插入内容后的目标段落位置
|
|
|
+ Aspose.Words.Paragraph targetParagraph = null;
|
|
|
+
|
|
|
// 处理每个内容项
|
|
|
for (int i = 0; i < contentItems.Count; i++)
|
|
|
{
|
|
|
@@ -3580,16 +3585,15 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // 如果不是第一个内容项,确保前一个段落没有过大的间距
|
|
|
- builder.MoveToDocumentEnd();
|
|
|
- var lastParagraph = doc.LastSection.Body.LastParagraph;
|
|
|
- if (lastParagraph != null)
|
|
|
+ // 如果不是第一个内容项,移动到目标段落位置
|
|
|
+ if (targetParagraph != null)
|
|
|
{
|
|
|
- // 减少前一个段落的间距
|
|
|
- lastParagraph.ParagraphFormat.SpaceAfter = 0;
|
|
|
- lastParagraph.ParagraphFormat.SpaceBefore = 0;
|
|
|
+ builder.MoveTo(targetParagraph);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ builder.MoveToDocumentEnd();
|
|
|
}
|
|
|
- // 不插入额外的段落分隔,直接追加内容
|
|
|
}
|
|
|
|
|
|
if (item.Type == WordContentType.Markdown)
|
|
|
@@ -3761,40 +3765,32 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // 非第一个内容项:记录追加前的段落数量
|
|
|
- int paraCountBefore = doc.FirstSection.Body.Paragraphs.Count;
|
|
|
+ // 非第一个内容项:插入到目标段落位置
|
|
|
+ builder.InsertDocument(tempDoc, Aspose.Words.ImportFormatMode.KeepSourceFormatting);
|
|
|
|
|
|
- // 追加到文档末尾
|
|
|
- doc.AppendDocument(tempDoc, Aspose.Words.ImportFormatMode.KeepSourceFormatting);
|
|
|
-
|
|
|
- // 追加后立即清理格式,确保与第一个内容项格式一致
|
|
|
+ // 统一字体格式
|
|
|
var appendedBody = doc.FirstSection.Body;
|
|
|
var allParagraphs = appendedBody.Paragraphs;
|
|
|
|
|
|
- // 处理所有追加的段落(从paraCountBefore开始)
|
|
|
- for (int paraIdx = paraCountBefore; paraIdx < allParagraphs.Count; paraIdx++)
|
|
|
+ foreach (Aspose.Words.Paragraph para in allParagraphs)
|
|
|
{
|
|
|
- var para = allParagraphs[paraIdx];
|
|
|
-
|
|
|
- // 删除空段落
|
|
|
+ // 跳过空段落(不删除)
|
|
|
if (string.IsNullOrWhiteSpace(para.GetText().Trim()))
|
|
|
{
|
|
|
- para.Remove();
|
|
|
- paraIdx--; // 调整索引
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // 统一段落格式:移除前间距,限制后间距
|
|
|
+ // 统一段落格式
|
|
|
para.ParagraphFormat.SpaceBefore = 0;
|
|
|
if (para.ParagraphFormat.SpaceAfter > 6)
|
|
|
{
|
|
|
para.ParagraphFormat.SpaceAfter = 6;
|
|
|
}
|
|
|
|
|
|
- // 统一字体格式 - 与第一个内容项的处理逻辑完全一致
|
|
|
+ // 统一字体格式
|
|
|
foreach (Aspose.Words.Run run in para.Runs)
|
|
|
{
|
|
|
- // 统一字体名称 - 强制设置为微软雅黑
|
|
|
+ // 统一字体名称
|
|
|
if (string.IsNullOrEmpty(run.Font.Name) ||
|
|
|
(!run.Font.Name.Contains("微软") && !run.Font.Name.Contains("Microsoft") &&
|
|
|
!run.Font.Name.Contains("Sim") && !run.Font.Name.Contains("宋体")))
|
|
|
@@ -3802,7 +3798,7 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
run.Font.Name = "微软雅黑";
|
|
|
}
|
|
|
|
|
|
- // 统一字体大小 - 与第一个内容项的逻辑完全一致
|
|
|
+ // 统一字体大小
|
|
|
bool isHeading = para.ParagraphFormat.StyleIdentifier == Aspose.Words.StyleIdentifier.Heading1 ||
|
|
|
para.ParagraphFormat.StyleIdentifier == Aspose.Words.StyleIdentifier.Heading2 ||
|
|
|
para.ParagraphFormat.StyleIdentifier == Aspose.Words.StyleIdentifier.Heading3 ||
|
|
|
@@ -3810,20 +3806,8 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
|
|
|
if (!isHeading)
|
|
|
{
|
|
|
- // 非标题:强制统一设置为10.5pt,确保与第一个内容项一致
|
|
|
run.Font.Size = 10.5;
|
|
|
}
|
|
|
- // 标题保持原有大小,但字体名称已在上面的逻辑中统一
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 确保追加内容前的最后一个段落没有过大的后间距
|
|
|
- if (paraCountBefore > 0 && paraCountBefore <= allParagraphs.Count)
|
|
|
- {
|
|
|
- var lastParaBefore = allParagraphs[paraCountBefore - 1];
|
|
|
- if (lastParaBefore != null)
|
|
|
- {
|
|
|
- lastParaBefore.ParagraphFormat.SpaceAfter = 0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -3832,6 +3816,16 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
// 移动builder到文档末尾
|
|
|
builder.MoveToDocumentEnd();
|
|
|
}
|
|
|
+
|
|
|
+ // 如果不是最后一个内容项,添加三个段落作为间隔
|
|
|
+ if (i < contentItems.Count - 1)
|
|
|
+ {
|
|
|
+ for (int p = 0; p < 3; p++)
|
|
|
+ {
|
|
|
+ builder.InsertBreak(Aspose.Words.BreakType.ParagraphBreak);
|
|
|
+ targetParagraph = builder.CurrentParagraph;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
else if (item.Type == WordContentType.Table)
|
|
|
{
|
|
|
@@ -3871,12 +3865,17 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
builder.InsertBreak(Aspose.Words.BreakType.ParagraphBreak);
|
|
|
builder.InsertBreak(Aspose.Words.BreakType.ParagraphBreak);
|
|
|
|
|
|
+ // 强制设置为标题3样式
|
|
|
+ builder.ParagraphFormat.StyleIdentifier = Aspose.Words.StyleIdentifier.Heading3;
|
|
|
builder.ParagraphFormat.SpaceAfter = 6;
|
|
|
builder.ParagraphFormat.SpaceBefore = 0; // 表格标题前不添加间距
|
|
|
builder.Font.Size = 12;
|
|
|
builder.Font.Bold = true;
|
|
|
builder.Font.Name = "微软雅黑";
|
|
|
builder.Writeln(item.TableTitle);
|
|
|
+
|
|
|
+ // 恢复为正常段落样式
|
|
|
+ builder.ParagraphFormat.StyleIdentifier = Aspose.Words.StyleIdentifier.Normal;
|
|
|
builder.Font.Bold = false;
|
|
|
builder.Font.Size = 10.5;
|
|
|
builder.ParagraphFormat.SpaceAfter = 3; // 标题和表格之间的小间距
|
|
|
@@ -3951,11 +3950,24 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
|
|
|
// 设置较小的段落间距
|
|
|
builder.ParagraphFormat.SpaceAfter = 6;
|
|
|
+
|
|
|
+ // 移动builder到文档末尾
|
|
|
+ builder.MoveToDocumentEnd();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果不是最后一个内容项,添加三个段落作为间隔
|
|
|
+ if (i < contentItems.Count - 1)
|
|
|
+ {
|
|
|
+ for (int p = 0; p < 3; p++)
|
|
|
+ {
|
|
|
+ builder.InsertBreak(Aspose.Words.BreakType.ParagraphBreak);
|
|
|
+ targetParagraph = builder.CurrentParagraph;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 清理文档开头的空段落,避免第一段内容前出现空白页
|
|
|
+ // 只清理文档开头的空段落(第一个有内容的段落之前的空段落)
|
|
|
var body = doc.FirstSection.Body;
|
|
|
var paragraphs = body.Paragraphs;
|
|
|
while (paragraphs.Count > 0)
|
|
|
@@ -3975,10 +3987,18 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 遍历所有段落,确保字体设置正确,并统一段落间距
|
|
|
+ // 注意:不删除内容项之间用于间隔的空段落
|
|
|
+
|
|
|
+ // 遍历所有段落,确保字体设置正确,并统一段落间距(不删除空段落)
|
|
|
foreach (Aspose.Words.Paragraph paragraph in doc.GetChildNodes(Aspose.Words.NodeType.Paragraph, true))
|
|
|
{
|
|
|
- // 统一段落间距,避免内容项之间出现大段空白
|
|
|
+ // 跳过空段落(不删除,用于内容项之间的间隔)
|
|
|
+ if (string.IsNullOrWhiteSpace(paragraph.GetText().Trim()))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 统一段落间距
|
|
|
if (paragraph.ParagraphFormat.StyleIdentifier != Aspose.Words.StyleIdentifier.Heading1 &&
|
|
|
paragraph.ParagraphFormat.StyleIdentifier != Aspose.Words.StyleIdentifier.Heading2 &&
|
|
|
paragraph.ParagraphFormat.StyleIdentifier != Aspose.Words.StyleIdentifier.Heading3 &&
|
|
|
@@ -3989,7 +4009,7 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
{
|
|
|
paragraph.ParagraphFormat.SpaceAfter = 6;
|
|
|
}
|
|
|
- // 移除段落前的间距,避免内容项之间出现空白
|
|
|
+ // 移除段落前的间距
|
|
|
if (paragraph.ParagraphFormat.SpaceBefore > 0)
|
|
|
{
|
|
|
paragraph.ParagraphFormat.SpaceBefore = 0;
|
|
|
@@ -4149,7 +4169,10 @@ OPTION (MAXRECURSION 0); -- 允许无限递归 ";
|
|
|
DepName = d.DepName,
|
|
|
JobPostId = u.JobPostId,
|
|
|
JobName = jp.JobName,
|
|
|
- WorkYears = SqlFunc.DateDiff(DateType.Year, u.Edate, DateTime.Now)
|
|
|
+ WorkYears = SqlFunc.DateDiff(DateType.Year, u.Edate, DateTime.Now),
|
|
|
+ HasPerformanceData = SqlFunc.Subqueryable<Pm_PerformanceAnalysis>()
|
|
|
+ .Where(pa => pa.UserId == u.Id && pa.Year == dto.Year && pa.Month == dto.Month && pa.IsDel == 0)
|
|
|
+ .Any()
|
|
|
})
|
|
|
.ToPageListAsync(dto.PageIndex, dto.PageSize, total);
|
|
|
|
|
|
@@ -4275,6 +4298,10 @@ ORDER BY MonthNumber, CollectionDays";
|
|
|
public int JobPostId { get; set; }
|
|
|
public string JobName { get; set; }
|
|
|
public int WorkYears { get; set; }
|
|
|
+ /// <summary>
|
|
|
+ /// 是否存在绩效分析数据
|
|
|
+ /// </summary>
|
|
|
+ public bool HasPerformanceData { get; set; }
|
|
|
}
|
|
|
|
|
|
#endregion
|