ShareMemberQualification.php 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. <?php
  2. namespace App\Services\Sharing;
  3. use Carbon\Carbon;
  4. use Illuminate\Support\Facades\DB;
  5. /** Read-only qualification shared by commission projection and reporting. */
  6. class ShareMemberQualification
  7. {
  8. public function read(string $date, bool $withMembers = true): array
  9. {
  10. $value = Carbon::createFromFormat('!Y-m-d', $date, ShareDefaults::TIMEZONE);
  11. if (!$value || $value->toDateString() !== $date) throw new \InvalidArgumentException('日期格式必须为Y-m-d');
  12. $missing = [];
  13. $schema = DB::connection()->getSchemaBuilder();
  14. foreach (['share_policies', 'share_system_state', 'share_bet_facts', 'users', 'balance_logs'] as $table) {
  15. if (!$schema->hasTable($table)) $missing[] = 'missing_table:' . $table;
  16. }
  17. $policy = in_array('missing_table:share_policies', $missing, true) ? null
  18. : DB::table('share_policies')->where('effective_date', '<=', $date)->orderByDesc('effective_date')->first();
  19. if (!$policy) $missing[] = 'no_effective_policy';
  20. elseif (($policy->valid_member_min_deposit ?? null) === null || ($policy->valid_member_min_effective_bet ?? null) === null) $missing[] = 'incomplete_qualification_policy';
  21. if (!in_array('missing_table:share_system_state', $missing, true)
  22. && !DB::table('share_system_state')->where('key', 'initialized_at')->exists()) $missing[] = 'relations_not_initialized';
  23. $meta = ['id' => $policy ? (int) $policy->id : null, 'effective_date' => $policy->effective_date ?? null,
  24. 'min_deposit' => isset($policy->valid_member_min_deposit) ? bcadd((string) $policy->valid_member_min_deposit, '0', 10) : null,
  25. 'min_effective_bet' => isset($policy->valid_member_min_effective_bet) ? bcadd((string) $policy->valid_member_min_effective_bet, '0', 10) : null,
  26. 'date' => $date, 'available' => !$missing, 'unavailable_reasons' => $missing];
  27. $result = ['policy' => $policy, 'policy_meta' => $meta, 'currency' => (string) config('third_game.currency', 'CNY'),
  28. 'users' => collect(), 'deposits' => collect(), 'effective' => collect(), 'qualified' => []];
  29. if ($missing || !$withMembers) return $result;
  30. $end = $date . ' 23:59:59';
  31. $result['users'] = DB::table('users')->where('from', '<>', 2)
  32. ->where(function ($q) use ($end) { $q->where('created_at', '<=', $end)->orWhereNull('created_at'); })
  33. ->get(['id', 'member_id'])->keyBy('id');
  34. $result['deposits'] = DB::table('balance_logs')->where('type', 1)->where('amount', '>', 0)
  35. ->whereIn('change_type', ['充值', '三方充值'])->where('created_at', '<=', $end)
  36. ->select('member_id')->selectRaw('SUM(amount) AS total')->groupBy('member_id')->pluck('total', 'member_id');
  37. $result['effective'] = DB::table('share_bet_facts')->where('settled', 1)->where('voided', 0)
  38. ->where('currency', $result['currency'])->where('bet_date', '<=', $date)
  39. ->select('user_id')->selectRaw('SUM(effective_amount) AS total')->groupBy('user_id')->pluck('total', 'user_id');
  40. foreach ($result['users'] as $id => $user) {
  41. if (bccomp((string) ($result['deposits'][$user->member_id] ?? 0), $meta['min_deposit'], 10) >= 0
  42. && bccomp((string) ($result['effective'][$id] ?? 0), $meta['min_effective_bet'], 10) >= 0) $result['qualified'][(int) $id] = true;
  43. }
  44. return $result;
  45. }
  46. }