为Transfer模块的手续费计算创建事件机制,允许其他模块监听手续费计算过程并修改手续费数额,提供灵活的扩展能力。
2025-06-18 23:55
创建了完整的手续费事件系统,支持:
class FeeCalculatingEvent
{
// 核心属性
public TransferApp $app; // 划转应用
public string $amount; // 原始金额
public string $type; // 手续费类型('in'/'out')
public float $feeRate; // 手续费率
public string $feeAmount; // 手续费金额
public string $actualAmount; // 实际到账金额
public bool $isModified; // 是否被修改
public ?string $modificationReason; // 修改原因
public ?string $modifiedBy; // 修改者标识
public array $context; // 上下文数据
// 修改方法
public function modifyFeeAmount(string $newFeeAmount, string $reason, string $modifiedBy)
public function modifyFeeRate(float $newFeeRate, string $reason, string $modifiedBy)
public function setFree(string $reason, string $modifiedBy)
public function addFee(string $additionalFee, string $reason, string $modifiedBy)
public function reduceFee(string $discountFee, string $reason, string $modifiedBy)
}
private static function calculateFeeWithEvents(TransferApp $app, string $amount, string $type, array $context = []): array
{
// 计算基础手续费
$baseResult = self::calculateFee($amount, $feeRate, $minFee, $maxFee);
// 创建并触发事件
$event = new FeeCalculatingEvent($app, $amount, $type, ...);
Event::dispatch($event);
// 获取最终结果
$finalResult = $event->getResult();
// 触发完成事件
Event::dispatch(FeeCalculatedEvent::fromCalculatingEvent($event));
return $finalResult;
}
class FeeCalculatingListener
{
public function handle(FeeCalculatingEvent $event): void
{
// VIP用户优惠
$this->handleVipDiscount($event);
// 大额交易优惠
$this->handleLargeAmountDiscount($event);
// 合作伙伴免费
$this->handleSpecialAppFee($event);
// 节假日优惠
$this->handleHolidayDiscount($event);
}
}
📋 测试1: 小额交易 (30.00)
🎯 监听到手续费计算事件:
应用ID: 2, 金额: 30.00, 类型: out
原始手续费: 0.5000
ℹ️ 无折扣条件
结果: 手续费 0.5000, 实际到账 29.5000
修改状态: 未修改
📋 测试2: 大额交易 (100.00)
🎯 监听到手续费计算事件:
应用ID: 2, 金额: 100.00, 类型: out
原始手续费: 1.0000
✅ 应用折扣: -0.5000
最终手续费: 0.5000
结果: 手续费 0.5000, 实际到账 99.5000
修改状态: 已修改
修改原因: 大额交易50%折扣
修改者: TestListener
📋 测试3: 转入手续费 (80.00)
🎯 监听到手续费计算事件:
应用ID: 2, 金额: 80.00, 类型: in
原始手续费: 0.4000
✅ 应用折扣: -0.2000
最终手续费: 0.2000
结果: 手续费 0.2000, 实际到账 79.8000
修改状态: 已修改
修改原因: 大额交易50%折扣
修改者: TestListener
if ($this->checkUserVipStatus($userId)) {
$discountAmount = bcmul($event->feeAmount, '0.5', 4);
$event->reduceFee($discountAmount, 'VIP用户50%手续费减免', 'VipDiscountService');
}
if (bccomp($event->amount, '1000.0000', 4) >= 0) {
if (bccomp($event->feeAmount, '10.0000', 4) > 0) {
$event->modifyFeeAmount('10.0000', '大额交易手续费上限', 'LargeAmountService');
}
}
if (in_array($event->app->id, $specialAppIds)) {
$event->setFree('合作伙伴应用免手续费', 'PartnerAppService');
}
if ($this->isHoliday()) {
$discountAmount = bcmul($event->feeAmount, '0.2', 4);
$event->reduceFee($discountAmount, '节假日手续费8折优惠', 'HolidayDiscountService');
}
$marketRate = $this->marketService->getCurrentFeeRate();
if ($marketRate !== $event->feeRate) {
$event->modifyFeeRate($marketRate, '市场动态调整', 'MarketService');
}
// 计算手续费(自动触发事件)
$result = TransferService::calculateOutFee(
transferAppId: 1,
amount: '100.00',
context: ['user_id' => 12345, 'source' => 'mobile_app']
);
// 检查是否被修改
if ($result['is_modified']) {
echo "手续费被修改: {$result['modification_reason']}";
}
// 在ServiceProvider中注册
Event::listen(FeeCalculatingEvent::class, YourFeeListener::class);
class YourFeeListener
{
public function handle(FeeCalculatingEvent $event): void
{
// 检查业务条件
if ($this->shouldApplyDiscount($event)) {
$event->reduceFee('1.0000', '特殊优惠', 'YourModule');
}
}
}
Transfer模块手续费事件机制实现完全成功,提供了:
这个事件机制大大提升了Transfer模块的扩展性和灵活性,允许其他模块根据业务需求实现各种复杂的手续费策略,同时保持了代码的模块化和可维护性。