Merge branch 'master' of ssh://118.31.104.155:4422/mnt/git/v2.tiantianxinye.365care

master
weizong song 3 months ago
commit 03f078a8f3

@ -136,12 +136,18 @@ class HomeController extends CommonController
$list = [];
foreach ($productItem as $item) {
foreach ($factor as $factor_item) {
// 修复:使用 MySQL 5.7 的 JSON 函数进行精确查询防止SQL注入
$factorItemId = (int) $factor_item->id;
$total = OrderItems::where('product_item_id', $item->id)
->whereRaw("factors like '%\"factor_item_id\": $factor_item->id%'")
->whereRaw("JSON_SEARCH(factors, 'one', ?, NULL, '$[*].factor_item_id') IS NOT NULL", [$factorItemId])
->sum('total');
$list [] = [
'name' => $item->price + $factor_item->price . '元/天',
'total_price' => $item->price + $factor_item->price,
// 修复:明确计算价格总和,避免运算符优先级问题
$totalPrice = (float) $item->price + (float) $factor_item->price;
$list[] = [
'name' => $totalPrice . '元/天',
'total_price' => $totalPrice,
'product_item_id' => $item->id,
'factor_item_id' => $factor_item->id,
'total' => $total,

@ -21,6 +21,7 @@ use App\Models\Orders;
use App\Models\Paramedic;
use App\Models\Product;
use App\Models\ProductItems;
use App\Models\ProductParamedicLevel;
use App\Models\Project;
use App\Models\Recharge;
use App\Models\Refund;
@ -94,17 +95,29 @@ class StatisticsController extends CommonController
$query->where("project_id", $project_id);
})->pluck("paramedic_id")->toArray();
$query->where("project_id", $project_id)->orWhereIn("id", $order_item_paramedic_ids);
})->with(["orderItems" => function ($query) use ($month, $project_id) {
$query->whereRaw("(DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}' or DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}')")
->where("total", ">", 0)
->whereHas("order", function ($query) use ($project_id) {
$query->where("project_id", $project_id);
})
->with(["order", "product", "productItem", "productParamedicLevel", "paramedic" => function ($query) {
$query->withoutGlobalScope(AdminProjectScope::class);
}, "bed", "room", "building", "area"])
->orderBy("id");
}])->get();
})->with([
"orderItems" => function ($query) use ($month, $project_id) {
$query->whereRaw("(DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}' or DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}')")
->where("total", ">", 0)
->whereHas("order", function ($query) use ($project_id) {
$query->where("project_id", $project_id);
})
->with([
"order",
"product",
"productItem",
"productParamedicLevel",
"paramedic" => function ($query) {
$query->withoutGlobalScope(AdminProjectScope::class);
},
"bed",
"room",
"building",
"area"
])
->orderBy("id");
}
])->get();
$allItems = collect();
foreach ($paramedics as $paramedic) {
@ -209,8 +222,10 @@ class StatisticsController extends CommonController
$factors = json_decode($orderItem->factors, true);
$parent_factors = json_decode($orderItem->order->factors, true);
if (!in_array("所在科室", collect($factors)->pluck("factor_name")->toArray())
&& in_array("所在科室", collect($parent_factors)->pluck("factor_name")->toArray())) {
if (
!in_array("所在科室", collect($factors)->pluck("factor_name")->toArray())
&& in_array("所在科室", collect($parent_factors)->pluck("factor_name")->toArray())
) {
$add = collect($parent_factors)->keyBy("factor_name")["所在科室"];
$factors[] = $add;
$orderItem->update([
@ -338,16 +353,16 @@ class StatisticsController extends CommonController
"patients" => function ($query) use ($before_datetime) {
$query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc");
},
// "oneBalance" => function ($query) use ($before_datetime) {
// "oneBalance" => function ($query) use ($before_datetime) {
// $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc");
// }
])
// ->whereHas("oneBalance", function ($query) use ($before_datetime) {
// ->whereHas("oneBalance", function ($query) use ($before_datetime) {
// $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->where("balance", ">", 0)->orderBy("id", "desc");
// })
->whereHas("orders", function ($query) use ($before_datetime, $project_id) {
$query
// ->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")
// ->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")
->where("project_id", $project_id);
})
->get();
@ -459,27 +474,81 @@ 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元/天),并取一条样本数据上的因子名称作为小字说明
// 使用 groupBy('total'),避免闭包分组可能导致的 array_key_exists 问题
$columns = $orderItems
->groupBy('total')
->map(function ($group, $total) {
/** @var OrderItems $sample */
$sample = $group->first();
$price = (float) $total;
$factor_item_name = '';
if ($sample && $sample->factors) {
$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);
}
// 获取所有列
$lie = [];
if (isset($data[0]->lies)) {
$lie = array_column($data[0]->lies, '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"));
@ -491,16 +560,33 @@ class StatisticsController extends CommonController
public function getLies($bedIds, $productItem, $factor, $month)
{
$list = [];
// 修复如果床位ID为空直接返回空数组避免 whereIn 空数组导致的SQL错误
if (empty($bedIds)) {
return $list;
}
foreach ($productItem as $item) {
foreach ($factor as $factor_item) {
$total = OrderItems::where('product_item_id', $item->id)
$query = OrderItems::where('product_item_id', $item->id)
->whereIn("bed_id", $bedIds)
->whereRaw("factors like '%\"factor_item_id\": $factor_item->id%'")
->where('paid_at', 'like', '%' . $month . '%')
->sum('total');
$list [] = [
'name' => $item->price + $factor_item->price . '元/天',
'total_price' => $item->price + $factor_item->price,
->where('paid_at', 'like', '%' . $month . '%');
// 使用 MySQL 5.7 的 JSON_SEARCH 精确匹配包含指定 factor_item_id 的子订单
$factorItemId = (int) $factor_item->id;
$query->whereRaw("JSON_SEARCH(factors, 'one', ?, NULL, '$[*].factor_item_id') IS NOT NULL", [$factorItemId]);
// 1列对应的真实总收入该因子 + 产品子项 + 病区 + 月份 下所有子订单的 total 之和
$total = (float) $query->sum('total');
// 2表头展示的价格按“公式”计算保证不是 0近似真实下单价
// 价格 = 产品子项基础价 + 因子价格
$totalPrice = (float) $item->price + (float) $factor_item->price;
$list[] = [
'name' => $totalPrice . '元/天',
'factor_item_name' => $factor_item->name ?? '',
'total_price' => $totalPrice,
'product_item_id' => $item->id,
'factor_item_id' => $factor_item->id,
'total' => $total

@ -0,0 +1 @@
XuhBUEvx2PXOhnrLb2lfM2is3XbaBhBOXl8SMmUHv0s.5-N8Ip449Q-0w2bLgJMR9BQtRA8QQojBMyN7wrETK2I

Binary file not shown.

@ -7,11 +7,10 @@
<div class="card-body">
<div class="mb-3">
<form class="form-inline" id="search-form" autocomplete="off">
<select class="form-control mr-1" name="project_id"
onchange="$(this).closest('form').submit()">
<select class="form-control mr-1" name="project_id" onchange="$(this).closest('form').submit()">
@foreach($projects as $pp)
<option
value="{{$pp->id}}" @if($pp->id == $project_id) {{ "selected" }}@endif>{{$pp->name}}</option>
<option value="{{$pp->id}}" @if($pp->id == $project_id) {{ "selected" }}@endif>{{$pp->name}}
</option>
@endforeach
</select>
<select class="form-control" name="month" onchange="$(this).closest('form').submit()">
@ -24,40 +23,45 @@
<div>合计:{{$sumOrderTotal}}</div>
<table class="table table-bordered" id="data-table">
<thead>
<tr>
<th>医院</th>
<th>
楼栋
</th>
<th>病区</th>
<th>总收入</th>
@foreach ($lie as $v)
<th>{{$v}}</th>
@endforeach
</tr>
<tr>
<th>医院</th>
<th>
楼栋
</th>
<th>病区</th>
<th>总收入</th>
@if(!empty($lie))
@foreach ($lie as $lieItem)
<th>
<div>{{$lieItem['name'] ?? ''}}</div>
</th>
@endforeach
@endif
</tr>
</thead>
<tbody>
@foreach ($data as $row)
<tr data-id="{{$row->id}}">
<td>
{{ $row->project->name }}
</td>
<td>
{{ $row->building->name }}
</td>
<td>
{{ $row->name }}
</td>
<td>{{ $row->order_total }}</td>
@foreach ($row->lies as $r)
@foreach ($data as $row)
<tr data-id="{{$row->id}}">
<td>
{{$r['total']}}
{{ $row->project->name }}
</td>
@endforeach
<td>
{{ $row->building->name }}
</td>
<td>
{{ $row->name }}
</td>
<td>{{ $row->order_total }}</td>
</tr>
@endforeach
@foreach ($row->lies as $r)
<td>
{{$r['total']}}
</td>
@endforeach
</tr>
@endforeach
</tbody>
</table>
@include("public._pages")
@ -74,4 +78,4 @@
<script>
</script>
@endpush
@endpush
Loading…
Cancel
Save