activeMap[$userId] = $isActive; } public function isActive($agent, $atTime = null) { $userId = is_array($agent) ? ($agent['user_id'] ?? 0) : ($agent->user_id ?? 0); if (isset($this->activeMap[$userId])) { return $this->activeMap[$userId]; } return true; // 默认均活跃 } } class MakerPeerTest { private $passed = 0; private $failed = 0; public function run() { echo "========================================================\n"; echo " 创客两代平级级联收益计算测试 (Maker Peer Cascading) \n"; echo "========================================================\n\n"; $this->testThreePeerCascade(); $this->testFourPeerCapLimit(); $this->testInactiveIntermediaryCascade(); $this->testV1PeerCascade(); $this->testMultiSegmentPeers(); echo "\n--------------------------------------------------------\n"; echo "测试执行结果: 通过 {$this->passed} 项, 失败 {$this->failed} 项\n"; echo "========================================================\n"; return $this->failed === 0 ? 0 : 1; } private function assert($condition, $testName, $detail = '') { if ($condition) { echo " [PASS] {$testName}\n"; $this->passed++; } else { echo " [FAIL] {$testName} - {$detail}\n"; $this->failed++; } } /** * 测试 1:经典 3 平级创客(A -> B -> C,均为基数 60 的 V3) * 规则验证: * A(2): 实拿极差全额 60.00 * B(3): 第1代平级 60 * 10% = 6.00 * C(4): 第2代平级 6 * 10% = 0.60 */ public function testThreePeerCascade() { $testName = "场景1: 3个平级创客(A->B->C, V3) 第1代拿6元,第2代拿0.60元"; Db::startTrans(); try { $order = ['id' => 9901, 'user_id' => 7]; $buyerId = 7; // 关系链:买家(7) -> A(2, V3/level 4) -> B(3, V3/level 4) -> C(4, V3/level 4) $chain = [ ['user_id' => 2, 'level' => 4], // Level 4 基数 60 (V3) ['user_id' => 3, 'level' => 4], ['user_id' => 4, 'level' => 4], ]; $diffResult = [ 'seen' => 60.0, 'paid' => [ ['user_id' => 2, 'level' => 4, 'cap' => 60.0, 'amount' => 60.0] ] ]; $active = new MockActiveService(); $reward = new MakerPeerReward(); $reward->run($order, $buyerId, $chain, $diffResult, $active); $records = Db::name('shopro_partner_reward') ->where('order_id', 9901) ->where('reward_type', 'maker_peer') ->order('id asc') ->select(); $bReward = null; $cReward = null; foreach ($records as $r) { if ($r['user_id'] == 3) $bReward = $r; if ($r['user_id'] == 4) $cReward = $r; } $bAmount = $bReward ? floatval($bReward['amount']) : 0; $cAmount = $cReward ? floatval($cReward['amount']) : 0; $bExt = $bReward ? json_decode($bReward['ext'], true) : []; $cExt = $cReward ? json_decode($cReward['ext'], true) : []; $bPass = ($bAmount == 6.00) && (($bExt['generation'] ?? 0) == 1); $cPass = ($cAmount == 0.60) && (($cExt['generation'] ?? 0) == 2); $this->assert($bPass && $cPass, $testName, "B金额={$bAmount}(期6.00), C金额={$cAmount}(期0.60)"); } catch (\Exception $e) { $this->assert(false, $testName, "异常: " . $e->getMessage()); } finally { Db::rollback(); } } /** * 测试 2:4 平级创客深度封顶(A -> B -> C -> D,均为 V3) * 规则验证: * 第3代创客 D 应严格封顶截断,不产生任何平级奖记录 */ public function testFourPeerCapLimit() { $testName = "场景2: 4个平级创客(A->B->C->D) 第3代D严格封顶截断不分佣"; Db::startTrans(); try { $order = ['id' => 9902, 'user_id' => 7]; $buyerId = 7; $chain = [ ['user_id' => 2, 'level' => 4], ['user_id' => 3, 'level' => 4], ['user_id' => 4, 'level' => 4], ['user_id' => 5, 'level' => 4], ]; $diffResult = [ 'seen' => 60.0, 'paid' => [ ['user_id' => 2, 'level' => 4, 'cap' => 60.0, 'amount' => 60.0] ] ]; $active = new MockActiveService(); $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(); $this->assert(empty($dReward), $testName, "第3代平级创客D应无平级奖记录"); } catch (\Exception $e) { $this->assert(false, $testName, "异常: " . $e->getMessage()); } finally { Db::rollback(); } } /** * 测试 3:中间创客未自购场景(A -> B(不活跃) -> C(活跃)) * 规则验证: * B 产生 skip 记录(status=-1, skip_reason=inactive_30d) * C 仍然作为合格第2代拿到 0.60 元 */ public function testInactiveIntermediaryCascade() { $testName = "场景3: 中间平级B 30日无自购被跳过,上级C仍正常获得第2代平级0.60元"; Db::startTrans(); try { $order = ['id' => 9903, 'user_id' => 7]; $buyerId = 7; $chain = [ ['user_id' => 2, 'level' => 4], ['user_id' => 3, 'level' => 4], ['user_id' => 4, 'level' => 4], ]; $diffResult = [ 'seen' => 60.0, 'paid' => [ ['user_id' => 2, 'level' => 4, 'cap' => 60.0, 'amount' => 60.0] ] ]; $active = new MockActiveService(); $active->setActive(3, false); // B 不活跃 $active->setActive(4, true); // C 活跃 $reward = new MakerPeerReward(); $reward->run($order, $buyerId, $chain, $diffResult, $active); $bSkip = Db::name('shopro_partner_reward') ->where('order_id', 9903) ->where('user_id', 3) ->where('status', -1) ->find(); $cReward = Db::name('shopro_partner_reward') ->where('order_id', 9903) ->where('user_id', 4) ->where('status', 1) ->find(); $bSkipped = !empty($bSkip) && floatval($bSkip['amount']) == 0; $cReceived = !empty($cReward) && floatval($cReward['amount']) == 0.60; $this->assert($bSkipped && $cReceived, $testName, "B被跳过记录, C正常结算0.60元"); } catch (\Exception $e) { $this->assert(false, $testName, "异常: " . $e->getMessage()); } finally { Db::rollback(); } } /** * 测试 4:V1 等级(level 2,基数 20 元)两代级联 * 规则验证: * A(2): 极差 20.00 * B(3): 第1代 20 * 10% = 2.00 * C(4): 第2代 2 * 10% = 0.20 */ public function testV1PeerCascade() { $testName = "场景4: V1等级(基数20元)两代级联 B得2.00元, C得0.20元"; Db::startTrans(); try { $order = ['id' => 9904, 'user_id' => 7]; $buyerId = 7; $chain = [ ['user_id' => 2, 'level' => 2], // Level 2 基数 20 (V1) ['user_id' => 3, 'level' => 2], ['user_id' => 4, 'level' => 2], ]; $diffResult = [ 'seen' => 20.0, 'paid' => [ ['user_id' => 2, 'level' => 2, 'cap' => 20.0, 'amount' => 20.0] ] ]; $active = new MockActiveService(); $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(); $bAmount = $bReward ? floatval($bReward['amount']) : 0; $cAmount = $cReward ? floatval($cReward['amount']) : 0; $this->assert($bAmount == 2.00 && $cAmount == 0.20, $testName, "B金额={$bAmount}(期2.00), C金额={$cAmount}(期0.20)"); } catch (\Exception $e) { $this->assert(false, $testName, "异常: " . $e->getMessage()); } finally { Db::rollback(); } } /** * 测试 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() { $testName = "场景5: 混合等级链条多段平级互不干扰独立级联"; Db::startTrans(); try { $order = ['id' => 9905, 'user_id' => 7]; $buyerId = 7; $chain = [ ['user_id' => 2, 'level' => 2], // V1 ['user_id' => 3, 'level' => 2], // V1 ['user_id' => 4, 'level' => 4], // V3 ['user_id' => 5, 'level' => 4], // V3 ['user_id' => 6, 'level' => 4], // V3 ]; $diffResult = [ 'seen' => 60.0, 'paid' => [ ['user_id' => 2, 'level' => 2, 'cap' => 20.0, 'amount' => 20.0], ['user_id' => 4, 'level' => 4, 'cap' => 60.0, 'amount' => 40.0] ] ]; $active = new MockActiveService(); $reward = new MakerPeerReward(); $reward->run($order, $buyerId, $chain, $diffResult, $active); $bReward = Db::name('shopro_partner_reward')->where('order_id', 9905)->where('user_id', 3)->find(); $dReward = Db::name('shopro_partner_reward')->where('order_id', 9905)->where('user_id', 5)->find(); $eReward = Db::name('shopro_partner_reward')->where('order_id', 9905)->where('user_id', 6)->find(); $bAmount = $bReward ? floatval($bReward['amount']) : 0; $dAmount = $dReward ? floatval($dReward['amount']) : 0; $eAmount = $eReward ? floatval($eReward['amount']) : 0; $this->assert( $bAmount == 2.00 && $dAmount == 6.00 && $eAmount == 0.60, $testName, "B(V1平级1)={$bAmount}(期2.00), D(V3平级1)={$dAmount}(期6.00), E(V3平级2)={$eAmount}(期0.60)" ); } catch (\Exception $e) { $this->assert(false, $testName, "异常: " . $e->getMessage()); } finally { Db::rollback(); } } } // 执行测试 if (php_sapi_name() === 'cli') { $tester = new MakerPeerTest(); exit($tester->run()); }