feat(partner): 全网平级奖支持逐代10%级联递减至0.01元截断机制

这个提交包含在:
chen
2026-09-17 14:04:28 +08:00
父节点 1f67b0a970
当前提交 5f9b407e64
共有 6 个文件被更改,包括 450 次插入 和 78 次删除

查看文件

@@ -49,11 +49,11 @@ class MakerPeerTest
public function run()
{
echo "========================================================\n";
echo " 创客两代平级级联收益计算测试 (Maker Peer Cascading) \n";
echo " 创客多代平级级联至0.01截断测试 (Maker Peer to 0.01) \n";
echo "========================================================\n\n";
$this->testThreePeerCascade();
$this->testFourPeerCapLimit();
$this->testMultiPeerUntilCentCutoff();
$this->testInactiveIntermediaryCascade();
$this->testV1PeerCascade();
$this->testMultiSegmentPeers();
@@ -139,13 +139,19 @@ class MakerPeerTest
}
/**
* 测试 2:4 平级创客深度封顶(A -> B -> C -> D,均为 V3)
* 规则验证:
* 第3代创客 D 应严格封顶截断,不产生任何平级奖记录
* 测试 2:多代平级持续向上拿,最少达到 0.01 元后截断
* 链条:买家(7) -> A(2) -> B(3) -> C(4) -> D(5) -> E(6) -> F(8) (均为 V3,基数 60)
* 计算递推:
* A: 极差 60.00
* B(3): 第1代 60 * 10% = 6.00
* C(4): 第2代 6 * 10% = 0.60
* D(5): 第3代 0.6 * 10% = 0.06
* E(6): 第4代 0.06 * 10% = 0.006 -> round 0.01 元(平台最小分币)
* F(8): 第5代 0.01 * 10% = 0.001 -> round 0.00 < 0.01,严格截断,不发放
*/
public function testFourPeerCapLimit()
public function testMultiPeerUntilCentCutoff()
{
$testName = "场景2: 4个平级创客(A->B->C->D) 第3代D严格封顶截断不分佣";
$testName = "场景2: V3创客多代平级(6.00 -> 0.60 -> 0.06 -> 0.01) 到0.01后上层截断";
Db::startTrans();
try {
@@ -156,6 +162,8 @@ class MakerPeerTest
['user_id' => 3, 'level' => 4],
['user_id' => 4, 'level' => 4],
['user_id' => 5, 'level' => 4],
['user_id' => 6, 'level' => 4],
['user_id' => 8, 'level' => 4],
];
$diffResult = [
@@ -169,13 +177,20 @@ class MakerPeerTest
$reward = new MakerPeerReward();
$reward->run($order, $buyerId, $chain, $diffResult, $active);
$dReward = Db::name('shopro_partner_reward')
->where('order_id', 9902)
->where('user_id', 5)
->where('reward_type', 'maker_peer')
->find();
$b = Db::name('shopro_partner_reward')->where('order_id', 9902)->where('user_id', 3)->find();
$c = Db::name('shopro_partner_reward')->where('order_id', 9902)->where('user_id', 4)->find();
$d = Db::name('shopro_partner_reward')->where('order_id', 9902)->where('user_id', 5)->find();
$e = Db::name('shopro_partner_reward')->where('order_id', 9902)->where('user_id', 6)->find();
$f = Db::name('shopro_partner_reward')->where('order_id', 9902)->where('user_id', 8)->find();
$this->assert(empty($dReward), $testName, "第3代平级创客D应无平级奖记录");
$bAmt = $b ? floatval($b['amount']) : 0;
$cAmt = $c ? floatval($c['amount']) : 0;
$dAmt = $d ? floatval($d['amount']) : 0;
$eAmt = $e ? floatval($e['amount']) : 0;
$pass = ($bAmt == 6.00) && ($cAmt == 0.60) && ($dAmt == 0.06) && ($eAmt == 0.01) && empty($f);
$this->assert($pass, $testName, "B={$bAmt}(6), C={$cAmt}(0.6), D={$dAmt}(0.06), E={$eAmt}(0.01), F=" . (empty($f) ? '已截断' : '未截断'));
} catch (\Exception $e) {
$this->assert(false, $testName, "异常: " . $e->getMessage());
} finally {
@@ -241,15 +256,17 @@ class MakerPeerTest
}
/**
* 测试 4:V1 等级(level 2,基数 20 元)两代级联
* 测试 4:V1 等级(level 2,基数 20 元)多代级联
* 规则验证:
* A(2): 极差 20.00
* A: 极差 20.00
* B(3): 第1代 20 * 10% = 2.00
* C(4): 第2代 2 * 10% = 0.20
* D(5): 第3代 0.2 * 10% = 0.02
* E(6): 第4代 0.02 * 10% = 0.002 -> 0.00 < 0.01 截断,不发放
*/
public function testV1PeerCascade()
{
$testName = "场景4: V1等级(基数20元)两代级联 B得2.00元, C得0.20元";
$testName = "场景4: V1等级(基数20元)多代级联 (2.00 -> 0.20 -> 0.02) 到0.01以下截断";
Db::startTrans();
try {
@@ -259,6 +276,8 @@ class MakerPeerTest
['user_id' => 2, 'level' => 2], // Level 2 基数 20 (V1)
['user_id' => 3, 'level' => 2],
['user_id' => 4, 'level' => 2],
['user_id' => 5, 'level' => 2],
['user_id' => 6, 'level' => 2],
];
$diffResult = [
@@ -272,13 +291,18 @@ class MakerPeerTest
$reward = new MakerPeerReward();
$reward->run($order, $buyerId, $chain, $diffResult, $active);
$bReward = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 3)->find();
$cReward = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 4)->find();
$b = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 3)->find();
$c = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 4)->find();
$d = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 5)->find();
$e = Db::name('shopro_partner_reward')->where('order_id', 9904)->where('user_id', 6)->find();
$bAmount = $bReward ? floatval($bReward['amount']) : 0;
$cAmount = $cReward ? floatval($cReward['amount']) : 0;
$bAmt = $b ? floatval($b['amount']) : 0;
$cAmt = $c ? floatval($c['amount']) : 0;
$dAmt = $d ? floatval($d['amount']) : 0;
$this->assert($bAmount == 2.00 && $cAmount == 0.20, $testName, "B金额={$bAmount}(期2.00), C金额={$cAmount}(期0.20)");
$pass = ($bAmt == 2.00) && ($cAmt == 0.20) && ($dAmt == 0.02) && empty($e);
$this->assert($pass, $testName, "B={$bAmt}(2), C={$cAmt}(0.2), D={$dAmt}(0.02), E=" . (empty($e) ? '已截断' : '未截断'));
} catch (\Exception $e) {
$this->assert(false, $testName, "异常: " . $e->getMessage());
} finally {
@@ -289,13 +313,6 @@ class MakerPeerTest
/**
* 测试 5:多段平级并存(V1平级 + V3平级在同一推荐链)
* 链条:买家(7) -> A(2, V1) -> B(3, V1) -> C(4, V3) -> D(5, V3) -> E(6, V3)
* diff paid: A (level 2, cap 20), C (level 4, cap 60)
* 期望:
* A(2): 极差 20.00
* B(3): V1第1代平级 = 20 * 10% = 2.00
* C(4): 极差 60 - 20 = 40.00
* D(5): V3第1代平级 = 60 * 10% = 6.00
* E(6): V3第2代平级 = 6 * 10% = 0.60
*/
public function testMultiSegmentPeers()
{