execute(function () use ($request, $reports, $domains) { $data = $request->validate([ 'page' => ['nullable', 'integer', 'min:1'], 'limit' => ['nullable', 'integer', 'min:1', 'max:100'], 'username' => ['nullable', 'string', 'max:64'], 'status' => ['nullable', 'integer', 'in:0,1'], 'direct_only' => ['nullable', 'boolean'], ]); $root = $this->currentAgent(); $page = max(1, (int) ($data['page'] ?? 1)); $limit = min(100, max(1, (int) ($data['limit'] ?? 20))); $query = Agent::query()->with('parent:id,username'); if (!empty($data['direct_only'])) { $query->where('parent_id', $root->id); } else { $query->whereIn('id', $reports->visibleAgentIds($root, false)); } if (!empty($data['username'])) $query->where('username', 'like', '%' . $data['username'] . '%'); if (isset($data['status'])) $query->where('status', $data['status']); $total = (clone $query)->count(); $list = $query->orderByDesc('id')->forPage($page, $limit)->get()->map(function (Agent $agent) use ($domains) { return array_merge($agent->toArray(), $domains->format($agent)); }); return compact('total', 'page', 'limit', 'list'); }); } public function store(Request $request, AgentService $service) { return $this->execute(function () use ($request, $service) { $root = $this->currentAgent(); $data = $request->validate([ 'username' => ['required', 'string', 'min:4', 'max:64', 'alpha_dash', 'unique:agents,username'], 'password' => ['required', 'string', 'min:6', 'max:100'], 'withdraw_password' => ['nullable', 'string', 'min:6', 'max:100'], 'real_name' => ['nullable', 'string', 'max:128'], 'parent_id' => ['nullable', 'integer', 'exists:agents,id'], 'deposit_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)], 'withdraw_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)], 'flow_commission_rate' => ['nullable', 'numeric', 'between:0,' . $root->flow_commission_rate, new DecimalNumber(3, 4)], 'profit_commission_rate' => ['nullable', 'numeric', 'between:0,' . $root->profit_commission_rate, new DecimalNumber(3, 4)], 'status' => ['nullable', 'integer', 'in:0,1'], ]); return $service->create($data, null, $root); }); } public function update(Request $request, AgentService $service) { return $this->execute(function () use ($request, $service) { $root = $this->currentAgent(); $data = $request->validate([ 'id' => ['required', 'integer', 'exists:agents,id'], 'password' => ['nullable', 'string', 'min:6', 'max:100'], 'withdraw_password' => ['nullable', 'string', 'min:6', 'max:100'], 'real_name' => ['nullable', 'string', 'max:128'], 'deposit_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)], 'withdraw_fee_rate' => ['nullable', 'numeric', 'between:0,100', new DecimalNumber(3, 4)], 'status' => ['nullable', 'integer', 'in:0,1'], ]); if ((int) $data['id'] === (int) $root->id) throw new \RuntimeException('不能在下级代理接口修改自己'); return $service->update(Agent::query()->findOrFail($data['id']), $data, $root); }); } public function transfer(Request $request, AgentService $agents, AgentWalletService $wallets) { return $this->execute(function () use ($request, $agents, $wallets) { $data = $request->validate([ 'agent_id' => ['required', 'integer', 'exists:agents,id'], 'direction' => ['required', 'in:credit,debit'], 'amount' => ['required', 'numeric', 'min:0.0001', new DecimalNumber()], 'remark' => ['required', 'string', 'max:500'], 'request_id' => ['required', 'string', 'max:64'], ]); $root = $this->currentAgent(); if ((int) $data['agent_id'] === (int) $root->id) throw new \RuntimeException('不能给自己转账'); $agents->assertVisible($root, (int) $data['agent_id']); $target = Agent::query()->findOrFail($data['agent_id']); if ($data['direction'] === 'credit' && (int) $target->status !== Agent::STATUS_ENABLED) { throw new \RuntimeException('不能给已禁用代理下发额度'); } $from = $data['direction'] === 'credit' ? (int) $root->id : (int) $data['agent_id']; $to = $data['direction'] === 'credit' ? (int) $data['agent_id'] : (int) $root->id; return $wallets->transfer($from, $to, (string) $data['amount'], $data['remark'], 'agent:' . $root->id . ':' . $data['request_id'], (int) $root->id); }); } }