AgentEquityRechargeLockTest.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <?php
  2. namespace Tests\Integration;
  3. use App\Models\Agent\Agent;
  4. use App\Models\Agent\AgentRechargeLock;
  5. use App\Models\Agent\AgentSetting;
  6. use App\Models\Agent\AgentWithdrawAccount;
  7. use App\Services\Agent\AgentEquityService;
  8. use App\Services\Agent\AgentWalletService;
  9. use App\Services\Agent\AgentWithdrawalService;
  10. use Carbon\Carbon;
  11. use Illuminate\Support\Facades\DB;
  12. use PHPUnit\Framework\TestCase;
  13. use Tests\Support\AgentTestEnvironment;
  14. /** 入股代理充值后 N 天内不能提现,可以立即购买股份(优先消耗锁定中的充值)。 */
  15. class AgentEquityRechargeLockTest extends TestCase
  16. {
  17. use AgentTestEnvironment;
  18. private AgentWalletService $wallets;
  19. private function recharge(Agent $agent, string $amount, string $key): void
  20. {
  21. $this->wallets->adjust($agent->id, $amount, 'recharge', '充值', $key, 'system', null, 'agent_recharge', 1);
  22. }
  23. private function setUpEquity(int $lockDays = 7): void
  24. {
  25. $this->wallets = new AgentWalletService();
  26. AgentSetting::current();
  27. DB::table('agent_settings')->where('id', 1)->update(['equity_enabled' => 1, 'equity_price_per_percent' => 1000,
  28. 'equity_min_percent' => 0.1, 'equity_max_percent' => 1, 'equity_recharge_lock_days' => $lockDays]);
  29. }
  30. public function test_recharge_is_locked_for_seven_days_then_withdrawable(): void
  31. {
  32. $this->setUpEquity();
  33. $this->paymentChannels();
  34. $agent = $this->agent(Agent::TYPE_EQUITY);
  35. $this->recharge($agent, '1000', 'r1');
  36. $agent = $agent->fresh();
  37. $this->assertSame('0.0000', $this->wallets->withdrawable($agent));
  38. $funds = $this->wallets->funds($agent);
  39. $this->assertSame(['1000.0000', '1000.0000', '0.0000', 7], [$funds['balance'], $funds['locked_amount'], $funds['withdrawable_amount'], $funds['recharge_lock_days']]);
  40. $locks = $this->wallets->activeLocks($agent);
  41. $this->assertSame('2026-09-14 12:00:00', $locks[0]['unlock_at']);
  42. $account = AgentWithdrawAccount::query()->create(['agent_id' => $agent->id, 'type' => 'usdt', 'network' => 'TRC20',
  43. 'account' => 'TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE', 'status' => 1]);
  44. try { (new AgentWithdrawalService($this->wallets))->request($agent, $account->id, '10', 'withdraw-old', 'locked'); $this->fail('locked'); }
  45. catch (\RuntimeException $e) { $this->assertSame('可提现余额不足(充值未满 7 天的金额暂不可提现)', $e->getMessage()); }
  46. Carbon::setTestNow(Carbon::parse('2026-09-14 12:00:01'));
  47. $this->assertSame('1000.0000', $this->wallets->withdrawable($agent->fresh()));
  48. $this->assertSame([], $this->wallets->activeLocks($agent));
  49. $this->assertSame('0.0000', $this->wallets->funds($agent->fresh())['locked_amount']);
  50. }
  51. public function test_share_purchase_uses_locked_recharge_first(): void
  52. {
  53. $this->setUpEquity();
  54. $agent = $this->agent(Agent::TYPE_EQUITY);
  55. $this->wallets->adjust($agent->id, '500', 'credit', '分红', 'c1', 'admin', 1); // 人工加款不锁定
  56. $this->recharge($agent, '1000', 'r1');
  57. $this->assertSame('500.0000', $this->wallets->withdrawable($agent->fresh()));
  58. $order = (new AgentEquityService($this->wallets))->order($agent->fresh(), '0.6'); // 600
  59. $this->assertSame('completed', $order->status);
  60. $agent = $agent->fresh();
  61. $this->assertSame('900.0000', $agent->balance);
  62. $this->assertSame('400.0000', $this->wallets->lockedAmount($agent));
  63. $this->assertSame('500.0000', $this->wallets->withdrawable($agent), 'the unlocked dividend stays withdrawable');
  64. }
  65. public function test_joint_agents_and_zero_days_are_not_locked(): void
  66. {
  67. $this->setUpEquity(0);
  68. $equity = $this->agent(Agent::TYPE_EQUITY);
  69. $this->recharge($equity, '300', 'r-equity');
  70. $this->assertSame('300.0000', $this->wallets->withdrawable($equity->fresh()));
  71. DB::table('agent_settings')->where('id', 1)->update(['equity_recharge_lock_days' => 7]);
  72. $joint = $this->agent(Agent::TYPE_JOINT);
  73. $this->recharge($joint, '300', 'r-joint');
  74. $this->assertSame(0, AgentRechargeLock::query()->count(), 'joint recharges are margin, not locked');
  75. $this->assertArrayNotHasKey('locked_amount', $this->wallets->funds($joint->fresh()));
  76. }
  77. }