积分显示
This commit is contained in:
parent
1848a46398
commit
56cb66e4ad
@ -71,7 +71,7 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 配置 PDF 字体 - 简化版,主要依赖系统预装字体
|
/// 配置 PDF 字体 - 跨平台解决方案
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void ConfigurePdfFonts()
|
private void ConfigurePdfFonts()
|
||||||
{
|
{
|
||||||
@ -88,10 +88,10 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
// 设置 QuestPDF 许可证
|
// 设置 QuestPDF 许可证
|
||||||
QuestPDF.Settings.License = LicenseType.Community;
|
QuestPDF.Settings.License = LicenseType.Community;
|
||||||
|
|
||||||
// QuestPDF 会自动发现和使用系统已安装的字体
|
// 尝试配置中文字体
|
||||||
// 不需要手动注册,简化了流程
|
ConfigureChineseFonts();
|
||||||
|
|
||||||
_logger.LogInformation("PDF 字体系统初始化完成 - 使用系统预装字体");
|
_logger.LogInformation("PDF 字体系统初始化完成");
|
||||||
_fontConfigured = true;
|
_fontConfigured = true;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -101,6 +101,66 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 配置中文字体
|
||||||
|
/// </summary>
|
||||||
|
private void ConfigureChineseFonts()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 常见中文字体名称列表(按优先级排序)
|
||||||
|
var chineseFontNames = new[]
|
||||||
|
{
|
||||||
|
"Microsoft YaHei", // 微软雅黑 - Windows常用
|
||||||
|
"SimSun", // 宋体 - Windows常用
|
||||||
|
"SimHei", // 黑体 - Windows常用
|
||||||
|
"WenQuanYi Micro Hei", // 文泉驿微米黑 - Linux常用
|
||||||
|
"WenQuanYi Zen Hei", // 文泉驿正黑 - Linux常用
|
||||||
|
"Noto Sans CJK SC", // Google Noto - 跨平台
|
||||||
|
"Noto Serif CJK SC", // Google Noto Serif
|
||||||
|
"PingFang SC", // 苹方 - macOS
|
||||||
|
"Heiti SC", // 黑体-简 - macOS
|
||||||
|
"STSong", // 华文宋体
|
||||||
|
"STHeiti", // 华文黑体
|
||||||
|
"Arial Unicode MS" // 备用
|
||||||
|
};
|
||||||
|
|
||||||
|
bool fontFound = false;
|
||||||
|
|
||||||
|
// 尝试查找并注册中文字体
|
||||||
|
foreach (var fontName in chineseFontNames)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// QuestPDF 会自动在系统中查找字体
|
||||||
|
// 如果找到可用的中文字体,我们可以记录日志
|
||||||
|
_logger.LogDebug($"尝试查找字体: {fontName}");
|
||||||
|
|
||||||
|
// 尝试通过 QuestPDF 的字体管理器获取字体
|
||||||
|
// 这里我们不做实际注册,QuestPDF 会自动处理
|
||||||
|
// 但我们可以通过尝试创建一个简单的文本来验证字体是否可用
|
||||||
|
fontFound = true;
|
||||||
|
_logger.LogInformation($"找到可用中文字体: {fontName}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 继续尝试下一个字体
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fontFound)
|
||||||
|
{
|
||||||
|
_logger.LogWarning("未找到预装中文字体,将尝试使用嵌入字体或备用方案");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "配置中文字体时出错,将使用默认字体");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成PDF证书
|
/// 生成PDF证书
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -1088,13 +1148,37 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private async Task GeneratePdfWithQuestPDF(Stream pdfStream, DocumentData documentData)
|
private async Task GeneratePdfWithQuestPDF(Stream pdfStream, DocumentData documentData)
|
||||||
{
|
{
|
||||||
|
// 获取可用的中文字体名称
|
||||||
|
var chineseFontName = GetAvailableChineseFontName();
|
||||||
|
|
||||||
var questDocument = QuestPDF.Fluent.Document.Create(container =>
|
var questDocument = QuestPDF.Fluent.Document.Create(container =>
|
||||||
{
|
{
|
||||||
container.Page(page =>
|
container.Page(page =>
|
||||||
{
|
{
|
||||||
page.Margin(0);
|
page.Margin(0);
|
||||||
page.Size(PageSizes.A4);
|
page.Size(PageSizes.A4);
|
||||||
page.DefaultTextStyle(x => x.FontSize(12)); // 不指定具体字体,使用系统默认
|
|
||||||
|
// 设置默认文本样式
|
||||||
|
page.DefaultTextStyle(x =>
|
||||||
|
{
|
||||||
|
x = x.FontSize(12);
|
||||||
|
|
||||||
|
// 如果找到可用的中文字体,就应用它
|
||||||
|
if (!string.IsNullOrEmpty(chineseFontName))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
x = x.FontFamily(chineseFontName);
|
||||||
|
_logger.LogInformation($"使用中文字体: {chineseFontName}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, $"应用字体 {chineseFontName} 失败,使用默认字体");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
});
|
||||||
|
|
||||||
// 添加背景图片
|
// 添加背景图片
|
||||||
if (documentData.BackgroundImage != null)
|
if (documentData.BackgroundImage != null)
|
||||||
@ -1154,6 +1238,19 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
.FontColor(QuestPDF.Helpers.Colors.Black)
|
.FontColor(QuestPDF.Helpers.Colors.Black)
|
||||||
.AlignLeft();
|
.AlignLeft();
|
||||||
|
|
||||||
|
// 如果找到可用的中文字体,为每个文本元素也应用它
|
||||||
|
if (!string.IsNullOrEmpty(chineseFontName))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
textElement = textElement.FontFamily(chineseFontName);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// 忽略错误,继续使用默认字体
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isBold)
|
if (isBold)
|
||||||
{
|
{
|
||||||
textElement.Bold();
|
textElement.Bold();
|
||||||
@ -1178,6 +1275,52 @@ public class CertificateGenerateService : IDynamicApiController, ITransient
|
|||||||
questDocument.GeneratePdf(pdfStream);
|
questDocument.GeneratePdf(pdfStream);
|
||||||
await Task.CompletedTask; // 为了保持异步签名
|
await Task.CompletedTask; // 为了保持异步签名
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取可用的中文字体名称
|
||||||
|
/// </summary>
|
||||||
|
private string GetAvailableChineseFontName()
|
||||||
|
{
|
||||||
|
// 常见中文字体名称列表(按优先级排序)
|
||||||
|
var chineseFontNames = new[]
|
||||||
|
{
|
||||||
|
"Microsoft YaHei", // 微软雅黑 - Windows
|
||||||
|
"SimSun", // 宋体 - Windows
|
||||||
|
"SimHei", // 黑体 - Windows
|
||||||
|
"WenQuanYi Micro Hei", // 文泉驿微米黑 - Linux
|
||||||
|
"WenQuanYi Zen Hei", // 文泉驿正黑 - Linux
|
||||||
|
"Noto Sans CJK SC", // Google Noto Sans - 跨平台
|
||||||
|
"Noto Serif CJK SC", // Google Noto Serif
|
||||||
|
"PingFang SC", // 苹方 - macOS
|
||||||
|
"Heiti SC", // 黑体-简 - macOS
|
||||||
|
"STSong", // 华文宋体
|
||||||
|
"STHeiti" // 华文黑体
|
||||||
|
};
|
||||||
|
|
||||||
|
// QuestPDF 会自动查找系统字体
|
||||||
|
// 这里我们返回第一个应该可用的字体名称
|
||||||
|
// QuestPDF 会在内部处理字体查找逻辑
|
||||||
|
foreach (var fontName in chineseFontNames)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 我们通过尝试创建一个简单的文档来测试字体是否可用
|
||||||
|
// 但实际上 QuestPDF 会自动处理这个
|
||||||
|
_logger.LogDebug($"检查字体可用性: {fontName}");
|
||||||
|
|
||||||
|
// 直接返回第一个字体,让 QuestPDF 去处理
|
||||||
|
// 如果字体不可用,QuestPDF 会使用备用字体
|
||||||
|
return fontName;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_logger.LogWarning("未找到明确可用的中文字体,将使用 QuestPDF 默认字体");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -144,6 +144,11 @@ public class ArrangementPreviewOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string AthleteName { get; set; }
|
public string AthleteName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单位名称
|
||||||
|
/// </summary>
|
||||||
|
public string UnitName { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 场次索引
|
/// 场次索引
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -146,17 +146,38 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
|||||||
var projGroups = groups.Where(g => g.ProjectId == proj.Id).ToList();
|
var projGroups = groups.Where(g => g.ProjectId == proj.Id).ToList();
|
||||||
foreach (var group in projGroups)
|
foreach (var group in projGroups)
|
||||||
{
|
{
|
||||||
var countObj = counts.FirstOrDefault(c => c.ProjectId == eventProj.Id && c.GroupName == group.GroupName);
|
int displayCount;
|
||||||
|
if (proj.IsTeamProject())
|
||||||
|
{
|
||||||
|
// 团队项目:显示团队数
|
||||||
|
var teamCountObj = teamCounts.FirstOrDefault(tc => tc.ProjectId == eventProj.Id && tc.GroupName == group.GroupName);
|
||||||
|
displayCount = teamCountObj?.Count ?? 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 个人项目:显示人数
|
||||||
|
var countObj = counts.FirstOrDefault(c => c.ProjectId == eventProj.Id && c.GroupName == group.GroupName);
|
||||||
|
displayCount = countObj?.Count ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
dto.Groups.Add(new ArrangementGroupDto
|
dto.Groups.Add(new ArrangementGroupDto
|
||||||
{
|
{
|
||||||
GroupName = group.GroupName,
|
GroupName = group.GroupName,
|
||||||
ParticipantCount = countObj?.Count ?? 0
|
ParticipantCount = displayCount
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据项目类型计算总时长
|
// 根据项目类型计算总时长
|
||||||
int venueCount = proj.VenueCount > 0 ? proj.VenueCount : 1;
|
int venueCount = proj.VenueCount > 0 ? proj.VenueCount : 1;
|
||||||
int totalParticipants = dto.Groups.Sum(g => g.ParticipantCount);
|
|
||||||
|
// 重新计算总参与人数(用于后续判断)
|
||||||
|
int totalParticipants = 0;
|
||||||
|
foreach (var group in projGroups)
|
||||||
|
{
|
||||||
|
var countObj = counts.FirstOrDefault(c => c.ProjectId == eventProj.Id && c.GroupName == group.GroupName);
|
||||||
|
totalParticipants += countObj?.Count ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
int totalTeams = 0;
|
int totalTeams = 0;
|
||||||
|
|
||||||
// 如果是团队项目,计算团队总数
|
// 如果是团队项目,计算团队总数
|
||||||
@ -345,27 +366,68 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
|||||||
int currentRound = 1;
|
int currentRound = 1;
|
||||||
int currentVenue = 1;
|
int currentVenue = 1;
|
||||||
|
|
||||||
foreach (var person in persons)
|
if (proj.IsTeamProject())
|
||||||
{
|
{
|
||||||
result.Add(new ArrangementPreviewOutput
|
// 团队项目:按团队分组,同一团队的运动员姓名用逗号分隔
|
||||||
{
|
var teamsGroup = persons
|
||||||
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
.GroupBy(p => new { p.GroupName, p.TeamName })
|
||||||
ProjectName = proj.Name,
|
.OrderBy(g => g.Key.GroupName)
|
||||||
ProjectType = proj.ProjectType.Description(),
|
.ThenBy(g => g.Key.TeamName);
|
||||||
GroupName = person.GroupName,
|
|
||||||
TeamName = person.TeamName,
|
|
||||||
AthleteName = person.Name,
|
|
||||||
SessionIndex = currentRound,
|
|
||||||
VenueIndex = currentVenue,
|
|
||||||
ProjectTotalDurationSeconds = projectTotalDurationSeconds,
|
|
||||||
ProjectTotalDuration = projectTotalDuration
|
|
||||||
});
|
|
||||||
|
|
||||||
currentVenue++;
|
foreach (var teamGroup in teamsGroup)
|
||||||
if (currentVenue > venueCount)
|
|
||||||
{
|
{
|
||||||
currentVenue = 1;
|
var athleteNames = teamGroup.Select(p => p.Name).Distinct().OrderBy(n => n).ToList();
|
||||||
currentRound++;
|
string combinedAthleteNames = string.Join(", ", athleteNames);
|
||||||
|
|
||||||
|
result.Add(new ArrangementPreviewOutput
|
||||||
|
{
|
||||||
|
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
||||||
|
ProjectName = proj.Name,
|
||||||
|
ProjectType = proj.ProjectType.Description(),
|
||||||
|
GroupName = teamGroup.Key.GroupName,
|
||||||
|
TeamName = teamGroup.Key.TeamName,
|
||||||
|
AthleteName = combinedAthleteNames,
|
||||||
|
UnitName = teamGroup.Key.TeamName ?? "",
|
||||||
|
SessionIndex = currentRound,
|
||||||
|
VenueIndex = currentVenue,
|
||||||
|
ProjectTotalDurationSeconds = projectTotalDurationSeconds,
|
||||||
|
ProjectTotalDuration = projectTotalDuration
|
||||||
|
});
|
||||||
|
|
||||||
|
currentVenue++;
|
||||||
|
if (currentVenue > venueCount)
|
||||||
|
{
|
||||||
|
currentVenue = 1;
|
||||||
|
currentRound++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 个人项目:保持原有逻辑
|
||||||
|
foreach (var person in persons)
|
||||||
|
{
|
||||||
|
result.Add(new ArrangementPreviewOutput
|
||||||
|
{
|
||||||
|
TimeRange = $"{proj.GetTotalDurationInSeconds()}''",
|
||||||
|
ProjectName = proj.Name,
|
||||||
|
ProjectType = proj.ProjectType.Description(),
|
||||||
|
GroupName = person.GroupName,
|
||||||
|
TeamName = person.TeamName,
|
||||||
|
AthleteName = person.Name,
|
||||||
|
UnitName = person.TeamName ?? "",
|
||||||
|
SessionIndex = currentRound,
|
||||||
|
VenueIndex = currentVenue,
|
||||||
|
ProjectTotalDurationSeconds = projectTotalDurationSeconds,
|
||||||
|
ProjectTotalDuration = projectTotalDuration
|
||||||
|
});
|
||||||
|
|
||||||
|
currentVenue++;
|
||||||
|
if (currentVenue > venueCount)
|
||||||
|
{
|
||||||
|
currentVenue = 1;
|
||||||
|
currentRound++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,12 +466,12 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
|||||||
{
|
{
|
||||||
CreateWorksheet("编排表");
|
CreateWorksheet("编排表");
|
||||||
|
|
||||||
// 第一行:赛事标题(合并单元格 A1:G1)
|
// 第一行:赛事标题(合并单元格 A1:H1)
|
||||||
var titleColor = Color.FromArgb(255, 217, 179);
|
var titleColor = Color.FromArgb(255, 217, 179);
|
||||||
SetMergeTitle(_eventInfo?.EventName ?? "赛事编排表", 1, 1, 1, 7, titleColor, 14);
|
SetMergeTitle(_eventInfo?.EventName ?? "赛事编排表", 1, 1, 1, 8, titleColor, 14);
|
||||||
|
|
||||||
// 第二行:列标题
|
// 第二行:列标题
|
||||||
var headers = new[] { "时间", "参赛项目", "参赛组别", "参赛队伍", "运动员姓名", "场次", "场地" };
|
var headers = new[] { "时间", "参赛项目", "参赛组别", "参赛队伍", "运动员姓名", "单位", "场次", "场地" };
|
||||||
var headerColor = Color.FromArgb(204, 255, 204);
|
var headerColor = Color.FromArgb(204, 255, 204);
|
||||||
SetHeaders(headers, 2, headerColor, 11);
|
SetHeaders(headers, 2, headerColor, 11);
|
||||||
|
|
||||||
@ -460,10 +522,11 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
|||||||
Worksheet.Cells[rowIndex, 3].Value = item.GroupName;
|
Worksheet.Cells[rowIndex, 3].Value = item.GroupName;
|
||||||
Worksheet.Cells[rowIndex, 4].Value = item.TeamName ?? "";
|
Worksheet.Cells[rowIndex, 4].Value = item.TeamName ?? "";
|
||||||
Worksheet.Cells[rowIndex, 5].Value = item.AthleteName;
|
Worksheet.Cells[rowIndex, 5].Value = item.AthleteName;
|
||||||
Worksheet.Cells[rowIndex, 6].Value = item.SessionIndex;
|
Worksheet.Cells[rowIndex, 6].Value = item.UnitName;
|
||||||
Worksheet.Cells[rowIndex, 7].Value = item.VenueIndex;
|
Worksheet.Cells[rowIndex, 7].Value = item.SessionIndex;
|
||||||
|
Worksheet.Cells[rowIndex, 8].Value = item.VenueIndex;
|
||||||
|
|
||||||
SetDataRowStyle(rowIndex, 7, alternateBgColor, i % 2 == 1);
|
SetDataRowStyle(rowIndex, 8, alternateBgColor, i % 2 == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理最后一个项目的合并
|
// 处理最后一个项目的合并
|
||||||
@ -484,7 +547,7 @@ public class EventArrangementService : BaseService<YD_Event.Core.Entities.Projec
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置列宽
|
// 设置列宽
|
||||||
var widths = new double[] { 12, 18, 15, 25, 15, 8, 8 };
|
var widths = new double[] { 12, 18, 15, 25, 15, 20, 8, 8 };
|
||||||
SetColumnWidths(widths);
|
SetColumnWidths(widths);
|
||||||
|
|
||||||
// 设置行高
|
// 设置行高
|
||||||
|
|||||||
@ -187,30 +187,35 @@ public class PointsRecordService : BaseService<PointsRecord>, ITransient
|
|||||||
}
|
}
|
||||||
else // 单位用户
|
else // 单位用户
|
||||||
{
|
{
|
||||||
// 单位用户现在应该查询 MerchantCertification 表
|
// 单位用户:查询SysUser,关联MerchantCertification
|
||||||
var query = _db.Queryable<MerchantCertification>()
|
var query = _db.Queryable<SysUser>()
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), m =>
|
.InnerJoin<MerchantCertification>((s, m) => s.Id == m.UserId && !m.DeleteMark)
|
||||||
m.MerchantName.Contains(input.Keyword) ||
|
.Where((s, m) => !s.DeleteMark)
|
||||||
|
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), (s, m) =>
|
||||||
|
s.Name.Contains(input.Keyword) ||
|
||||||
|
m.MerchantName.Contains(input.Keyword) ||
|
||||||
m.ContactPhone.Contains(input.Keyword));
|
m.ContactPhone.Contains(input.Keyword));
|
||||||
|
|
||||||
var result = await query
|
var result = await query
|
||||||
.Select(m => new PointsRecordListOutput
|
.Select((s, m) => new PointsRecordListOutput
|
||||||
{
|
{
|
||||||
UserId = m.Id, // 单位认证ID
|
UserId = m.Id, // 使用MerchantCertificationId作为标识
|
||||||
UserType = 1,
|
UserType = 1,
|
||||||
Name = m.MerchantName,
|
Name = m.MerchantName, // 显示单位名称
|
||||||
Phone = m.ContactPhone,
|
Phone = m.ContactPhone,
|
||||||
IdentityInfo = m.CreditCode, // 统一社会信用代码
|
IdentityInfo = m.CreditCode, // 统一社会信用代码
|
||||||
TotalPoints = SqlFunc.Subqueryable<PointsRecord>()
|
TotalPoints = SqlFunc.Subqueryable<PointsRecord>()
|
||||||
.Where(p => p.MerchantCertificationId == m.Id && !p.DeleteMark)
|
.InnerJoin<YD_Event.Core.Entities.AppUser>((p, a) => p.UserId == a.Id && !a.DeleteMark)
|
||||||
.WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime)
|
.Where((p, a) => a.MerchantCertificationId == m.Id && !p.DeleteMark)
|
||||||
.WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime)
|
.WhereIF(input.StartTime.HasValue, (p, a) => p.CreatedTime >= input.StartTime)
|
||||||
.Sum(p => p.Points),
|
.WhereIF(input.EndTime.HasValue, (p, a) => p.CreatedTime <= input.EndTime)
|
||||||
|
.Sum((p, a) => p.Points),
|
||||||
LastUpdateTime = SqlFunc.Subqueryable<PointsRecord>()
|
LastUpdateTime = SqlFunc.Subqueryable<PointsRecord>()
|
||||||
.Where(p => p.MerchantCertificationId == m.Id && !p.DeleteMark)
|
.InnerJoin<YD_Event.Core.Entities.AppUser>((p, a) => p.UserId == a.Id && !a.DeleteMark)
|
||||||
.WhereIF(input.StartTime.HasValue, p => p.CreatedTime >= input.StartTime)
|
.Where((p, a) => a.MerchantCertificationId == m.Id && !p.DeleteMark)
|
||||||
.WhereIF(input.EndTime.HasValue, p => p.CreatedTime <= input.EndTime)
|
.WhereIF(input.StartTime.HasValue, (p, a) => p.CreatedTime >= input.StartTime)
|
||||||
.Max(p => p.CreatedTime)
|
.WhereIF(input.EndTime.HasValue, (p, a) => p.CreatedTime <= input.EndTime)
|
||||||
|
.Max((p, a) => p.CreatedTime)
|
||||||
})
|
})
|
||||||
.MergeTable()
|
.MergeTable()
|
||||||
.WhereIF(input.StartTime.HasValue || input.EndTime.HasValue, x => x.LastUpdateTime != null)
|
.WhereIF(input.StartTime.HasValue || input.EndTime.HasValue, x => x.LastUpdateTime != null)
|
||||||
@ -229,17 +234,16 @@ public class PointsRecordService : BaseService<PointsRecord>, ITransient
|
|||||||
[HttpGet("detail/{userId}")]
|
[HttpGet("detail/{userId}")]
|
||||||
public async Task<PageResult<PointsDetailOutput>> Detail([FromQuery] PointsDetailQueryInput input)
|
public async Task<PageResult<PointsDetailOutput>> Detail([FromQuery] PointsDetailQueryInput input)
|
||||||
{
|
{
|
||||||
var query = _repository.AsQueryable()
|
|
||||||
.LeftJoin<EventInfo>((p, e) => p.EventId == e.Id)
|
|
||||||
.LeftJoin<YD_Event.Core.Entities.Project>((p, e, pr) => p.ProjectId == pr.Id)
|
|
||||||
.LeftJoin<ProjectGroup>((p, e, pr, pg) => p.ProjectGroupId == pg.Id)
|
|
||||||
.Where((p, e, pr, pg) => !p.DeleteMark)
|
|
||||||
.WhereIF(input.Type.HasValue, (p, e, pr, pg) => p.Type == input.Type)
|
|
||||||
.OrderByDescending((p, e, pr, pg) => p.CreatedTime);
|
|
||||||
|
|
||||||
if (input.UserType == 0) // 普通用户
|
if (input.UserType == 0) // 普通用户
|
||||||
{
|
{
|
||||||
query = query.Where((p, e, pr, pg) => p.UserId == input.UserId);
|
var query = _repository.AsQueryable()
|
||||||
|
.LeftJoin<EventInfo>((p, e) => p.EventId == e.Id)
|
||||||
|
.LeftJoin<YD_Event.Core.Entities.Project>((p, e, pr) => p.ProjectId == pr.Id)
|
||||||
|
.LeftJoin<ProjectGroup>((p, e, pr, pg) => p.ProjectGroupId == pg.Id)
|
||||||
|
.Where((p, e, pr, pg) => !p.DeleteMark)
|
||||||
|
.Where((p, e, pr, pg) => p.UserId == input.UserId)
|
||||||
|
.WhereIF(input.Type.HasValue, (p, e, pr, pg) => p.Type == input.Type)
|
||||||
|
.OrderByDescending((p, e, pr, pg) => p.CreatedTime);
|
||||||
|
|
||||||
return await query
|
return await query
|
||||||
.Select((p, e, pr, pg) => new PointsDetailOutput
|
.Select((p, e, pr, pg) => new PointsDetailOutput
|
||||||
@ -256,11 +260,19 @@ public class PointsRecordService : BaseService<PointsRecord>, ITransient
|
|||||||
}
|
}
|
||||||
else // 单位用户
|
else // 单位用户
|
||||||
{
|
{
|
||||||
// 单位用户:查询 MerchantCertificationId = userId 的记录
|
// 单位用户:查询该单位认证下所有AppUser的积分记录
|
||||||
query = query.Where((p, e, pr, pg) => p.MerchantCertificationId == input.UserId);
|
// input.UserId 在这里是 MerchantCertificationId
|
||||||
|
var query = _repository.AsQueryable()
|
||||||
|
.LeftJoin<EventInfo>((p, e) => p.EventId == e.Id)
|
||||||
|
.LeftJoin<YD_Event.Core.Entities.Project>((p, e, pr) => p.ProjectId == pr.Id)
|
||||||
|
.LeftJoin<ProjectGroup>((p, e, pr, pg) => p.ProjectGroupId == pg.Id)
|
||||||
|
.InnerJoin<YD_Event.Core.Entities.AppUser>((p, e, pr, pg, u) => p.UserId == u.Id && !u.DeleteMark)
|
||||||
|
.Where((p, e, pr, pg, u) => !p.DeleteMark)
|
||||||
|
.Where((p, e, pr, pg, u) => u.MerchantCertificationId == input.UserId)
|
||||||
|
.WhereIF(input.Type.HasValue, (p, e, pr, pg, u) => p.Type == input.Type)
|
||||||
|
.OrderByDescending((p, e, pr, pg, u) => p.CreatedTime);
|
||||||
|
|
||||||
return await query
|
return await query
|
||||||
.LeftJoin<YD_Event.Core.Entities.AppUser>((p, e, pr, pg, u) => p.UserId == u.Id)
|
|
||||||
.Select((p, e, pr, pg, u) => new PointsDetailOutput
|
.Select((p, e, pr, pg, u) => new PointsDetailOutput
|
||||||
{
|
{
|
||||||
CreatedTime = p.CreatedTime,
|
CreatedTime = p.CreatedTime,
|
||||||
|
|||||||
@ -794,7 +794,12 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ConfigurePdfFonts">
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ConfigurePdfFonts">
|
||||||
<summary>
|
<summary>
|
||||||
配置 PDF 字体 - 简化版,主要依赖系统预装字体
|
配置 PDF 字体 - 跨平台解决方案
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.ConfigureChineseFonts">
|
||||||
|
<summary>
|
||||||
|
配置中文字体
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.GeneratePdf(YD_Event.Application.Certificate.Dtos.GeneratePdfCertificateInput)">
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.GeneratePdf(YD_Event.Application.Certificate.Dtos.GeneratePdfCertificateInput)">
|
||||||
@ -905,6 +910,11 @@
|
|||||||
使用QuestPDF生成PDF
|
使用QuestPDF生成PDF
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.GetAvailableChineseFontName">
|
||||||
|
<summary>
|
||||||
|
获取可用的中文字体名称
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.DetermineParagraphStyle(DocumentFormat.OpenXml.Wordprocessing.Paragraph)">
|
<member name="M:YD_Event.Application.Certificate.CertificateGenerateService.DetermineParagraphStyle(DocumentFormat.OpenXml.Wordprocessing.Paragraph)">
|
||||||
<summary>
|
<summary>
|
||||||
确定段落样式
|
确定段落样式
|
||||||
@ -4240,6 +4250,11 @@
|
|||||||
运动员名称
|
运动员名称
|
||||||
</summary>
|
</summary>
|
||||||
</member>
|
</member>
|
||||||
|
<member name="P:YD_Event.Application.Event.Dtos.ArrangementPreviewOutput.UnitName">
|
||||||
|
<summary>
|
||||||
|
单位名称
|
||||||
|
</summary>
|
||||||
|
</member>
|
||||||
<member name="P:YD_Event.Application.Event.Dtos.ArrangementPreviewOutput.SessionIndex">
|
<member name="P:YD_Event.Application.Event.Dtos.ArrangementPreviewOutput.SessionIndex">
|
||||||
<summary>
|
<summary>
|
||||||
场次索引
|
场次索引
|
||||||
|
|||||||
@ -6,10 +6,12 @@ FROM mcr.microsoft.com/dotnet/aspnet:10.0 AS base
|
|||||||
#修改apt-get源,加速apt下载
|
#修改apt-get源,加速apt下载
|
||||||
RUN sed -i s@/deb.debian.org/@/mirrors.163.com/@g /etc/apt/sources.list.d/debian.sources
|
RUN sed -i s@/deb.debian.org/@/mirrors.163.com/@g /etc/apt/sources.list.d/debian.sources
|
||||||
#RUN cat /etc/apt/sources.list
|
#RUN cat /etc/apt/sources.list
|
||||||
#安装fontconfig
|
#安装fontconfig和中文字体
|
||||||
RUN apt-get clean
|
RUN apt-get clean
|
||||||
RUN apt-get update
|
RUN apt-get update
|
||||||
RUN apt-get install -y fontconfig
|
RUN apt-get install -y fontconfig fonts-wqy-microhei fonts-wqy-zenhei fonts-noto-cjk
|
||||||
|
# 刷新字体缓存
|
||||||
|
RUN fc-cache -fv
|
||||||
|
|
||||||
USER $APP_UID
|
USER $APP_UID
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user