| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- <?php
- namespace App\Services\Agent;
- use App\Models\Agent\Agent;
- use App\Models\Agent\AgentProfitCommissionProfile;
- use Illuminate\Support\Facades\DB;
- class AgentProfitCommissionProfileService
- {
- public function __construct(private AgentProfitCommissionAssignmentService $assignments)
- {
- }
- public function paginate(array $params): array
- {
- $page = max(1, (int) ($params['page'] ?? 1));
- $limit = min(100, max(1, (int) ($params['limit'] ?? 20)));
- $query = AgentProfitCommissionProfile::query();
- if (!empty($params['name'])) $query->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();
- });
- }
- }
|