where('name', 'like', '%' . $params['name'] . '%'); $total = (clone $query)->count(); $list = $query->orderByDesc('is_default')->orderByDesc('id')->forPage($page, $limit)->get(); return compact('total', 'page', 'limit', 'list'); } public function save(array $data, ?int $adminId = null): AgentProfitCommissionProfile { return DB::transaction(function () use ($data, $adminId) { $profiles = AgentProfitCommissionProfile::query()->orderBy('id')->lockForUpdate()->get(['id', 'is_default']); $profile = empty($data['id']) ? new AgentProfitCommissionProfile() : AgentProfitCommissionProfile::query()->lockForUpdate()->findOrFail($data['id']); $oldDefaultId = $profiles->firstWhere('is_default', 1)?->id; $isDefault = !empty($data['is_default']); if ($profile->exists && (int) $oldDefaultId === (int) $profile->id && !$isDefault) { throw new \RuntimeException('默认比例必须始终保留一条,请先将其他比例设为默认'); } $name = trim((string) $data['name']); if ($name === '') throw new \InvalidArgumentException('盈亏比例名称不能为空'); $duplicate = AgentProfitCommissionProfile::query()->where('name', $name) ->when($profile->exists, fn($query) => $query->where('id', '<>', $profile->id))->exists(); if ($duplicate) throw new \InvalidArgumentException('盈亏比例名称已存在'); $profile->name = $name; foreach (AgentProfitCommissionProfile::RATE_FIELDS as $field) $profile->{$field} = (string) $data[$field]; $willBeDefault = $isDefault || (!$profile->exists && !$oldDefaultId); $profile->is_default = $willBeDefault ? 1 : 0; $snapshotChanged = !$profile->exists || $profile->isDirty(AgentProfitCommissionProfile::RATE_FIELDS); $affectedAgentIds = []; if ($snapshotChanged && $profile->exists) { $affectedAgentIds = Agent::query()->where('profit_commission_profile_id', $profile->id) ->pluck('id')->map(fn($id) => (int) $id)->all(); } if ($willBeDefault) { $defaultAgentIds = Agent::query()->where(function ($query) use ($oldDefaultId, $profile) { $query->whereNull('profit_commission_profile_id'); if ($oldDefaultId && (int) $oldDefaultId !== (int) $profile->id) { $query->orWhere('profit_commission_profile_id', $oldDefaultId); } })->pluck('id')->map(fn($id) => (int) $id)->all(); $affectedAgentIds = array_values(array_unique(array_merge($affectedAgentIds, $defaultAgentIds))); } $profile->save(); if ($willBeDefault) { AgentProfitCommissionProfile::query()->where('id', '<>', $profile->id)->update(['is_default' => 0]); Agent::query()->where(function ($query) use ($oldDefaultId) { $query->whereNull('profit_commission_profile_id'); if ($oldDefaultId) $query->orWhere('profit_commission_profile_id', $oldDefaultId); })->update(['profit_commission_profile_id' => $profile->id]); } $this->assignments->assignMany($affectedAgentIds, $profile, now()->toDateString(), $adminId); return $profile->fresh(); }); } public function delete(int $id, ?int $adminId = null): void { DB::transaction(function () use ($id, $adminId) { $profile = AgentProfitCommissionProfile::query()->lockForUpdate()->findOrFail($id); if ((int) $profile->is_default === 1) throw new \RuntimeException('默认比例不能删除'); $default = AgentProfitCommissionProfile::query()->where('is_default', 1)->lockForUpdate()->first(); if (!$default) throw new \RuntimeException('缺少默认比例,不能删除'); $agentIds = Agent::query()->where('profit_commission_profile_id', $profile->id) ->pluck('id')->map(fn($agentId) => (int) $agentId)->all(); $this->assignments->assignMany($agentIds, $default, now()->toDateString(), $adminId); Agent::query()->where('profit_commission_profile_id', $profile->id) ->update(['profit_commission_profile_id' => $default->id]); $profile->delete(); }); } }