| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- <?php
- namespace App\Module\Transfer\Commands;
- use App\Module\Transfer\Models\TransferOrder;
- use App\Module\Transfer\Models\TransferApp;
- use App\Module\Transfer\Enums\TransferStatus;
- use App\Module\Transfer\Enums\TransferType;
- use Illuminate\Console\Command;
- use Illuminate\Support\Facades\DB;
- /**
- * Transfer统计命令
- */
- class TransferStatsCommand extends Command
- {
- /**
- * 命令签名
- */
- protected $signature = 'transfer:stats
- {--period=today : 统计周期 (today|yesterday|week|month)}
- {--app= : 指定应用ID}
- {--export= : 导出到文件}';
- /**
- * 命令描述
- */
- protected $description = '显示Transfer模块的统计信息';
- /**
- * 执行命令
- */
- public function handle(): int
- {
- $period = $this->option('period');
- $appId = $this->option('app');
- $exportFile = $this->option('export');
- $this->info("Transfer模块统计报告 - {$period}");
- $this->line(str_repeat('=', 60));
- try {
- // 获取时间范围
- [$startDate, $endDate] = $this->getDateRange($period);
-
- $this->info("统计时间: {$startDate} 至 {$endDate}");
- $this->line('');
- // 基础统计
- $this->showBasicStats($startDate, $endDate, $appId);
-
- // 按应用统计
- $this->showAppStats($startDate, $endDate, $appId);
-
- // 按状态统计
- $this->showStatusStats($startDate, $endDate, $appId);
-
- // 按小时统计(仅当日)
- if ($period === 'today') {
- $this->showHourlyStats($startDate, $endDate, $appId);
- }
- // 导出数据
- if ($exportFile) {
- $this->exportStats($startDate, $endDate, $appId, $exportFile);
- }
- return 0;
- } catch (\Exception $e) {
- $this->error("统计失败: " . $e->getMessage());
- return 1;
- }
- }
- /**
- * 获取日期范围
- */
- private function getDateRange(string $period): array
- {
- return match ($period) {
- 'today' => [
- now()->startOfDay()->toDateTimeString(),
- now()->endOfDay()->toDateTimeString()
- ],
- 'yesterday' => [
- now()->subDay()->startOfDay()->toDateTimeString(),
- now()->subDay()->endOfDay()->toDateTimeString()
- ],
- 'week' => [
- now()->startOfWeek()->toDateTimeString(),
- now()->endOfWeek()->toDateTimeString()
- ],
- 'month' => [
- now()->startOfMonth()->toDateTimeString(),
- now()->endOfMonth()->toDateTimeString()
- ],
- default => throw new \InvalidArgumentException("无效的统计周期: {$period}")
- };
- }
- /**
- * 显示基础统计
- */
- private function showBasicStats(string $startDate, string $endDate, ?string $appId): void
- {
- $query = TransferOrder::whereBetween('created_at', [$startDate, $endDate]);
-
- if ($appId) {
- $query->where('transfer_app_id', $appId);
- }
- $totalOrders = $query->count();
- $totalAmount = $query->sum('amount');
-
- $inOrders = (clone $query)->where('type', TransferType::IN)->count();
- $outOrders = (clone $query)->where('type', TransferType::OUT)->count();
-
- $inAmount = (clone $query)->where('type', TransferType::IN)->sum('amount');
- $outAmount = (clone $query)->where('type', TransferType::OUT)->sum('amount');
-
- $completedOrders = (clone $query)->where('status', TransferStatus::COMPLETED)->count();
- $failedOrders = (clone $query)->where('status', TransferStatus::FAILED)->count();
- $this->info('基础统计:');
- $this->table(
- ['指标', '数值'],
- [
- ['总订单数', number_format($totalOrders)],
- ['总金额', number_format($totalAmount, 2)],
- ['转入订单', number_format($inOrders)],
- ['转出订单', number_format($outOrders)],
- ['转入金额', number_format($inAmount, 2)],
- ['转出金额', number_format($outAmount, 2)],
- ['成功订单', number_format($completedOrders)],
- ['失败订单', number_format($failedOrders)],
- ['成功率', $totalOrders > 0 ? number_format($completedOrders / $totalOrders * 100, 2) . '%' : '0%'],
- ]
- );
- $this->line('');
- }
- /**
- * 显示按应用统计
- */
- private function showAppStats(string $startDate, string $endDate, ?string $appId): void
- {
- $query = DB::table('transfer_orders as o')
- ->join('transfer_apps as a', 'o.transfer_app_id', '=', 'a.id')
- ->whereBetween('o.created_at', [$startDate, $endDate])
- ->select([
- 'a.title as app_name',
- DB::raw('COUNT(*) as total_orders'),
- DB::raw('SUM(o.amount) as total_amount'),
- DB::raw('SUM(CASE WHEN o.type = 1 THEN 1 ELSE 0 END) as in_orders'),
- DB::raw('SUM(CASE WHEN o.type = 2 THEN 1 ELSE 0 END) as out_orders'),
- DB::raw('SUM(CASE WHEN o.status = 100 THEN 1 ELSE 0 END) as completed_orders'),
- ])
- ->groupBy('a.id', 'a.title')
- ->orderBy('total_amount', 'desc');
- if ($appId) {
- $query->where('a.id', $appId);
- }
- $stats = $query->get();
- if ($stats->isNotEmpty()) {
- $this->info('按应用统计:');
- $this->table(
- ['应用名称', '总订单', '总金额', '转入', '转出', '成功', '成功率'],
- $stats->map(function ($stat) {
- $successRate = $stat->total_orders > 0
- ? number_format($stat->completed_orders / $stat->total_orders * 100, 1) . '%'
- : '0%';
-
- return [
- $stat->app_name,
- number_format($stat->total_orders),
- number_format($stat->total_amount, 2),
- number_format($stat->in_orders),
- number_format($stat->out_orders),
- number_format($stat->completed_orders),
- $successRate,
- ];
- })
- );
- $this->line('');
- }
- }
- /**
- * 显示按状态统计
- */
- private function showStatusStats(string $startDate, string $endDate, ?string $appId): void
- {
- $query = TransferOrder::whereBetween('created_at', [$startDate, $endDate])
- ->select([
- 'status',
- DB::raw('COUNT(*) as count'),
- DB::raw('SUM(amount) as amount')
- ])
- ->groupBy('status')
- ->orderBy('status');
- if ($appId) {
- $query->where('transfer_app_id', $appId);
- }
- $stats = $query->get();
- if ($stats->isNotEmpty()) {
- $this->info('按状态统计:');
- $this->table(
- ['状态', '订单数', '金额'],
- $stats->map(function ($stat) {
- $status = TransferStatus::from($stat->status);
- return [
- $status->getDescription(),
- number_format($stat->count),
- number_format($stat->amount, 2),
- ];
- })
- );
- $this->line('');
- }
- }
- /**
- * 显示按小时统计
- */
- private function showHourlyStats(string $startDate, string $endDate, ?string $appId): void
- {
- $query = TransferOrder::whereBetween('created_at', [$startDate, $endDate])
- ->select([
- DB::raw('HOUR(created_at) as hour'),
- DB::raw('COUNT(*) as count'),
- DB::raw('SUM(amount) as amount')
- ])
- ->groupBy(DB::raw('HOUR(created_at)'))
- ->orderBy('hour');
- if ($appId) {
- $query->where('transfer_app_id', $appId);
- }
- $stats = $query->get();
- if ($stats->isNotEmpty()) {
- $this->info('按小时统计:');
- $this->table(
- ['小时', '订单数', '金额'],
- $stats->map(function ($stat) {
- return [
- sprintf('%02d:00', $stat->hour),
- number_format($stat->count),
- number_format($stat->amount, 2),
- ];
- })
- );
- $this->line('');
- }
- }
- /**
- * 导出统计数据
- */
- private function exportStats(string $startDate, string $endDate, ?string $appId, string $filename): void
- {
- $this->info("正在导出统计数据到 {$filename}...");
-
- // 这里可以实现CSV或Excel导出逻辑
- $this->info('导出功能待实现');
- }
- }
|