SubAgentController.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. <?php
  2. namespace App\Http\Controllers\agent;
  3. use App\Http\Controllers\AgentApiController;
  4. use App\Models\Agent\Agent;
  5. use App\Services\Agent\AgentDomainService;
  6. use App\Services\Agent\AgentReportService;
  7. use App\Services\Agent\AgentService;
  8. use App\Services\Agent\AgentWalletService;
  9. use Illuminate\Http\Request;
  10. use App\Rules\DecimalNumber;
  11. class SubAgentController extends AgentApiController
  12. {
  13. public function index(Request $request, AgentReportService $reports, AgentDomainService $domains)
  14. {
  15. return $this->execute(function () use ($request, $reports, $domains) {
  16. $data = $request->validate([
  17. 'page' => ['nullable', 'integer', 'min:1'], 'limit' => ['nullable', 'integer', 'min:1', 'max:100'],
  18. 'username' => ['nullable', 'string', 'max:64'], 'status' => ['nullable', 'integer', 'in:0,1'],
  19. 'direct_only' => ['nullable', 'boolean'],
  20. ]);
  21. $root = $this->currentAgent();
  22. $page = max(1, (int) ($data['page'] ?? 1));
  23. $limit = min(100, max(1, (int) ($data['limit'] ?? 20)));
  24. $query = Agent::query()->with('parent:id,username');
  25. if (!empty($data['direct_only'])) {
  26. $query->where('parent_id', $root->id);
  27. } else {
  28. $query->whereIn('id', $reports->visibleAgentIds($root, false));
  29. }
  30. if (!empty($data['username'])) $query->where('username', 'like', '%' . $data['username'] . '%');
  31. if (isset($data['status'])) $query->where('status', $data['status']);
  32. $total = (clone $query)->count();
  33. $list = $query->orderByDesc('id')->forPage($page, $limit)->get()->map(function (Agent $agent) use ($domains) {
  34. return array_merge($agent->toArray(), $domains->format($agent));
  35. });
  36. return compact('total', 'page', 'limit', 'list');
  37. });
  38. }
  39. public function store(Request $request, AgentService $service)
  40. {
  41. return $this->execute(function () use ($request, $service) {
  42. $root = $this->currentAgent();
  43. $data = $request->validate([
  44. 'username' => ['required', 'string', 'min:4', 'max:64', 'alpha_dash', 'unique:agents,username'],
  45. 'password' => ['required', 'string', 'min:6', 'max:100'],
  46. 'withdraw_password' => ['nullable', 'string', 'min:6', 'max:100'],
  47. 'real_name' => ['nullable', 'string', 'max:128'],
  48. 'parent_id' => ['nullable', 'integer', 'exists:agents,id'],
  49. 'deposit_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)],
  50. 'withdraw_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)],
  51. 'flow_commission_rate' => ['nullable', 'numeric', 'between:0,' . $root->flow_commission_rate, new DecimalNumber(3, 4)],
  52. 'profit_commission_rate' => ['nullable', 'numeric', 'between:0,' . $root->profit_commission_rate, new DecimalNumber(3, 4)],
  53. 'status' => ['nullable', 'integer', 'in:0,1'],
  54. ]);
  55. return $service->create($data, null, $root);
  56. });
  57. }
  58. public function update(Request $request, AgentService $service)
  59. {
  60. return $this->execute(function () use ($request, $service) {
  61. $root = $this->currentAgent();
  62. $data = $request->validate([
  63. 'id' => ['required', 'integer', 'exists:agents,id'],
  64. 'password' => ['nullable', 'string', 'min:6', 'max:100'],
  65. 'withdraw_password' => ['nullable', 'string', 'min:6', 'max:100'],
  66. 'real_name' => ['nullable', 'string', 'max:128'],
  67. 'deposit_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)],
  68. 'withdraw_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)],
  69. 'status' => ['nullable', 'integer', 'in:0,1'],
  70. ]);
  71. if ((int) $data['id'] === (int) $root->id) throw new \RuntimeException('不能在下级代理接口修改自己');
  72. return $service->update(Agent::query()->findOrFail($data['id']), $data, $root);
  73. });
  74. }
  75. public function transfer(Request $request, AgentService $agents, AgentWalletService $wallets)
  76. {
  77. return $this->execute(function () use ($request, $agents, $wallets) {
  78. $data = $request->validate([
  79. 'agent_id' => ['required', 'integer', 'exists:agents,id'],
  80. 'direction' => ['required', 'in:credit,debit'],
  81. 'amount' => ['required', 'numeric', 'min:0.0001', new DecimalNumber()],
  82. 'remark' => ['required', 'string', 'max:500'],
  83. 'request_id' => ['required', 'string', 'max:64'],
  84. ]);
  85. $root = $this->currentAgent();
  86. if ((int) $data['agent_id'] === (int) $root->id) throw new \RuntimeException('不能给自己转账');
  87. $agents->assertVisible($root, (int) $data['agent_id']);
  88. $target = Agent::query()->findOrFail($data['agent_id']);
  89. if ($data['direction'] === 'credit' && (int) $target->status !== Agent::STATUS_ENABLED) {
  90. throw new \RuntimeException('不能给已禁用代理下发额度');
  91. }
  92. $from = $data['direction'] === 'credit' ? (int) $root->id : (int) $data['agent_id'];
  93. $to = $data['direction'] === 'credit' ? (int) $data['agent_id'] : (int) $root->id;
  94. return $wallets->transfer($from, $to, (string) $data['amount'], $data['remark'], 'agent:' . $root->id . ':' . $data['request_id'], (int) $root->id);
  95. });
  96. }
  97. }