301 行
12 KiB
PHP
301 行
12 KiB
PHP
<?php
|
||
|
||
namespace tests\partner;
|
||
|
||
// 引导 ThinkPHP 环境
|
||
define('APP_PATH', __DIR__ . '/../../application/');
|
||
define('ROOT_PATH', dirname(realpath(APP_PATH)) . '/');
|
||
require_once __DIR__ . '/../../thinkphp/base.php';
|
||
require_once __DIR__ . '/../../thinkphp/helper.php';
|
||
require_once __DIR__ . '/../../application/common.php';
|
||
|
||
\think\Config::set(include APP_PATH . 'database.php', 'database');
|
||
\think\Loader::addNamespace('app', APP_PATH);
|
||
require_once __DIR__ . '/../../addons/shopro/helper/helper.php';
|
||
|
||
use addons\shopro\service\partner\PeerShareReward;
|
||
use addons\shopro\service\partner\ActiveService;
|
||
use addons\shopro\service\partner\PartnerRewardService;
|
||
use addons\shopro\service\partner\PartnerConfig;
|
||
use think\Db;
|
||
|
||
class MockPeerActiveService extends ActiveService
|
||
{
|
||
private $activeMap = [];
|
||
|
||
public function setActive($userId, $isActive)
|
||
{
|
||
$this->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 PeerShareTest
|
||
{
|
||
private $passed = 0;
|
||
private $failed = 0;
|
||
|
||
public function run()
|
||
{
|
||
echo "========================================================\n";
|
||
echo " 酒道馆/区县平级逐代递减级联至0.01截断测试 (Peer Share) \n";
|
||
echo "========================================================\n\n";
|
||
|
||
$this->testVenuePeerCascadeToCent();
|
||
$this->testCountyPeerWithVenueCascadeToCent();
|
||
$this->testCountyPeerNoVenueCascadeToCent();
|
||
$this->testVenuePeerInactiveIntermediary();
|
||
|
||
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:酒道馆平级逐代递减级联(基数 50 元)
|
||
* 链条:买家(7) -> 馆A(2) -> 馆B(3) -> 馆C(4) -> 馆D(5) -> 馆E(6) -> 馆F(8)
|
||
* 预期:
|
||
* 馆B(3): 第1代 50 * 10% = 5.00
|
||
* 馆C(4): 第2代 5 * 10% = 0.50
|
||
* 馆D(5): 第3代 0.5 * 10% = 0.05
|
||
* 馆E(6): 第4代 0.05 * 10% = 0.005 -> round 0.01
|
||
* 馆F(8): 第5代 0.01 * 10% = 0.001 -> round 0.00 < 0.01,截断不发放
|
||
*/
|
||
public function testVenuePeerCascadeToCent()
|
||
{
|
||
$testName = "酒道馆: 平级逐代递减(5.00 -> 0.50 -> 0.05 -> 0.01) 到0.01截断";
|
||
|
||
Db::startTrans();
|
||
try {
|
||
$order = ['id' => 9911, 'user_id' => 7];
|
||
$buyerId = 7;
|
||
$chain = [
|
||
['user_id' => 2, 'is_venue' => 1], // 馆A
|
||
['user_id' => 3, 'is_venue' => 1], // 馆B
|
||
['user_id' => 4, 'is_venue' => 1], // 馆C
|
||
['user_id' => 5, 'is_venue' => 1], // 馆D
|
||
['user_id' => 6, 'is_venue' => 1], // 馆E
|
||
['user_id' => 8, 'is_venue' => 1], // 馆F
|
||
];
|
||
|
||
$teamResult = [
|
||
'venue' => ['user_id' => 2, 'amount' => 50.0, 'index' => 0],
|
||
'county' => null
|
||
];
|
||
|
||
$active = new MockPeerActiveService();
|
||
$reward = new PeerShareReward();
|
||
$reward->run($order, $buyerId, $chain, $teamResult, $active);
|
||
|
||
$b = Db::name('shopro_partner_reward')->where('order_id', 9911)->where('user_id', 3)->where('reward_type', 'venue_peer')->find();
|
||
$c = Db::name('shopro_partner_reward')->where('order_id', 9911)->where('user_id', 4)->where('reward_type', 'venue_peer')->find();
|
||
$d = Db::name('shopro_partner_reward')->where('order_id', 9911)->where('user_id', 5)->where('reward_type', 'venue_peer')->find();
|
||
$e = Db::name('shopro_partner_reward')->where('order_id', 9911)->where('user_id', 6)->where('reward_type', 'venue_peer')->find();
|
||
$f = Db::name('shopro_partner_reward')->where('order_id', 9911)->where('user_id', 8)->where('reward_type', 'venue_peer')->find();
|
||
|
||
$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 == 5.00) && ($cAmt == 0.50) && ($dAmt == 0.05) && ($eAmt == 0.01) && empty($f);
|
||
|
||
$this->assert($pass, $testName, "B={$bAmt}(5), C={$cAmt}(0.5), D={$dAmt}(0.05), E={$eAmt}(0.01), F=" . (empty($f) ? '已截断' : '未截断'));
|
||
} catch (\Exception $e) {
|
||
$this->assert(false, $testName, "异常: " . $e->getMessage());
|
||
} finally {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 测试 2:区县代理(有馆拆分场景,基数 50 元)逐代递减级联至 0.01 截断
|
||
* 预期:
|
||
* 县B(3): 第1代 50 * 10% = 5.00
|
||
* 县C(4): 第2代 0.50
|
||
* 县D(5): 第3代 0.05
|
||
* 县E(6): 第4代 0.01
|
||
* 县F(8): 截断
|
||
*/
|
||
public function testCountyPeerWithVenueCascadeToCent()
|
||
{
|
||
$testName = "区县代理(有馆): 平级逐代递减(5.00 -> 0.50 -> 0.05 -> 0.01) 到0.01截断";
|
||
|
||
Db::startTrans();
|
||
try {
|
||
$order = ['id' => 9912, 'user_id' => 7];
|
||
$buyerId = 7;
|
||
$chain = [
|
||
['user_id' => 2, 'is_county' => 1],
|
||
['user_id' => 3, 'is_county' => 1],
|
||
['user_id' => 4, 'is_county' => 1],
|
||
['user_id' => 5, 'is_county' => 1],
|
||
['user_id' => 6, 'is_county' => 1],
|
||
['user_id' => 8, 'is_county' => 1],
|
||
];
|
||
|
||
$teamResult = [
|
||
'venue' => ['user_id' => 1, 'amount' => 50.0, 'index' => -1],
|
||
'county' => ['user_id' => 2, 'amount' => 50.0, 'index' => 0]
|
||
];
|
||
|
||
$active = new MockPeerActiveService();
|
||
$reward = new PeerShareReward();
|
||
$reward->run($order, $buyerId, $chain, $teamResult, $active);
|
||
|
||
$b = Db::name('shopro_partner_reward')->where('order_id', 9912)->where('user_id', 3)->where('reward_type', 'county_peer')->find();
|
||
$c = Db::name('shopro_partner_reward')->where('order_id', 9912)->where('user_id', 4)->where('reward_type', 'county_peer')->find();
|
||
$d = Db::name('shopro_partner_reward')->where('order_id', 9912)->where('user_id', 5)->where('reward_type', 'county_peer')->find();
|
||
$e = Db::name('shopro_partner_reward')->where('order_id', 9912)->where('user_id', 6)->where('reward_type', 'county_peer')->find();
|
||
$f = Db::name('shopro_partner_reward')->where('order_id', 9912)->where('user_id', 8)->where('reward_type', 'county_peer')->find();
|
||
|
||
$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 == 5.00) && ($cAmt == 0.50) && ($dAmt == 0.05) && ($eAmt == 0.01) && empty($f);
|
||
|
||
$this->assert($pass, $testName, "B={$bAmt}(5), C={$cAmt}(0.5), D={$dAmt}(0.05), E={$eAmt}(0.01), F=" . (empty($f) ? '已截断' : '未截断'));
|
||
} catch (\Exception $e) {
|
||
$this->assert(false, $testName, "异常: " . $e->getMessage());
|
||
} finally {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 测试 3:区县代理(无馆独享全额 100 元)逐代递减级联至 0.01 截断
|
||
* 预期:
|
||
* 县B(3): 第1代 100 * 10% = 10.00
|
||
* 县C(4): 第2代 10 * 10% = 1.00
|
||
* 县D(5): 第3代 1 * 10% = 0.10
|
||
* 县E(6): 第4代 0.10 * 10% = 0.01
|
||
* 县F(8): 第5代 0.01 * 10% = 0.001 -> 0.00 截断
|
||
*/
|
||
public function testCountyPeerNoVenueCascadeToCent()
|
||
{
|
||
$testName = "区县代理(无馆): 平级逐代递减(10.00 -> 1.00 -> 0.10 -> 0.01) 到0.01截断";
|
||
|
||
Db::startTrans();
|
||
try {
|
||
$order = ['id' => 9913, 'user_id' => 7];
|
||
$buyerId = 7;
|
||
$chain = [
|
||
['user_id' => 2, 'is_county' => 1],
|
||
['user_id' => 3, 'is_county' => 1],
|
||
['user_id' => 4, 'is_county' => 1],
|
||
['user_id' => 5, 'is_county' => 1],
|
||
['user_id' => 6, 'is_county' => 1],
|
||
['user_id' => 8, 'is_county' => 1],
|
||
];
|
||
|
||
$teamResult = [
|
||
'venue' => null,
|
||
'county' => ['user_id' => 2, 'amount' => 100.0, 'index' => 0]
|
||
];
|
||
|
||
$active = new MockPeerActiveService();
|
||
$reward = new PeerShareReward();
|
||
$reward->run($order, $buyerId, $chain, $teamResult, $active);
|
||
|
||
$b = Db::name('shopro_partner_reward')->where('order_id', 9913)->where('user_id', 3)->where('reward_type', 'county_peer')->find();
|
||
$c = Db::name('shopro_partner_reward')->where('order_id', 9913)->where('user_id', 4)->where('reward_type', 'county_peer')->find();
|
||
$d = Db::name('shopro_partner_reward')->where('order_id', 9913)->where('user_id', 5)->where('reward_type', 'county_peer')->find();
|
||
$e = Db::name('shopro_partner_reward')->where('order_id', 9913)->where('user_id', 6)->where('reward_type', 'county_peer')->find();
|
||
$f = Db::name('shopro_partner_reward')->where('order_id', 9913)->where('user_id', 8)->where('reward_type', 'county_peer')->find();
|
||
|
||
$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 == 10.00) && ($cAmt == 1.00) && ($dAmt == 0.10) && ($eAmt == 0.01) && empty($f);
|
||
|
||
$this->assert($pass, $testName, "B={$bAmt}(10), C={$cAmt}(1), D={$dAmt}(0.1), E={$eAmt}(0.01), F=" . (empty($f) ? '已截断' : '未截断'));
|
||
} catch (\Exception $e) {
|
||
$this->assert(false, $testName, "异常: " . $e->getMessage());
|
||
} finally {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 测试 4:酒道馆中间平级未自购跳过场景
|
||
*/
|
||
public function testVenuePeerInactiveIntermediary()
|
||
{
|
||
$testName = "酒道馆: 中间平级馆B未自购被跳过,上级馆C仍正常获得第2代平级0.50元";
|
||
|
||
Db::startTrans();
|
||
try {
|
||
$order = ['id' => 9914, 'user_id' => 7];
|
||
$buyerId = 7;
|
||
$chain = [
|
||
['user_id' => 2, 'is_venue' => 1],
|
||
['user_id' => 3, 'is_venue' => 1],
|
||
['user_id' => 4, 'is_venue' => 1],
|
||
];
|
||
|
||
$teamResult = [
|
||
'venue' => ['user_id' => 2, 'amount' => 50.0, 'index' => 0],
|
||
'county' => null
|
||
];
|
||
|
||
$active = new MockPeerActiveService();
|
||
$active->setActive(3, false); // 馆B 未自购
|
||
$active->setActive(4, true); // 馆C 活跃
|
||
|
||
$reward = new PeerShareReward();
|
||
$reward->run($order, $buyerId, $chain, $teamResult, $active);
|
||
|
||
$bSkip = Db::name('shopro_partner_reward')
|
||
->where('order_id', 9914)
|
||
->where('user_id', 3)
|
||
->where('status', -1)
|
||
->find();
|
||
|
||
$cReward = Db::name('shopro_partner_reward')
|
||
->where('order_id', 9914)
|
||
->where('user_id', 4)
|
||
->where('status', 1)
|
||
->find();
|
||
|
||
$bSkipped = !empty($bSkip) && floatval($bSkip['amount']) == 0;
|
||
$cReceived = !empty($cReward) && floatval($cReward['amount']) == 0.50;
|
||
|
||
$this->assert($bSkipped && $cReceived, $testName, "B被跳过记录, C正常结算0.50元");
|
||
} catch (\Exception $e) {
|
||
$this->assert(false, $testName, "异常: " . $e->getMessage());
|
||
} finally {
|
||
Db::rollback();
|
||
}
|
||
}
|
||
}
|
||
|
||
// 执行测试
|
||
if (php_sapi_name() === 'cli') {
|
||
$tester = new PeerShareTest();
|
||
exit($tester->run());
|
||
}
|