parseTimeOption('from'); $to = $this->parseTimeOption('to'); } catch (\InvalidArgumentException $e) { $this->error($e->getMessage()); return self::FAILURE; } if ($from !== null && $to !== null && $from->greaterThan($to)) { $this->error('--from 不能晚于 --to'); return self::FAILURE; } $query = BalanceLog::query() ->whereNotNull('member_id') ->where('member_id', '<>', '') ->whereIn('change_type', ['三方游戏转入', '三方游戏转出']) ->select('member_id'); if ($from !== null) { $query->where('created_at', '>=', $from->format('Y-m-d H:i:s')); } if ($to !== null) { $query->where('created_at', '<=', $to->format('Y-m-d H:i:s')); } $specifiedMemberIds = array_values(array_filter( array_map('strval', (array) $this->option('member_id')) )); if ($specifiedMemberIds !== []) { $query->whereIn('member_id', $specifiedMemberIds); } $memberIds = $query->distinct()->orderBy('member_id')->pluck('member_id'); $this->line("member_id\tthird_game_id\tthird_game_balance"); $count = 0; foreach ($memberIds as $memberId) { $memberId = (string) $memberId; $detail = $service->detail($memberId, true); $balance = ($detail['ok'] ?? false) ? $this->decimal($detail['total_game_balance'] ?? 0) : '查询失败:' . (string) ($detail['msg'] ?? '未知错误'); $this->line(implode("\t", [$memberId, $service->playerId($memberId), $balance])); $count++; } $this->info('共找到 ' . $count . ' 个玩家'); $this->comment('本命令只读:已请求三方当前余额,未回收余额,未修改钱包或流水。'); return self::SUCCESS; } private function parseTimeOption(string $name): ?Carbon { $value = trim((string) $this->option($name)); if ($value === '') { return null; } try { return Carbon::createFromFormat('Y-m-d H:i:s', $value); } catch (\Throwable $e) { throw new \InvalidArgumentException('--' . $name . ' 格式必须为 YYYY-MM-DD HH:MM:SS'); } } private function decimal($value): string { return bcadd(is_numeric($value) ? (string) $value : '0', '0', 10); } }