142 lines
5.6 KiB
C#
142 lines
5.6 KiB
C#
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 totalProjectPrice = 0;
|
||
|
||
foreach (var project in input.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 * input.ParticipantCount;
|
||
result.TotalAmount = totalAmount;
|
||
|
||
result.Details.Add(new PricingDetailItem
|
||
{
|
||
ItemName = input.ParticipantCount == 1 ? "项目总价" : "项目总价 × 人数",
|
||
UnitPrice = totalProjectPrice,
|
||
Quantity = input.ParticipantCount,
|
||
Subtotal = totalAmount,
|
||
Remark = input.ParticipantCount == 1
|
||
? $"个人参赛,项目总价 {totalProjectPrice:F2} 元"
|
||
: $"团队参赛,({totalProjectPrice:F2} 元) × {input.ParticipantCount} 人"
|
||
});
|
||
result.CalculationLogs.Add($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 单价(项目)模式: 项目总价 {totalProjectPrice:F2} 元 × {input.ParticipantCount} 人 = {totalAmount:F2} 元");
|
||
}
|
||
}
|