PlayedGameService.php 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. <?php
  2. namespace App\Services;
  3. use App\Services\Sharing\ShareDefaults;
  4. use Carbon\Carbon;
  5. use Illuminate\Support\Facades\DB;
  6. /** Read actual orders so historical and not-yet-settled play does not depend on commission synchronization. */
  7. class PlayedGameService
  8. {
  9. public static function forMembers(array $memberIds, ?string $start = null, ?string $end = null): array
  10. {
  11. if ($memberIds === []) return [];
  12. $played = [];
  13. $third = DB::table('third_game_orders as o')->join('users as u', function ($join) {
  14. $join->on('o.user_id', '=', 'u.id')->orWhere(function ($join) {
  15. $join->whereNull('o.user_id')->on('o.member_id', '=', 'u.member_id');
  16. });
  17. })->whereIn('u.member_id', $memberIds)
  18. ->where(function ($query) {
  19. $query->whereNull('o.member_id')->orWhere('o.member_id', '')->orWhereColumn('o.member_id', 'u.member_id');
  20. })
  21. ->whereIn('o.game_type', range(1, 7))->whereIn('o.status', [0, 1])->where('o.bet_amount', '>', 0);
  22. if ($start && $end) $third->whereBetween('o.bet_time', [$start, $end]);
  23. foreach ($third->distinct()->get(['u.member_id', 'o.game_type']) as $row) {
  24. $played[$row->member_id]['third:' . $row->game_type] = true;
  25. }
  26. // sport_order.user_id stores the member ID, unlike third_game_orders.user_id (users.id).
  27. $sources = [
  28. ['sport_order', 'user_id', 'create_time', 'self:sport', 'status', [1], true],
  29. ['sport_game_order', 'member_id', 'created_at', 'self:sport', 'status', [0, 1, 2], false],
  30. ['lhc_order', 'member_id', 'created_at', 'self:lottery', 'lottery_status', [0, 1, 2], true],
  31. ['bets', 'member_id', 'created_at', 'self:lottery', 'status', [1, 2], false],
  32. ['jisu_game_order', 'member_id', 'created_at', 'self:lottery', 'status', [0, 1, 2], false],
  33. ];
  34. $startTimestamp = $start ? Carbon::parse($start, ShareDefaults::TIMEZONE)->timestamp : null;
  35. $endTimestamp = $end ? Carbon::parse($end, ShareDefaults::TIMEZONE)->timestamp : null;
  36. $schema = DB::connection()->getSchemaBuilder();
  37. foreach ($sources as [$table, $memberColumn, $timeColumn, $category, $statusColumn, $statuses, $timestamp]) {
  38. $query = DB::table($table)->whereIn($memberColumn, $memberIds)
  39. ->whereIn($statusColumn, $statuses)->where('amount', '>', 0);
  40. // Historical lottery/sports tables may not contain this optional per-order flag.
  41. if (in_array($table, ['sport_order', 'lhc_order'], true) && $schema->hasColumn($table, 'is_faker')) {
  42. $query->where('is_faker', 0);
  43. }
  44. if ($table === 'sport_order') $query->where('pay_status', 1)->where('return_status', '<>', 2);
  45. if ($start && $end) {
  46. $query->whereBetween($timeColumn, $timestamp
  47. ? [$startTimestamp, $endTimestamp]
  48. : [$start, $end]);
  49. }
  50. foreach ($query->distinct()->pluck($memberColumn) as $memberId) $played[$memberId][$category] = true;
  51. }
  52. $result = [];
  53. foreach ($played as $memberId => $categories) {
  54. // Keep the same names and stable ordering as commission categories.
  55. foreach (ShareDefaults::categories() as $category => $label) {
  56. if (isset($categories[$category])) $result[$memberId][] = ['category' => $category, 'label' => $label];
  57. }
  58. }
  59. return $result;
  60. }
  61. }