YD_Event.Admin/YD_Event.Core/Domain/Pricing/EventPricingService.cs
2026-05-08 14:50:01 +08:00

132 lines
5.0 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using YD_Event.Core.Enum;
using YD_Event.Core.Domain.Pricing.Models;
namespace YD_Event.Core.Domain.Pricing;
/// <summary>
/// 赛事定价计算服务
/// 所有金额计算均以此服务为准,确保计算结果的一致性
/// </summary>
public static class EventPricingService
{
/// <summary>
/// 计算赛事报名费用
/// </summary>
/// <param name="input">定价计算输入</param>
/// <returns>定价计算结果</returns>
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);
break;
case ChargeMode.UnitPriceEvent:
CalculateUnitPriceEventMode(result, input);
break;
case ChargeMode.UnitPriceProject:
CalculateUnitPriceProjectMode(result, input);
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;
}
/// <summary>
/// 免费模式
/// </summary>
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 元");
}
/// <summary>
/// 定价(赛事)模式:固定为赛事设定价格/场,无论参赛主体是个人还是单位,也无论参赛项目数量多少,均统一按固定价格计算
/// </summary>
private static void CalculateFixedPriceMode(PricingResult result, PricingInput input)
{
var price = input.EventPrice;
result.TotalAmount = price;
result.Details.Add(new PricingDetailItem
{
ItemName = "赛事报名费",
UnitPrice = price,
Quantity = 1,
Subtotal = price,
Remark = $"固定价格 {price:F2} 元/场,参赛人数: {input.ParticipantCount} 人"
});
result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 定价(赛事)模式: 固定价格 {price:F2} 元/场");
}
/// <summary>
/// 单价(赛事)模式:按照赛事设定的单价乘以实际报名人数计算总金额
/// </summary>
private static void CalculateUnitPriceEventMode(PricingResult result, PricingInput input)
{
var unitPrice = input.EventPrice;
var totalAmount = unitPrice * input.ParticipantCount;
result.TotalAmount = totalAmount;
result.Details.Add(new PricingDetailItem
{
ItemName = "赛事报名费",
UnitPrice = unitPrice,
Quantity = input.ParticipantCount,
Subtotal = totalAmount,
Remark = input.ParticipantCount == 1
? $"个人参赛 {unitPrice:F2} 元"
: $"团队参赛 {unitPrice:F2} 元/人 × {input.ParticipantCount} 人"
});
result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 单价(赛事)模式: {unitPrice:F2} 元/人 × {input.ParticipantCount} 人 = {totalAmount:F2} 元");
}
/// <summary>
/// 单价(项目)模式:根据每个项目的单独定价和报名人数进行计算。
/// 每个项目独立计算:项目单价 × 对应人数,然后累加所有项目的金额
/// </summary>
private static void CalculateUnitPriceProjectMode(PricingResult result, PricingInput input)
{
decimal totalAmount = 0;
foreach (var project in input.Projects)
{
var subtotal = project.UnitPrice * project.Quantity;
totalAmount += subtotal;
result.Details.Add(new PricingDetailItem
{
ItemName = project.ProjectName,
UnitPrice = project.UnitPrice,
Quantity = project.Quantity,
Subtotal = subtotal,
Remark = "项目单价"
});
result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 项目: {project.ProjectName}, 单价: {project.UnitPrice:F2} 元, 人数: {project.Quantity}, 小计: {subtotal:F2} 元");
}
result.TotalAmount = totalAmount;
result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 单价(项目)模式: 总金额 {totalAmount:F2} 元");
}
}