feat(fsgx): 完成全部24项开发任务 Phase1-7
Phase1 后端核心:
- 新增 fsgx_v1.sql 迁移脚本(is_queue_goods/frozen_points/available_points/no_assess)
- SystemConfigServices 返佣设置扩展(周期人数/分档比例/范围/时机)
- StoreOrderCreateServices 周期循环佣金计算
- StoreOrderTakeServices 佣金发放后同步冻结积分
- StoreProductServices/StoreProduct 保存 is_queue_goods
Phase2 后端接口:
- GET /api/hjf/brokerage/progress 佣金周期进度
- GET /api/hjf/assets/overview 资产总览
- HjfPointsServices 每日 frozen_points 0.4‰ 释放定时任务
- PUT /adminapi/hjf/member/{uid}/no_assess 不考核接口
- GET /adminapi/hjf/points/release_log 积分日志接口
Phase3 前端清理:
- hjfCustom.js 路由精简(仅保留 points/log)
- hjfQueue.js/hjfMember.js API 清理/重定向至 CRMEB 原生接口
- pages.json 公排→推荐佣金/佣金记录/佣金规则
Phase4-5 前端改造:
- queue/status.vue 推荐佣金进度页整体重写
- 商品详情/订单确认/支付结果页文案与逻辑改造
- 个人中心/资产页/引导页/规则页文案改造
- HjfQueueProgress/HjfRefundNotice/HjfAssetCard 组件改造
- 推广中心嵌入佣金进度摘要
- hjfMockData.js 全量更新(公排字段→佣金字段)
Phase6 Admin 增强:
- 用户列表新增 frozen_points/available_points 列及不考核操作按钮
- hjfPoints.js USE_MOCK=false 对接真实积分日志接口
Phase7 配置文档:
- docs/fsgx-phase7-config-checklist.md 后台配置与全链路验收清单
Made-with: Cursor
This commit is contained in:
320
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/BackoffTest.php
vendored
Executable file
320
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/BackoffTest.php
vendored
Executable file
@@ -0,0 +1,320 @@
|
||||
<?php
|
||||
namespace STS\Backoff;
|
||||
|
||||
use Exception;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use STS\Backoff\Strategies\ConstantStrategy;
|
||||
use STS\Backoff\Strategies\ExponentialStrategy;
|
||||
use STS\Backoff\Strategies\LinearStrategy;
|
||||
use STS\Backoff\Strategies\PolynomialStrategy;
|
||||
|
||||
class BackoffTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$this->assertEquals(5, $b->getMaxAttempts());
|
||||
$this->assertInstanceOf(PolynomialStrategy::class, $b->getStrategy());
|
||||
$this->assertFalse($b->jitterEnabled());
|
||||
}
|
||||
|
||||
public function testFluidApi()
|
||||
{
|
||||
$b = new Backoff();
|
||||
$result = $b
|
||||
->setStrategy('constant')
|
||||
->setMaxAttempts(10)
|
||||
->setWaitCap(5)
|
||||
->enableJitter();
|
||||
|
||||
$this->assertEquals(10, $b->getMaxAttempts());
|
||||
$this->assertEquals(5, $b->getWaitCap());
|
||||
$this->assertTrue($b->jitterEnabled());
|
||||
$this->assertInstanceOf(ConstantStrategy::class, $b->getStrategy());
|
||||
}
|
||||
|
||||
public function testChangingStaticDefaults()
|
||||
{
|
||||
Backoff::$defaultMaxAttempts = 15;
|
||||
Backoff::$defaultStrategy = "constant";
|
||||
Backoff::$defaultJitterEnabled = true;
|
||||
|
||||
$b = new Backoff();
|
||||
|
||||
$this->assertEquals(15, $b->getMaxAttempts());
|
||||
$this->assertInstanceOf(ConstantStrategy::class, $b->getStrategy());
|
||||
$this->assertTrue($b->jitterEnabled());
|
||||
|
||||
Backoff::$defaultStrategy = new LinearStrategy(250);
|
||||
|
||||
$b = new Backoff();
|
||||
|
||||
$this->assertInstanceOf(LinearStrategy::class, $b->getStrategy());
|
||||
|
||||
// Put them back!
|
||||
Backoff::$defaultMaxAttempts = 5;
|
||||
Backoff::$defaultStrategy = "polynomial";
|
||||
Backoff::$defaultJitterEnabled = false;
|
||||
}
|
||||
|
||||
public function testConstructorParams()
|
||||
{
|
||||
$b = new Backoff(10, "linear");
|
||||
|
||||
$this->assertEquals(10, $b->getMaxAttempts());
|
||||
$this->assertInstanceOf(LinearStrategy::class, $b->getStrategy());
|
||||
}
|
||||
|
||||
public function testStrategyKeys()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$b->setStrategy("constant");
|
||||
$this->assertInstanceOf(ConstantStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy("linear");
|
||||
$this->assertInstanceOf(LinearStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy("polynomial");
|
||||
$this->assertInstanceOf(PolynomialStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy("exponential");
|
||||
$this->assertInstanceOf(ExponentialStrategy::class, $b->getStrategy());
|
||||
}
|
||||
|
||||
public function testStrategyInstances()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$b->setStrategy(new ConstantStrategy());
|
||||
$this->assertInstanceOf(ConstantStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy(new LinearStrategy());
|
||||
$this->assertInstanceOf(LinearStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy(new PolynomialStrategy());
|
||||
$this->assertInstanceOf(PolynomialStrategy::class, $b->getStrategy());
|
||||
|
||||
$b->setStrategy(new ExponentialStrategy());
|
||||
$this->assertInstanceOf(ExponentialStrategy::class, $b->getStrategy());
|
||||
}
|
||||
|
||||
public function testClosureStrategy()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$strategy = function () {
|
||||
return "hi there";
|
||||
};
|
||||
|
||||
$b->setStrategy($strategy);
|
||||
|
||||
$this->assertEquals("hi there", call_user_func($b->getStrategy()));
|
||||
}
|
||||
|
||||
public function testIntegerReturnsConstantStrategy()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$b->setStrategy(500);
|
||||
|
||||
$this->assertInstanceOf(ConstantStrategy::class, $b->getStrategy());
|
||||
}
|
||||
|
||||
public function testInvalidStrategy()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
$b->setStrategy("foo");
|
||||
}
|
||||
|
||||
public function testWaitTimes()
|
||||
{
|
||||
$b = new Backoff(1, "linear");
|
||||
|
||||
$this->assertEquals(100, $b->getStrategy()->getBase());
|
||||
|
||||
$this->assertEquals(100, $b->getWaitTime(1));
|
||||
$this->assertEquals(200, $b->getWaitTime(2));
|
||||
}
|
||||
|
||||
public function testWaitCap()
|
||||
{
|
||||
$b = new Backoff(1, new LinearStrategy(5000));
|
||||
|
||||
$this->assertEquals(10000, $b->getWaitTime(2));
|
||||
|
||||
$b->setWaitCap(5000);
|
||||
|
||||
$this->assertEquals(5000, $b->getWaitTime(2));
|
||||
}
|
||||
|
||||
public function testWait()
|
||||
{
|
||||
$b = new Backoff(1, new LinearStrategy(50));
|
||||
|
||||
$start = microtime(true);
|
||||
|
||||
$b->wait(2);
|
||||
|
||||
$end = microtime(true);
|
||||
|
||||
$elapsedMS = ($end - $start) * 1000;
|
||||
|
||||
// We expect that this took just barely over the 100ms we asked for
|
||||
$this->assertTrue($elapsedMS > 90 && $elapsedMS < 150,
|
||||
sprintf("Expected elapsedMS between 100 & 110, got: $elapsedMS\n"));
|
||||
}
|
||||
|
||||
public function testSuccessfulWork()
|
||||
{
|
||||
$b = new Backoff();
|
||||
|
||||
$result = $b->run(function () {
|
||||
return "done";
|
||||
});
|
||||
|
||||
$this->assertEquals("done", $result);
|
||||
}
|
||||
|
||||
public function testFirstAttemptDoesNotCallStrategy()
|
||||
{
|
||||
$b = new Backoff();
|
||||
$b->setStrategy(function () {
|
||||
throw new \Exception("We shouldn't be here");
|
||||
});
|
||||
|
||||
$result = $b->run(function () {
|
||||
return "done";
|
||||
});
|
||||
|
||||
$this->assertEquals("done", $result);
|
||||
}
|
||||
|
||||
public function testFailedWorkReThrowsException()
|
||||
{
|
||||
$b = new Backoff(2, new ConstantStrategy(0));
|
||||
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage("failure");
|
||||
|
||||
$b->run(function () {
|
||||
throw new \Exception("failure");
|
||||
});
|
||||
}
|
||||
|
||||
public function testHandleErrorsPhp7()
|
||||
{
|
||||
$b = new Backoff(2, new ConstantStrategy(0));
|
||||
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage("Modulo by zero");
|
||||
|
||||
$b->run(function () {
|
||||
if (version_compare(PHP_VERSION, '7.0.0') >= 0) {
|
||||
return 1 % 0;
|
||||
} else {
|
||||
// Handle version < 7
|
||||
throw new Exception("Modulo by zero");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public function testAttempts()
|
||||
{
|
||||
$b = new Backoff(10, new ConstantStrategy(0));
|
||||
|
||||
$attempt = 0;
|
||||
|
||||
$result = $b->run(function () use (&$attempt) {
|
||||
$attempt++;
|
||||
|
||||
if ($attempt < 5) {
|
||||
throw new \Exception("failure");
|
||||
}
|
||||
|
||||
return "success";
|
||||
});
|
||||
|
||||
$this->assertEquals(5, $attempt);
|
||||
$this->assertEquals("success", $result);
|
||||
}
|
||||
|
||||
public function testCustomDeciderAttempts()
|
||||
{
|
||||
$b = new Backoff(10, new ConstantStrategy(0));
|
||||
$b->setDecider(
|
||||
function ($retry, $maxAttempts, $result = null, $exception = null) {
|
||||
if ($retry >= $maxAttempts || $result == "success") {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
$attempt = 0;
|
||||
|
||||
$result = $b->run(function () use (&$attempt) {
|
||||
$attempt++;
|
||||
|
||||
if ($attempt < 5) {
|
||||
throw new \Exception("failure");
|
||||
}
|
||||
|
||||
if ($attempt < 7) {
|
||||
return 'not yet';
|
||||
}
|
||||
|
||||
return "success";
|
||||
});
|
||||
|
||||
$this->assertEquals(7, $attempt);
|
||||
$this->assertEquals("success", $result);
|
||||
}
|
||||
|
||||
public function testErrorHandler()
|
||||
{
|
||||
$log = [];
|
||||
|
||||
$b = new Backoff(10, new ConstantStrategy(0));
|
||||
$b->setErrorHandler(function($exception, $attempt, $maxAttempts) use(&$log) {
|
||||
$log[] = "Attempt $attempt of $maxAttempts: " . $exception->getMessage();
|
||||
});
|
||||
|
||||
$attempt = 0;
|
||||
|
||||
$result = $b->run(function () use (&$attempt) {
|
||||
$attempt++;
|
||||
|
||||
if ($attempt < 5) {
|
||||
throw new \Exception("failure");
|
||||
}
|
||||
|
||||
return "success";
|
||||
});
|
||||
|
||||
$this->assertEquals(4, count($log));
|
||||
$this->assertEquals("Attempt 4 of 10: failure", array_pop($log));
|
||||
$this->assertEquals("success", $result);
|
||||
}
|
||||
|
||||
public function testJitter()
|
||||
{
|
||||
$b = new Backoff(10, new ConstantStrategy(1000));
|
||||
|
||||
// First without jitter
|
||||
$this->assertEquals(1000, $b->getWaitTime(1));
|
||||
|
||||
// Now with jitter
|
||||
$b->enableJitter();
|
||||
|
||||
// Because it's still possible that I could get 1000 back even with jitter, I'm going to generate two
|
||||
$waitTime1 = $b->getWaitTime(1);
|
||||
$waitTime2 = $b->getWaitTime(1);
|
||||
|
||||
// And I'm banking that I didn't hit the _extremely_ rare chance that both were randomly chosen to be 1000 still
|
||||
$this->assertTrue($waitTime1 < 1000 || $waitTime2 < 1000);
|
||||
}
|
||||
}
|
||||
69
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/HelpersTest.php
vendored
Executable file
69
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/HelpersTest.php
vendored
Executable file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace STS\Backoff;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use STS\Backoff\Strategies\ConstantStrategy;
|
||||
|
||||
class HelpersTest extends TestCase
|
||||
{
|
||||
public function testSuccessWithDefaults()
|
||||
{
|
||||
$result = backoff(function() {
|
||||
return "success";
|
||||
});
|
||||
|
||||
$this->assertEquals("success", $result);
|
||||
}
|
||||
|
||||
public function testFailureWithDefaults()
|
||||
{
|
||||
$this->expectException(\Exception::class);
|
||||
$this->expectExceptionMessage("failure");
|
||||
|
||||
backoff(function() {
|
||||
throw new \Exception("failure");
|
||||
}, 2);
|
||||
}
|
||||
|
||||
public function testStrategy()
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
// We're going to run a test for 100 attempts, just to verify we were able to
|
||||
// set our own strategy with a low sleep time.
|
||||
|
||||
try {
|
||||
backoff(function() {
|
||||
throw new \Exception("failure");
|
||||
}, 100, new ConstantStrategy(1));
|
||||
} catch(\Exception $e) {}
|
||||
|
||||
$end = microtime(true);
|
||||
|
||||
$elapsedMS = ($end - $start) * 1000;
|
||||
|
||||
// We expect that this took just a bit over the 100ms that we slept
|
||||
$this->assertTrue($elapsedMS > 100 && $elapsedMS < 200);
|
||||
}
|
||||
|
||||
public function testWaitCap()
|
||||
{
|
||||
$start = microtime(true);
|
||||
|
||||
// We're going to specify a really long sleep time, but with a short cap to override.
|
||||
|
||||
try {
|
||||
backoff(function() {
|
||||
throw new \Exception("failure");
|
||||
}, 2, new ConstantStrategy(100000), 100);
|
||||
} catch(\Exception $e) {}
|
||||
|
||||
$end = microtime(true);
|
||||
|
||||
$elapsedMS = ($end - $start) * 1000;
|
||||
|
||||
// We expect that this took just a bit over the 100ms that we slept
|
||||
$this->assertTrue($elapsedMS > 90 && $elapsedMS < 150,
|
||||
sprintf("Expected elapsedMS between 90 & 200, got: $elapsedMS\n"));
|
||||
}
|
||||
}
|
||||
23
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/ConstantStrategyTest.php
vendored
Executable file
23
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/ConstantStrategyTest.php
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace STS\Backoff\Strategies;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ConstantStrategyTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$s = new ConstantStrategy();
|
||||
|
||||
$this->assertEquals(100, $s->getBase());
|
||||
}
|
||||
|
||||
public function testWaitTimes()
|
||||
{
|
||||
$s = new ConstantStrategy(100);
|
||||
|
||||
$this->assertEquals(100, $s->getWaitTime(1));
|
||||
$this->assertEquals(100, $s->getWaitTime(2));
|
||||
$this->assertEquals(100, $s->getWaitTime(3));
|
||||
}
|
||||
}
|
||||
28
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/ExponentialStrategyTest.php
vendored
Executable file
28
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/ExponentialStrategyTest.php
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
namespace STS\Backoff\Strategies;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ExponentialStrategyTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$s = new ExponentialStrategy();
|
||||
|
||||
$this->assertEquals(100, $s->getBase());
|
||||
}
|
||||
|
||||
public function testWaitTimes()
|
||||
{
|
||||
$s = new ExponentialStrategy(200);
|
||||
|
||||
$this->assertEquals(200, $s->getWaitTime(1));
|
||||
$this->assertEquals(800, $s->getWaitTime(2));
|
||||
$this->assertEquals(1600, $s->getWaitTime(3));
|
||||
$this->assertEquals(3200, $s->getWaitTime(4));
|
||||
$this->assertEquals(6400, $s->getWaitTime(5));
|
||||
$this->assertEquals(12800, $s->getWaitTime(6));
|
||||
$this->assertEquals(25600, $s->getWaitTime(7));
|
||||
$this->assertEquals(51200, $s->getWaitTime(8));
|
||||
}
|
||||
}
|
||||
23
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/LinearStrategyTest.php
vendored
Executable file
23
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/LinearStrategyTest.php
vendored
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace STS\Backoff\Strategies;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LinearStrategyTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$s = new LinearStrategy();
|
||||
|
||||
$this->assertEquals(100, $s->getBase());
|
||||
}
|
||||
|
||||
public function testWaitTimes()
|
||||
{
|
||||
$s = new LinearStrategy(100);
|
||||
|
||||
$this->assertEquals(100, $s->getWaitTime(1));
|
||||
$this->assertEquals(200, $s->getWaitTime(2));
|
||||
$this->assertEquals(300, $s->getWaitTime(3));
|
||||
}
|
||||
}
|
||||
29
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/PolynomialStrategyTest.php
vendored
Executable file
29
pro_v3.5.1_副本/vendor/stechstudio/backoff/tests/Strategies/PolynomialStrategyTest.php
vendored
Executable file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace STS\Backoff\Strategies;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class PolynomialStrategyTest extends TestCase
|
||||
{
|
||||
public function testDefaults()
|
||||
{
|
||||
$s = new PolynomialStrategy();
|
||||
|
||||
$this->assertEquals(100, $s->getBase());
|
||||
$this->assertEquals(2, $s->getDegree());
|
||||
}
|
||||
|
||||
public function testWaitTimes()
|
||||
{
|
||||
$s = new PolynomialStrategy(200, 2);
|
||||
|
||||
$this->assertEquals(200, $s->getWaitTime(1));
|
||||
$this->assertEquals(800, $s->getWaitTime(2));
|
||||
$this->assertEquals(1800, $s->getWaitTime(3));
|
||||
$this->assertEquals(3200, $s->getWaitTime(4));
|
||||
$this->assertEquals(5000, $s->getWaitTime(5));
|
||||
$this->assertEquals(7200, $s->getWaitTime(6));
|
||||
$this->assertEquals(9800, $s->getWaitTime(7));
|
||||
$this->assertEquals(12800, $s->getWaitTime(8));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user