| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- <?php
- namespace App\Services\Agent;
- use App\Models\Agent\Agent;
- use App\Models\Agent\AgentPlanApplication;
- use App\Models\Agent\AgentProfitCommissionProfile;
- use App\Models\Agent\AgentSetting;
- use Illuminate\Support\Facades\DB;
- /** 合营代理申请分成方案(方案由总后台配置),总后台审核通过后立即生效。 */
- class AgentPlanApplicationService
- {
- public function __construct(
- private AgentProfitCommissionAssignmentService $assignments,
- private AgentWalletService $wallets
- ) {
- }
- public function plans(Agent $agent): array
- {
- $agent->loadMissing('profitCommissionProfile');
- return [
- 'current_profile' => $agent->profitCommissionProfile,
- 'profit_active' => (int) $agent->profit_active,
- 'margin_stop_percent' => (string) AgentSetting::current()->margin_stop_percent,
- 'pending_application' => AgentPlanApplication::query()->where('agent_id', $agent->id)
- ->where('status', AgentPlanApplication::STATUS_PENDING)->latest('id')->first(),
- 'list' => AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')
- ->orderBy('margin_amount')->orderBy('id')->get(),
- ];
- }
- public function apply(Agent $agent, int $profileId, string $remark = ''): AgentPlanApplication
- {
- return DB::transaction(function () use ($agent, $profileId, $remark) {
- $agent = Agent::query()->lockForUpdate()->findOrFail($agent->id);
- if (!$agent->isJoint()) throw new \RuntimeException('只有合营代理可以申请分成方案');
- $profile = AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')->findOrFail($profileId);
- if ((int) $agent->profit_commission_profile_id === (int) $profile->id) throw new \RuntimeException('已在使用该方案');
- if (AgentPlanApplication::query()->where('agent_id', $agent->id)->where('status', AgentPlanApplication::STATUS_PENDING)->exists()) {
- throw new \RuntimeException('已有待审核的方案申请');
- }
- return AgentPlanApplication::query()->create([
- 'agent_id' => $agent->id, 'profile_id' => $profile->id, 'profile_name' => $profile->name,
- 'status' => AgentPlanApplication::STATUS_PENDING, 'remark' => trim($remark),
- ]);
- });
- }
- public function paginate(array $params, ?Agent $agent = null): array
- {
- $page = max(1, (int) ($params['page'] ?? 1));
- $limit = min(100, max(1, (int) ($params['limit'] ?? 20)));
- $query = AgentPlanApplication::query()->with(['agent:id,username,real_name,balance,margin_amount', 'profile']);
- if ($agent) $query->where('agent_id', $agent->id);
- if (!empty($params['agent_id'])) $query->where('agent_id', (int) $params['agent_id']);
- if (!empty($params['status'])) $query->where('status', $params['status']);
- if (!empty($params['username'])) {
- $query->whereHas('agent', fn ($q) => $q->where('username', 'like', '%' . $params['username'] . '%'));
- }
- $total = (clone $query)->count();
- $list = $query->orderByDesc('id')->forPage($page, $limit)->get();
- return compact('total', 'page', 'limit', 'list');
- }
- public function audit(int $id, string $status, int $adminId, string $reason = ''): AgentPlanApplication
- {
- return DB::transaction(function () use ($id, $status, $adminId, $reason) {
- $application = AgentPlanApplication::query()->lockForUpdate()->findOrFail($id);
- if ($application->status !== AgentPlanApplication::STATUS_PENDING) throw new \RuntimeException('申请已审核');
- $agent = Agent::query()->lockForUpdate()->findOrFail($application->agent_id);
- if ($status === AgentPlanApplication::STATUS_APPROVED) {
- $profile = AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')->find($application->profile_id);
- if (!$profile) throw new \RuntimeException('方案已删除,请驳回');
- if (!$agent->isJoint()) throw new \RuntimeException('只有合营代理可以使用分成方案');
- $agent->profit_commission_profile_id = $profile->id;
- $agent->save();
- $this->assignments->assign($agent, $profile, $adminId);
- $this->wallets->evaluateActivation($agent, true);
- } else {
- $reason = trim($reason);
- if ($reason === '') throw new \InvalidArgumentException('请填写驳回原因');
- $application->reject_reason = $reason;
- }
- $application->status = $status;
- $application->reviewed_by = $adminId;
- $application->reviewed_at = now();
- $application->save();
- return $application->fresh(['agent:id,username,profit_active', 'profile']);
- });
- }
- }
|