|
|
|
@ -1873,6 +1873,184 @@ public function correctUsedCount($rosterId)
|
|
|
|
]);
|
|
|
|
]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 测试校正号源:只读计算,不更新数据库
|
|
|
|
|
|
|
|
* 返回当前排班号源占用详情与校正后应占数的对比
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public function calculateUsedCount($rosterId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!$rosterId) {
|
|
|
|
|
|
|
|
return \Yz::echoError1('参数错误:roster_id 不能为空');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 排班基本信息
|
|
|
|
|
|
|
|
$rosterInfo = DB::table('s_source_roster_detail')
|
|
|
|
|
|
|
|
->leftJoin('s_department_resources', 's_source_roster_detail.resources_id', '=', 's_department_resources.id')
|
|
|
|
|
|
|
|
->leftJoin('s_department', 's_source_roster_detail.department_id', '=', 's_department.id')
|
|
|
|
|
|
|
|
->where('s_source_roster_detail.id', $rosterId)
|
|
|
|
|
|
|
|
->select(
|
|
|
|
|
|
|
|
's_source_roster_detail.*',
|
|
|
|
|
|
|
|
's_department_resources.department_resources_name',
|
|
|
|
|
|
|
|
's_department.department_name'
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
->first();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!$rosterInfo) {
|
|
|
|
|
|
|
|
return \Yz::echoError1('排班不存在');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 渠道当前信息
|
|
|
|
|
|
|
|
$channels = DB::table('s_source_roster_detail_count')
|
|
|
|
|
|
|
|
->leftJoin('s_appointment_type', 's_source_roster_detail_count.appointment_type_id', '=', 's_appointment_type.id')
|
|
|
|
|
|
|
|
->where('s_source_roster_detail_count.roster_detail_id', $rosterId)
|
|
|
|
|
|
|
|
->select(
|
|
|
|
|
|
|
|
's_source_roster_detail_count.*',
|
|
|
|
|
|
|
|
's_appointment_type.name as appointment_type_name',
|
|
|
|
|
|
|
|
's_appointment_type.jiancheng'
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取该排班上所有活跃项目及其配置
|
|
|
|
|
|
|
|
$activeItems = DB::table('s_list')
|
|
|
|
|
|
|
|
->join('s_check_item', 's_list.entrust_code', '=', 's_check_item.item_code')
|
|
|
|
|
|
|
|
->where('s_list.roster_id', $rosterId)
|
|
|
|
|
|
|
|
->whereIn('s_list.list_status', [1, 2, 3])
|
|
|
|
|
|
|
|
->where('s_list.is_nullify', 0)
|
|
|
|
|
|
|
|
->where('s_check_item.status', 1)
|
|
|
|
|
|
|
|
->where('s_check_item.is_del', 0)
|
|
|
|
|
|
|
|
->select('s_list.*', 's_check_item.use_seats', 's_check_item.is_share_slot')
|
|
|
|
|
|
|
|
->get();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按患者分组计算占位
|
|
|
|
|
|
|
|
$grouped = [];
|
|
|
|
|
|
|
|
$firstDetail = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($activeItems as $item) {
|
|
|
|
|
|
|
|
$reg = $item->reg_num;
|
|
|
|
|
|
|
|
if (!isset($grouped[$reg])) {
|
|
|
|
|
|
|
|
$grouped[$reg] = [
|
|
|
|
|
|
|
|
'sharedMax' => 0,
|
|
|
|
|
|
|
|
'nonSharedSum' => 0,
|
|
|
|
|
|
|
|
'items' => [],
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$seats = (int)($item->use_seats ?? 1);
|
|
|
|
|
|
|
|
if (!empty($item->is_share_slot)) {
|
|
|
|
|
|
|
|
$grouped[$reg]['sharedMax'] = max($grouped[$reg]['sharedMax'], $seats);
|
|
|
|
|
|
|
|
$grouped[$reg]['items'][] = [
|
|
|
|
|
|
|
|
'id' => $item->id,
|
|
|
|
|
|
|
|
'entrust' => $item->entrust,
|
|
|
|
|
|
|
|
'entrust_code' => $item->entrust_code,
|
|
|
|
|
|
|
|
'list_status' => $item->list_status,
|
|
|
|
|
|
|
|
'type' => '共享',
|
|
|
|
|
|
|
|
'use_seats' => $seats,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
$grouped[$reg]['nonSharedSum'] += $seats;
|
|
|
|
|
|
|
|
$grouped[$reg]['items'][] = [
|
|
|
|
|
|
|
|
'id' => $item->id,
|
|
|
|
|
|
|
|
'entrust' => $item->entrust,
|
|
|
|
|
|
|
|
'entrust_code' => $item->entrust_code,
|
|
|
|
|
|
|
|
'list_status' => $item->list_status,
|
|
|
|
|
|
|
|
'type' => '非共享',
|
|
|
|
|
|
|
|
'use_seats' => $seats,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 记录第一个有 detail 的渠道
|
|
|
|
|
|
|
|
if ($firstDetail === null) {
|
|
|
|
|
|
|
|
$details = json_decode($item->appointment_use_plan_detail, true) ?: [];
|
|
|
|
|
|
|
|
if (!empty($details)) {
|
|
|
|
|
|
|
|
$firstDetail = $details;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算总占位
|
|
|
|
|
|
|
|
$patientOccupancy = [];
|
|
|
|
|
|
|
|
$totalUsed = 0;
|
|
|
|
|
|
|
|
foreach ($grouped as $reg => $g) {
|
|
|
|
|
|
|
|
$patientTotal = $g['sharedMax'] + $g['nonSharedSum'];
|
|
|
|
|
|
|
|
$totalUsed += $patientTotal;
|
|
|
|
|
|
|
|
$patientOccupancy[] = [
|
|
|
|
|
|
|
|
'reg_num' => $reg,
|
|
|
|
|
|
|
|
'shared_max' => $g['sharedMax'],
|
|
|
|
|
|
|
|
'non_shared_sum' => $g['nonSharedSum'],
|
|
|
|
|
|
|
|
'patient_total' => $patientTotal,
|
|
|
|
|
|
|
|
'items' => $g['items'],
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按渠道分配计算
|
|
|
|
|
|
|
|
$channelCalculated = [];
|
|
|
|
|
|
|
|
$hasDiff = false;
|
|
|
|
|
|
|
|
if ($firstDetail && $totalUsed > 0) {
|
|
|
|
|
|
|
|
$totalDetailCount = array_sum(array_column($firstDetail, 'count'));
|
|
|
|
|
|
|
|
foreach ($firstDetail as $d) {
|
|
|
|
|
|
|
|
$cid = $d['roster_detail_count_id'] ?? null;
|
|
|
|
|
|
|
|
if (!$cid) continue;
|
|
|
|
|
|
|
|
$ratio = $totalDetailCount > 0 ? ($d['count'] / $totalDetailCount) : 0;
|
|
|
|
|
|
|
|
$channelUsed = (int)round($totalUsed * $ratio);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$current = $channels->firstWhere('id', $cid);
|
|
|
|
|
|
|
|
$currentUsed = $current ? (int)$current->used_count : 0;
|
|
|
|
|
|
|
|
$diff = $channelUsed - $currentUsed;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$channelCalculated[] = [
|
|
|
|
|
|
|
|
'id' => $cid,
|
|
|
|
|
|
|
|
'appointment_type_id' => $current->appointment_type_id ?? null,
|
|
|
|
|
|
|
|
'appointment_type_name' => $current->appointment_type_name ?? null,
|
|
|
|
|
|
|
|
'count' => $current ? (int)$current->count : 0,
|
|
|
|
|
|
|
|
'current_used_count' => $currentUsed,
|
|
|
|
|
|
|
|
'calculated_used_count' => $channelUsed,
|
|
|
|
|
|
|
|
'locked_count' => $current ? (int)$current->locked_count : 0,
|
|
|
|
|
|
|
|
'diff' => $diff,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
if ($diff !== 0) {
|
|
|
|
|
|
|
|
$hasDiff = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// 无 detail 时,各渠道直接取 totalUsed
|
|
|
|
|
|
|
|
foreach ($channels as $ch) {
|
|
|
|
|
|
|
|
$currentUsed = (int)$ch->used_count;
|
|
|
|
|
|
|
|
$diff = $totalUsed - $currentUsed;
|
|
|
|
|
|
|
|
$channelCalculated[] = [
|
|
|
|
|
|
|
|
'id' => $ch->id,
|
|
|
|
|
|
|
|
'appointment_type_id' => $ch->appointment_type_id,
|
|
|
|
|
|
|
|
'appointment_type_name' => $ch->appointment_type_name,
|
|
|
|
|
|
|
|
'count' => (int)$ch->count,
|
|
|
|
|
|
|
|
'current_used_count' => $currentUsed,
|
|
|
|
|
|
|
|
'calculated_used_count' => $totalUsed,
|
|
|
|
|
|
|
|
'locked_count' => (int)$ch->locked_count,
|
|
|
|
|
|
|
|
'diff' => $diff,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
if ($diff !== 0) {
|
|
|
|
|
|
|
|
$hasDiff = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
|
|
|
'roster_id' => (int)$rosterId,
|
|
|
|
|
|
|
|
'roster_info' => [
|
|
|
|
|
|
|
|
'date' => $rosterInfo->date,
|
|
|
|
|
|
|
|
'begin_time' => $rosterInfo->begin_time,
|
|
|
|
|
|
|
|
'end_time' => $rosterInfo->end_time,
|
|
|
|
|
|
|
|
'weekname' => $rosterInfo->weekname,
|
|
|
|
|
|
|
|
'patient_type' => $rosterInfo->patient_type,
|
|
|
|
|
|
|
|
'department_name' => $rosterInfo->department_name,
|
|
|
|
|
|
|
|
'resources_name' => $rosterInfo->department_resources_name,
|
|
|
|
|
|
|
|
],
|
|
|
|
|
|
|
|
'active_item_count' => $activeItems->count(),
|
|
|
|
|
|
|
|
'patient_occupancy' => $patientOccupancy,
|
|
|
|
|
|
|
|
'total_used' => $totalUsed,
|
|
|
|
|
|
|
|
'channels' => $channelCalculated,
|
|
|
|
|
|
|
|
'has_diff' => $hasDiff,
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 预约完成后通知 HIS 回写执行科室
|
|
|
|
* 预约完成后通知 HIS 回写执行科室
|
|
|
|
* 在事务提交后调用,异常不影响主流程
|
|
|
|
* 在事务提交后调用,异常不影响主流程
|
|
|
|
|