| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <?php
- namespace App\Services\Agent;
- use App\Models\Agent\Agent;
- use App\Models\Agent\AgentPlanApplication;
- use App\Models\Agent\AgentProfitCommissionProfile;
- use Illuminate\Support\Facades\DB;
- /** 合营盈亏分成方案(只有总后台官方方案)。 */
- class AgentProfitCommissionProfileService
- {
- public function __construct(
- private AgentProfitCommissionAssignmentService $assignments,
- private AgentWalletService $wallets
- ) {
- }
- 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()->whereNull('owner_agent_id');
- if (!empty($params['name'])) $query->where('name', 'like', '%' . $params['name'] . '%');
- $total = (clone $query)->count();
- $list = $query->withCount('agents')->orderBy('margin_amount')->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) {
- $profile = empty($data['id'])
- ? new AgentProfitCommissionProfile()
- : AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')->lockForUpdate()->findOrFail($data['id']);
- $name = trim((string) $data['name']);
- if ($name === '') throw new \InvalidArgumentException('方案名称不能为空');
- $duplicate = AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')->where('name', $name)
- ->when($profile->exists, fn ($query) => $query->where('id', '<>', $profile->id))->exists();
- if ($duplicate) throw new \InvalidArgumentException('方案名称已存在');
- $profile->name = $name;
- $profile->margin_amount = bcadd((string) $data['margin_amount'], '0', 4);
- foreach (AgentProfitCommissionProfile::RATE_FIELDS as $field) {
- $profile->{$field} = bcadd((string) $data[$field], '0', 4);
- }
- if (!$profile->exists) $profile->is_default = 0;
- $changed = $profile->exists && $profile->isDirty(array_merge(AgentProfitCommissionProfile::RATE_FIELDS, ['margin_amount', 'name']));
- $profile->save();
- if ($changed) {
- // 已在使用该方案的代理:比例从现在起按新值计算,并按新保证金重新判断是否继续分成。
- $agentIds = Agent::query()->where('profit_commission_profile_id', $profile->id)->pluck('id')->all();
- $this->assignments->assignMany($agentIds, $profile, $adminId);
- foreach ($agentIds as $agentId) {
- $this->wallets->evaluateActivation(Agent::query()->lockForUpdate()->findOrFail($agentId));
- }
- }
- return $profile->fresh();
- });
- }
- public function delete(int $id): void
- {
- DB::transaction(function () use ($id) {
- $profile = AgentProfitCommissionProfile::query()->whereNull('owner_agent_id')->lockForUpdate()->findOrFail($id);
- if (Agent::query()->where('profit_commission_profile_id', $profile->id)->exists()) {
- throw new \RuntimeException('仍有代理使用该方案,不能删除');
- }
- if (AgentPlanApplication::query()->where('profile_id', $profile->id)->where('status', AgentPlanApplication::STATUS_PENDING)->exists()) {
- throw new \RuntimeException('该方案有待审核的申请,不能删除');
- }
- $profile->delete();
- });
- }
- }
|