diff --git a/app/Http/Controllers/Admin/StatisticsController.php b/app/Http/Controllers/Admin/StatisticsController.php index e7dd704..52add5f 100755 --- a/app/Http/Controllers/Admin/StatisticsController.php +++ b/app/Http/Controllers/Admin/StatisticsController.php @@ -474,28 +474,80 @@ class StatisticsController extends CommonController })->paginate(40); $data->appends($request->all())->render(); - $product = Product::where('project_id', $project_id)->first(); - $productItem = ProductItems::where('product_id', $product->id)->get(); - $factor = FactorItems::where('factor_id', $product->statistic_factor_id)->get(); + // ===== 重构:先从 OrderItems 获取真实价格数据,生成列,然后再统计每个病区的数据 ===== + // 1. 获取当前分页中所有病区的床位 ID + $areaIds = collect($data->items())->pluck('id'); + $beds = Bed::whereIn('area_id', $areaIds)->get(); + $bedsByArea = $beds->groupBy('area_id'); + $allBedIds = $beds->pluck('id'); + + // 2. 获取这些床位在当月的所有真实子订单(仅统计 total > 0,且属于当前项目) + $orderItems = OrderItems::whereIn('bed_id', $allBedIds) + ->where('total', '>', 0) + ->where('paid_at', 'like', '%' . $month . '%') + ->whereHas('order', function ($query) use ($project_id) { + $query->where('project_id', $project_id); + }) + ->get(); + + // 3. 按「真实价格」去重生成表头列(xx元/天),并取一条样本数据上的因子名称作为小字说明 + $columns = $orderItems + ->groupBy(function ($item) { + return (float) $item->total; // 以真实 total 作为价格分组键 + }) + ->map(function ($group) { + /** @var OrderItems $sample */ + $sample = $group->first(); + $price = (float) $sample->total; + + $factor_item_name = ''; + $factors = json_decode($sample->factors, true) ?: []; + if (!empty($factors)) { + // 取第一条因子作为说明文本(前端展示不变:价格 + 小字) + $factor_item_name = $factors[0]['factor_item_name'] ?? ''; + } + + return [ + 'price' => $price, + 'name' => $price . '元/天', + 'factor_item_name' => $factor_item_name, + ]; + }) + ->sortBy('price') + ->values() + ->toArray(); + // 4. 按病区 + 列价格 统计每个病区在每个价格档位上的总金额 $sumOrderTotal = 0; foreach ($data as $item) { - // 获取所有床位id - $bedIds = Bed::where('area_id', $item->id)->pluck('id'); - // 总和 - $item->order_total = OrderItems::whereIn('product_item_id', $productItem->pluck('id')) - ->whereIn("bed_id", $bedIds) - ->where('paid_at', 'like', '%' . $month . '%') - ->sum('total'); + // 当前病区所有床位 ID + $bedIds = $bedsByArea->get($item->id, collect())->pluck('id'); + + // 当前病区相关的所有子订单 + $areaOrderItems = $orderItems->whereIn('bed_id', $bedIds->all()); + + // 病区总收入 + $item->order_total = $areaOrderItems->sum('total'); $sumOrderTotal += $item->order_total; - // 子项 - $item->lies = $this->getLies($bedIds, $productItem, $factor, $month); - } - // 获取所有列(包含价格和 factor_item 名称) - $lie = []; - if (isset($data[0]->lies)) { - $lie = $data[0]->lies; // 直接传递完整的 lies 数组,包含 name 和 factor_item_name + + // 子项:按表头列(价格)统计该病区在各价格档位上的总金额 + $lies = []; + foreach ($columns as $col) { + $price = (float) $col['price']; + $colTotal = $areaOrderItems->where('total', $price)->sum('total'); + + $lies[] = [ + 'name' => $col['name'], + 'factor_item_name' => $col['factor_item_name'], + 'total_price' => $price, + 'total' => $colTotal, + ]; + } + $item->lies = $lies; } + + // 表头列:使用上面生成的真实价格列(包含价格和 factor_item 名称) + $lie = $columns; $months = $this->_getMonths(); return view($this->bladePath . ".huli", compact("sumOrderTotal", "data", "month", "lie", "projects", "project_id"));