get(); $processedApps = []; $totalOrders = 0; $totalFee = '0.0000000000'; foreach ($apps as $app) { $result = self::processAppStatistics($app, $date); $processedApps[] = $result; $totalOrders += $result['total_orders']; $totalFee = bcadd($totalFee, $result['total_fee'], 10); } return [ 'date' => $date, 'apps' => $processedApps, 'summary' => [ 'processed_apps' => count($processedApps), 'total_orders' => $totalOrders, 'total_fee' => $totalFee ] ]; } /** * 处理单个应用的统计 * * @param TransferApp $app 应用 * @param string $date 统计日期 * @return array */ public static function processAppStatistics(TransferApp $app, string $date): array { // 构建当天的时间范围 $startTime = $date . ' 00:00:00'; $endTime = $date . ' 23:59:59'; // 查询当天完成的所有订单 $orders = TransferOrder::where('transfer_app_id', $app->id) ->where('status', TransferStatus::COMPLETED) ->whereBetween('completed_at', [$startTime, $endTime]) ->orderBy('id') ->get(); if ($orders->isEmpty()) { return [ 'app_id' => $app->id, 'app_name' => $app->keyname, 'total_orders' => 0, 'total_fee' => '0.0000000000', 'message' => '当天无已完成订单' ]; } // 计算统计数据 $stats = self::calculateOrderStats($orders); $stats['stat_date'] = $date; $stats['transfer_app_id'] = $app->id; // 保存统计数据 TransferFeeDailyStats::createOrUpdate($stats); return [ 'app_id' => $app->id, 'app_name' => $app->keyname, 'total_orders' => $stats['total_order_count'], 'total_fee' => $stats['total_fee_amount'], 'message' => '统计完成' ]; } /** * 计算订单统计数据 * * @param \Illuminate\Database\Eloquent\Collection $orders 订单集合 * @return array */ public static function calculateOrderStats($orders): array { $inOrders = $orders->where('type', TransferType::IN); $outOrders = $orders->where('type', TransferType::OUT); // 转入统计 $inOrderCount = $inOrders->count(); $inTotalAmount = $inOrders->sum('amount'); $inFeeAmount = $inOrders->sum('fee_amount'); $inAvgFeeRate = $inOrderCount > 0 ? $inOrders->avg('fee_rate') : 0; // 转出统计 $outOrderCount = $outOrders->count(); $outTotalAmount = $outOrders->sum('amount'); $outFeeAmount = $outOrders->sum('fee_amount'); $outAvgFeeRate = $outOrderCount > 0 ? $outOrders->avg('fee_rate') : 0; // 总计统计 $totalOrderCount = $orders->count(); $totalAmount = $orders->sum('amount'); $totalFeeAmount = $orders->sum('fee_amount'); $avgFeeRate = $totalOrderCount > 0 ? $orders->avg('fee_rate') : 0; return [ 'in_order_count' => $inOrderCount, 'in_total_amount' => $inTotalAmount, 'in_fee_amount' => $inFeeAmount, 'in_avg_fee_rate' => $inAvgFeeRate, 'out_order_count' => $outOrderCount, 'out_total_amount' => $outTotalAmount, 'out_fee_amount' => $outFeeAmount, 'out_avg_fee_rate' => $outAvgFeeRate, 'total_order_count' => $totalOrderCount, 'total_amount' => $totalAmount, 'total_fee_amount' => $totalFeeAmount, 'avg_fee_rate' => $avgFeeRate, ]; } /** * 获取指定日期范围的统计数据 * * @param string $startDate 开始日期 * @param string $endDate 结束日期 * @param int $appId 应用ID * @return array */ public static function getStatsByDateRange(string $startDate, string $endDate, int $appId ): array { $data = TransferFeeDailyStats::getByDateRange($startDate, $endDate, $appId); // 计算汇总数据 $summary = [ 'total_days' => $data->count(), 'total_orders' => $data->sum('total_order_count'), 'total_amount' => $data->sum('total_amount'), 'total_fee' => $data->sum('total_fee_amount'), 'avg_fee_rate' => $data->avg('avg_fee_rate'), 'total_in_orders' => $data->sum('in_order_count'), 'total_in_fee' => $data->sum('in_fee_amount'), 'total_out_orders' => $data->sum('out_order_count'), 'total_out_fee' => $data->sum('out_fee_amount'), ]; return [ 'data' => $data->toArray(), 'summary' => $summary, 'date_range' => [ 'start' => $startDate, 'end' => $endDate ] ]; } /** * 获取月度统计数据 * * @param int $year 年份 * @param int $month 月份 * @param int $appId 应用ID * @return array */ public static function getMonthlyStats(int $year, int $month, int $appId = 0): array { return TransferFeeDailyStats::getMonthlyStats($year, $month, $appId); } /** * 获取应用汇总统计 * * @param int $appId 应用ID * @return array */ public static function getAppSummary(int $appId = 0): array { $data = TransferFeeDailyStats::getAppSummary($appId); return [ 'data' => $data, 'total_apps' => count($data) ]; } /** * 获取手续费收入排行榜 * * @param string $startDate 开始日期 * @param string $endDate 结束日期 * @param int $limit 限制数量 * @return array */ public static function getFeeRanking(string $startDate, string $endDate, int $limit = 10): array { $data = TransferFeeDailyStats::with('transferApp') ->whereBetween('stat_date', [$startDate, $endDate]) ->selectRaw(' transfer_app_id, SUM(total_fee_amount) as total_fee, SUM(total_order_count) as total_orders, AVG(avg_fee_rate) as avg_fee_rate ') ->groupBy('transfer_app_id') ->orderBy('total_fee', 'desc') ->limit($limit) ->get(); return [ 'data' => $data->toArray(), 'date_range' => [ 'start' => $startDate, 'end' => $endDate ] ]; } /** * 重新统计指定日期的数据 * * @param string $date 统计日期 * @param int $appId 应用ID * @return array */ public static function restatistics(string $date, int $appId = 0): array { if ($appId > 0) { // 重新统计指定应用 $app = TransferApp::findOrFail($appId); // 删除原有统计数据 TransferFeeDailyStats::where('stat_date', $date) ->where('transfer_app_id', $appId) ->delete(); // 重新统计 $result = self::processAppStatistics($app, $date); return [ 'date' => $date, 'app_id' => $appId, 'result' => $result ]; } else { // 重新统计所有应用 TransferFeeDailyStats::where('stat_date', $date)->delete(); return self::runDailyStatistics($date); } } /** * 验证统计数据的完整性 * * @param string $date 检查日期 * @return array */ public static function validateStatistics(string $date): array { $apps = TransferApp::where('is_enabled', true)->get(); $validationResults = []; $allValid = true; foreach ($apps as $app) { $statsRecord = TransferFeeDailyStats::getByDateAndApp($date, $app->id); if (!$statsRecord) { $validationResults[] = [ 'app_id' => $app->id, 'app_name' => $app->keyname, 'valid' => false, 'message' => '缺少统计记录' ]; $allValid = false; continue; } // 验证订单数据一致性 - 使用时间范围查询 $startTime = $date . ' 00:00:00'; $endTime = $date . ' 23:59:59'; $actualOrders = TransferOrder::where('transfer_app_id', $app->id) ->where('status', TransferStatus::COMPLETED) ->whereBetween('completed_at', [$startTime, $endTime]) ->get(); $actualStats = self::calculateOrderStats($actualOrders); $isValid = ( $statsRecord->total_order_count == $actualStats['total_order_count'] && bccomp($statsRecord->total_fee_amount, $actualStats['total_fee_amount'], 10) == 0 ); $validationResults[] = [ 'app_id' => $app->id, 'app_name' => $app->keyname, 'valid' => $isValid, 'message' => $isValid ? '数据一致' : '数据不一致', 'recorded_orders' => $statsRecord->total_order_count, 'actual_orders' => $actualStats['total_order_count'], 'recorded_fee' => $statsRecord->total_fee_amount, 'actual_fee' => $actualStats['total_fee_amount'] ]; if (!$isValid) { $allValid = false; } } return [ 'date' => $date, 'valid' => $allValid, 'details' => $validationResults ]; } }