模拟校正号源

main
鹿和sa0ChunLuyu 4 days ago
parent b1dc20a8c5
commit 29574ce526

@ -1228,4 +1228,17 @@ public function BatchChangeLocked(Request $request)
return \Yz::echoError1('批量占位失败'); return \Yz::echoError1('批量占位失败');
} }
} }
//测试校正号源(只读,不更新数据库)
public function CorrectUsedCountTest(Request $request, PlanListService $planListService)
{
$rosterId = request('roster_id');
$result = $planListService->calculateUsedCount($rosterId);
// calculateUsedCount 返回数组(成功)或 Yz::echoError1 的响应
if (is_array($result)) {
return \Yz::Return(true, '计算完成', $result);
}
return $result;
}
} }

@ -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 回写执行科室
* 在事务提交后调用,异常不影响主流程 * 在事务提交后调用,异常不影响主流程

@ -0,0 +1,22 @@
-- 科室检查项目配置表
-- 覆盖表模式:存储科室级别的检查项目个性化配置,查询时 LEFT JOIN s_check_item 用 COALESCE 取值
-- 一个检查项目在一个科室只存一条覆盖记录
CREATE TABLE `s_dept_check_item` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键',
`check_item_id` int(10) UNSIGNED NOT NULL COMMENT '关联 s_check_item.id',
`department_id` int(10) UNSIGNED NOT NULL COMMENT '关联 s_department.id当前科室',
`reservation_method` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL COMMENT '预约方式逗号分隔的ID串',
`limosis` tinyint(4) NULL DEFAULT NULL COMMENT '是否空腹 1是 0否',
`check_time` int(11) NULL DEFAULT NULL COMMENT '检查时长,单位分钟',
`check_begin_time` int(11) NULL DEFAULT NULL COMMENT '医嘱开具后等待时间,单位分钟',
`check_notice` varchar(8000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '检查须知',
`warm_tips` varchar(8000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '温馨提示',
`use_seats` int(10) NULL DEFAULT 1 COMMENT '占用号源数默认1',
`is_share_slot` tinyint(1) NULL DEFAULT 0 COMMENT '是否共享号源 0否 1是',
`created_at` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
`updated_at` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_check_item_dept` (`check_item_id`, `department_id`) USING BTREE,
INDEX `idx_department_id` (`department_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '科室检查项目配置表' ROW_FORMAT = Dynamic;

@ -143,6 +143,7 @@
Route::post('admin/PlanListBatchChangeCount','App\Http\Controllers\API\Admin\YeWu\PlanListController@BatchChangeCount');//批量修改号源数量(不修改占位) Route::post('admin/PlanListBatchChangeCount','App\Http\Controllers\API\Admin\YeWu\PlanListController@BatchChangeCount');//批量修改号源数量(不修改占位)
Route::post('admin/PlanListBatchChangeLocked','App\Http\Controllers\API\Admin\YeWu\PlanListController@BatchChangeLocked');//批量修改号源占位(不修改数量) Route::post('admin/PlanListBatchChangeLocked','App\Http\Controllers\API\Admin\YeWu\PlanListController@BatchChangeLocked');//批量修改号源占位(不修改数量)
Route::post('admin/SaveLockedCount','App\Http\Controllers\API\Admin\YeWu\PlanListController@SaveLockedCount');//保存占位数量 Route::post('admin/SaveLockedCount','App\Http\Controllers\API\Admin\YeWu\PlanListController@SaveLockedCount');//保存占位数量
Route::post('admin/PlanListCorrectUsedCountTest','App\Http\Controllers\API\Admin\YeWu\PlanListController@CorrectUsedCountTest');//测试校正号源(只读)
Route::post('admin/GetMainList','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetList');//获取主表列表 Route::post('admin/GetMainList','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetList');//获取主表列表
Route::post('admin/GetMainListByDept','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetListByDept');//管理员获取主表列表(支持科室切换) Route::post('admin/GetMainListByDept','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetListByDept');//管理员获取主表列表(支持科室切换)
Route::post('admin/GetLoglist','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetLoglist');//获取日志 Route::post('admin/GetLoglist','App\Http\Controllers\API\Admin\YeWu\WorkMainController@GetLoglist');//获取日志

Loading…
Cancel
Save