using YD_Event.Core.Enum; namespace YD_Event.Core.Domain.Pricing; /// /// 赛事定价计算服务 /// 所有金额计算均以此服务为准,确保计算结果的一致性 /// public static class EventPricingService { /// /// 赛事基础定价(元) /// public const decimal EventBasePrice = 1000m; /// /// 项目A定价(元) /// public const decimal ProjectAPrice = 500m; /// /// 项目B定价(元) /// public const decimal ProjectBPrice = 1000m; /// /// 定价计算输入参数 /// public class PricingInput { /// /// 收费模式 /// public ChargeMode ChargeMode { get; set; } /// /// 参赛人数 /// public int ParticipantCount { get; set; } /// /// 项目列表(单价项目模式使用) /// public List Projects { get; set; } = new List(); } /// /// 项目定价信息 /// public class ProjectPricingInfo { /// /// 项目ID /// public long ProjectId { get; set; } /// /// 项目名称 /// public string ProjectName { get; set; } = string.Empty; /// /// 项目单价(元) /// public decimal UnitPrice { get; set; } } /// /// 定价计算结果 /// public class PricingResult { /// /// 总金额(精确到分) /// public decimal TotalAmount { get; set; } /// /// 总人数 /// public int TotalPersonCount { get; set; } /// /// 费用明细 /// public List Details { get; set; } = new List(); /// /// 计算日志(用于审计) /// public List CalculationLogs { get; set; } = new List(); } /// /// 费用明细项 /// public class PricingDetailItem { /// /// 项目名称 /// public string ItemName { get; set; } = string.Empty; /// /// 单价 /// public decimal UnitPrice { get; set; } /// /// 数量 /// public int Quantity { get; set; } /// /// 小计 /// public decimal Subtotal { get; set; } /// /// 备注 /// public string? Remark { get; set; } } /// /// 计算赛事报名费用 /// /// 定价计算输入 /// 定价计算结果 public static PricingResult Calculate(PricingInput input) { var result = new PricingResult { TotalPersonCount = input.ParticipantCount }; result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 开始计算费用,收费模式: {input.ChargeMode}, 人数: {input.ParticipantCount}"); switch (input.ChargeMode) { case ChargeMode.Free: CalculateFreeMode(result); break; case ChargeMode.FixedPrice: CalculateFixedPriceMode(result, input.ParticipantCount); break; case ChargeMode.UnitPriceEvent: CalculateUnitPriceEventMode(result, input.ParticipantCount); break; case ChargeMode.UnitPriceProject: CalculateUnitPriceProjectMode(result, input.Projects, input.ParticipantCount); break; } // 确保金额精确到分 result.TotalAmount = Math.Round(result.TotalAmount, 2, MidpointRounding.AwayFromZero); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 最终总金额: {result.TotalAmount:F2} 元"); return result; } /// /// 免费模式 /// private static void CalculateFreeMode(PricingResult result) { result.TotalAmount = 0; result.Details.Add(new PricingDetailItem { ItemName = "报名费", UnitPrice = 0, Quantity = 1, Subtotal = 0, Remark = "免费" }); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 免费模式,总金额: 0 元"); } /// /// 定价(赛事)模式:固定为1000元/场,无论参赛主体是个人还是单位,也无论参赛项目数量多少,均统一按1000元计算 /// private static void CalculateFixedPriceMode(PricingResult result, int participantCount) { var price = EventBasePrice; result.TotalAmount = price; result.Details.Add(new PricingDetailItem { ItemName = "赛事报名费", UnitPrice = price, Quantity = 1, Subtotal = price, Remark = $"固定价格 {EventBasePrice:F2} 元/场,参赛人数: {participantCount} 人" }); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 定价(赛事)模式: 固定价格 {EventBasePrice:F2} 元/场"); } /// /// 单价(赛事)模式:赛事基础定价为1000元,个人参赛按1000元计算;团队参赛按人数乘以1000元计算 /// private static void CalculateUnitPriceEventMode(PricingResult result, int participantCount) { var unitPrice = EventBasePrice; var totalAmount = unitPrice * participantCount; result.TotalAmount = totalAmount; result.Details.Add(new PricingDetailItem { ItemName = "赛事报名费", UnitPrice = unitPrice, Quantity = participantCount, Subtotal = totalAmount, Remark = participantCount == 1 ? $"个人参赛 {unitPrice:F2} 元" : $"团队参赛 {unitPrice:F2} 元/人 × {participantCount} 人" }); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 单价(赛事)模式: {unitPrice:F2} 元/人 × {participantCount} 人 = {totalAmount:F2} 元"); } /// /// 单价(项目)模式:按具体项目定价计算,个人参加多项时,费用为各项单价之和;团队参加多项时,费用为(各项单价之和)×团队人数 /// private static void CalculateUnitPriceProjectMode(PricingResult result, List projects, int participantCount) { decimal totalProjectPrice = 0; foreach (var project in projects) { totalProjectPrice += project.UnitPrice; result.Details.Add(new PricingDetailItem { ItemName = project.ProjectName, UnitPrice = project.UnitPrice, Quantity = 1, Subtotal = project.UnitPrice, Remark = "项目单价" }); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 项目: {project.ProjectName}, 单价: {project.UnitPrice:F2} 元"); } var totalAmount = totalProjectPrice * participantCount; result.TotalAmount = totalAmount; // 添加汇总项 result.Details.Add(new PricingDetailItem { ItemName = participantCount == 1 ? "项目总价" : "项目总价 × 人数", UnitPrice = totalProjectPrice, Quantity = participantCount, Subtotal = totalAmount, Remark = participantCount == 1 ? $"个人参赛,项目总价 {totalProjectPrice:F2} 元" : $"团队参赛,({totalProjectPrice:F2} 元) × {participantCount} 人" }); result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 单价(项目)模式: 项目总价 {totalProjectPrice:F2} 元 × {participantCount} 人 = {totalAmount:F2} 元"); } }