From 4b7ec9e0c5e2286905c35d169cd6acfa38589205 Mon Sep 17 00:00:00 2001 From: sa0ChunLuyu Date: Fri, 24 Jul 2026 11:14:19 +0800 Subject: [PATCH] =?UTF-8?q?1=20=E5=9B=9E=E5=86=99HIS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/API/His/HisController.php | 39 +++++ .../Controllers/API/Third/YiJiController.php | 149 ++++++++++++++++ .../Services/Admin/YeWu/PlanListService.php | 162 ++++++++++++++++++ Laravel/routes/api.php | 1 + 4 files changed, 351 insertions(+) diff --git a/Laravel/app/Http/Controllers/API/His/HisController.php b/Laravel/app/Http/Controllers/API/His/HisController.php index 43765fd..8f50d97 100644 --- a/Laravel/app/Http/Controllers/API/His/HisController.php +++ b/Laravel/app/Http/Controllers/API/His/HisController.php @@ -69,6 +69,45 @@ public static function Get($url_code, $data) } + /** + * POST 请求,带日志记录 + */ + public static function Post($url_path, $data) + { + $fullUrl = self::$baseUrl . $url_path; + self::RequestLog($fullUrl, $data, 'HIS回写', 'Roc接口'); + + $response = Http::withHeaders([ + 'Domain' => 'QhdLK_YYGL', + 'Key' => 'f7ed8036-b7a1-41ec-80f6-0e180efba1f4', + 'Content-Type' => 'application/json', + ])->post($fullUrl, $data); + + if ($response->successful()) { + $res_string = json_encode($response->json(), JSON_UNESCAPED_UNICODE); + $str_len = mb_strlen($res_string, 'utf-8'); + $str_size = $str_len / 1024; + $save_res = $res_string; + if ($str_size > 10) $save_res = '{"data":"Row size too large"}'; + self::$request->response_data = $save_res; + self::$request->save(); + + $res = json_decode($res_string, true); + if ($res['code']<>200) { + throw new HttpResponseException(\Yz::JsonError("Roc接口提示:" . $res['msg'])); + } + return [ + 'code' => $res['code'], + 'message' => $res['msg'], + 'data' => $res['data'] + ]; + } else { + self::$request->response_data = "请求Roc接口失败"; + self::$request->save(); + throw new HttpResponseException(\Yz::JsonError("请求Roc接口失败")); + } + } + public static function RequestLog($url, $post_data, $mark, $code = 0) { self::CheckTableName(); diff --git a/Laravel/app/Http/Controllers/API/Third/YiJiController.php b/Laravel/app/Http/Controllers/API/Third/YiJiController.php index 0e36f6c..3d2a855 100644 --- a/Laravel/app/Http/Controllers/API/Third/YiJiController.php +++ b/Laravel/app/Http/Controllers/API/Third/YiJiController.php @@ -361,6 +361,155 @@ function QueryHisShenQingDan() } + /** + * 测试 HIS 回写接口入参收集 + * 根据 s_list ID 查询 HIS 申请单,组装回写所需参数并返回,不实际调用回写接口 + */ + public function TestHisCallbackParams() + { + try { + $id = request('id'); + if (empty($id)) { + return \Yz::JsonReturn(false, '参数 id 不能为空', []); + } + + $sList = DB::table('s_list')->where('id', $id)->first(); + if (!$sList) { + return \Yz::JsonReturn(false, '未找到该记录', []); + } + + $result = [ + 's_list_info' => [ + 'id' => $sList->id, + 'entrust_id' => $sList->entrust_id, + 'entrust_code' => $sList->entrust_code, + 'entrust' => $sList->entrust, + 'reg_num' => $sList->reg_num, + 'episodeid' => $sList->episodeid, + 'app_num' => $sList->app_num, + 'patient_type' => $sList->patient_type, + 'reservation_sources' => $sList->reservation_sources, + 'RISRAcceptDeptCode' => $sList->RISRAcceptDeptCode, + 'implement_department' => $sList->implement_department, + ], + ]; + + // 1. 获取 execDeptCode / execDeptName(通过排班→诊室资源→执行科室链路) + $execDeptCode = ''; + $execDeptName = ''; + $execDeptInfo = []; + + if (!empty($sList->reservation_sources)) { + $resource = DB::table('s_department_resources') + ->where('id', $sList->reservation_sources) + ->first(); + if ($resource) { + $deptId = $resource->execute_department_id ?: $resource->department_id; + if ($deptId) { + $dept = DB::table('s_department') + ->where('id', $deptId) + ->first(); + if ($dept) { + $execDeptCode = $dept->department_number; + $execDeptName = $dept->department_name; + $execDeptInfo = [ + 'resources_id' => $sList->reservation_sources, + 'execute_department_id' => $resource->execute_department_id, + 'department_id' => $resource->department_id, + 'dept_id_used' => $deptId, + 'department_number' => $dept->department_number, + 'department_name' => $dept->department_name, + ]; + } + } + } + } + $result['exec_dept_info'] = $execDeptInfo; + + // 2. 调 HIS 查询申请单接口 + $patientHisTypeMap = [ + 0 => '03', // 住院 + 1 => '01', // 门诊 + 2 => '02', // 急诊 + 3 => '04', // 体检 + ]; + $visitTypeCode = $patientHisTypeMap[$sList->patient_type] ?? '09'; + + $hisQueryData = [ + 'visitSqNo' => $sList->episodeid, + 'requestNo' => $sList->app_num, + 'visitTypeCode' => $visitTypeCode, + ]; + + $result['his_query'] = [ + 'params' => $hisQueryData, + ]; + + try { + $hisRes = HisController::Get('查询检查申请单', $hisQueryData); + $result['his_query']['response'] = $hisRes; + $result['his_query']['success'] = ($hisRes['code'] == 200); + + if ($hisRes['code'] == 200 && !empty($hisRes['data'])) { + $hisData = $hisRes['data'][0] ?? null; + + if ($hisData) { + // 3. 提取申请单级数据 + $comboNo = $hisData['requestNo'] ?? ''; + // 住院取 episodeid,门诊取 reg_num + $inpatientNo = $sList->patient_type == 0 ? $sList->episodeid : $sList->reg_num; + + // 4. 匹配项目级数据 + $moOrder = ''; + $hisOrderNo = ''; + $matchedItem = []; + + if (!empty($hisData['itemList']) && is_array($hisData['itemList'])) { + foreach ($hisData['itemList'] as $item) { + if (($item['termCode'] ?? '') == $sList->entrust_code) { + $moOrder = $item['orderNo'] ?? ''; + $hisOrderNo = $item['chargeList'][0]['hisOrderNo'] ?? ''; + $matchedItem = [ + 'termCode' => $item['termCode'] ?? '', + 'termName' => $item['termName'] ?? '', + 'orderNo' => $item['orderNo'] ?? '', + 'hisOrderNo' => $hisOrderNo, + ]; + break; + } + } + } + + $result['matched_item'] = $matchedItem; + + // 5. 组装回写参数 + $result['callback_params'] = [ + 'moOrder' => $moOrder, + 'execDeptCode' => $execDeptCode, + 'execDeptName' => $execDeptName, + 'inpatientNo' => $inpatientNo, + 'hisOrderNo' => $hisOrderNo, + 'comboNo' => $comboNo, + 'itemCode' => $sList->entrust_code, + ]; + } + } + } catch (\Exception $e) { + $result['his_query']['response'] = null; + $result['his_query']['success'] = false; + $result['his_query']['error'] = $e->getMessage(); + } + + return \Yz::JsonReturn(true, '查询完成', $result); + + } catch (\Exception $e) { + return \Yz::JsonReturn(false, '接口异常:' . $e->getMessage(), [ + 'error_file' => $e->getFile(), + 'error_line' => $e->getLine() + ]); + } + } + function build_yiji_url($regnum, $entrustid, $episodeid) { // 固定参数 diff --git a/Laravel/app/Services/Admin/YeWu/PlanListService.php b/Laravel/app/Services/Admin/YeWu/PlanListService.php index 682e3bc..8c27f42 100644 --- a/Laravel/app/Services/Admin/YeWu/PlanListService.php +++ b/Laravel/app/Services/Admin/YeWu/PlanListService.php @@ -2,6 +2,7 @@ namespace App\Services\Admin\YeWu; +use App\Http\Controllers\API\His\HisController; use App\Http\Controllers\API\Third\CSharpController; use App\Services\SendMessgeService; use DateInterval; @@ -820,6 +821,18 @@ public function YuYue($planid, $appointment_type, $mainlistids, $do_type,$is_eme } DB::commit(); + + // HIS 回写通知 + try { + $this->notifyHisAfterYuYue($oldMainInfos, $planInfo); + } catch (\Exception $e) { + Log::error('HIS 回写通知异常', [ + 'planid' => $planid, + 'mainlistids' => $mainlistids, + 'error' => $e->getMessage() + ]); + } + if(config('app.globals.预约完成短信通知')==1){ $this->SendMsg($oldMainInfos,$do_type); } @@ -1065,6 +1078,155 @@ private function releaseSourceFallback($mainInfo) return $affected > 0; } + /** + * 预约完成后通知 HIS 回写执行科室 + * 在事务提交后调用,异常不影响主流程 + */ + private function notifyHisAfterYuYue($oldMainInfos, $planInfo) + { + // 1. 获取 execDeptCode / execDeptName(本地数据库) + $execDeptCode = ''; + $execDeptName = ''; + $resource = DB::table('s_department_resources') + ->where('id', $planInfo->resources_id) + ->first(); + if ($resource) { + $deptId = $resource->execute_department_id ?: $resource->department_id; + if ($deptId) { + $dept = DB::table('s_department') + ->where('id', $deptId) + ->first(); + if ($dept) { + $execDeptCode = $dept->department_number; + $execDeptName = $dept->department_name; + } + } + } + + if (empty($execDeptCode)) { + Log::warning('HIS 回写通知跳过:未找到执行科室信息', [ + 'resources_id' => $planInfo->resources_id + ]); + return; + } + + // 2. 按 app_num 分组去重 + $grouped = []; + foreach ($oldMainInfos as $mainInfo) { + $appNum = $mainInfo->app_num; + if (empty($appNum)) continue; + if (!isset($grouped[$appNum])) { + $grouped[$appNum] = [ + 'episodeid' => $mainInfo->episodeid, + 'patient_type' => $mainInfo->patient_type, + 'items' => [], + ]; + } + $grouped[$appNum]['items'][] = $mainInfo; + } + + if (empty($grouped)) { + Log::warning('HIS 回写通知跳过:没有有效的申请单号'); + return; + } + + // patient_type 到 visitTypeCode 映射 + $patientHisTypeMap = [ + 0 => '03', // 住院 + 1 => '01', // 门诊 + 2 => '02', // 急诊 + 3 => '04', // 体检 + ]; + + // 3. 遍历每组,调 HIS 查询接口获取最新数据 + foreach ($grouped as $appNum => $group) { + $visitSqNo = $group['episodeid']; + $visitTypeCode = $patientHisTypeMap[$group['patient_type']] ?? '09'; + + $hisQueryData = [ + 'visitSqNo' => $visitSqNo, + 'requestNo' => $appNum, + 'visitTypeCode' => $visitTypeCode, + ]; + + try { + $hisRes = HisController::Get('查询检查申请单', $hisQueryData); + } catch (\Exception $e) { + Log::warning('HIS 查询申请单异常', [ + 'app_num' => $appNum, + 'error' => $e->getMessage() + ]); + continue; + } + + if ($hisRes['code'] != 200 || empty($hisRes['data'])) { + Log::warning('HIS 查询申请单失败', [ + 'app_num' => $appNum, + 'response' => $hisRes + ]); + continue; + } + + $hisData = $hisRes['data'][0] ?? null; + if (!$hisData) { + Log::warning('HIS 查询返回数据为空', ['app_num' => $appNum]); + continue; + } + + // 4. 提取申请单级数据(comboNo 从 HIS 返回数据获取最新) + $comboNo = $hisData['requestNo'] ?? ''; + + // 5. 遍历每条 s_list,匹配 entrust_code 获取项目级数据 + foreach ($group['items'] as $mainInfo) { + // 住院取 episodeid,门诊取 reg_num + $inpatientNo = $mainInfo->patient_type == 0 ? $mainInfo->episodeid : $mainInfo->reg_num; + + $entrustCode = $mainInfo->entrust_code; + $moOrder = ''; + $hisOrderNo = ''; + + // 在 itemList 中匹配 termCode == entrust_code + if (!empty($hisData['itemList']) && is_array($hisData['itemList'])) { + foreach ($hisData['itemList'] as $item) { + if (($item['termCode'] ?? '') == $entrustCode) { + $moOrder = $item['orderNo'] ?? ''; + $hisOrderNo = $item['chargeList'][0]['hisOrderNo'] ?? ''; + break; + } + } + } + + if (empty($moOrder)) { + Log::warning('HIS 回写:未匹配到 itemList 中的项目', [ + 'entrust_code' => $entrustCode, + 'app_num' => $appNum + ]); + continue; + } + + // 6. 组装并调用 HIS 回写接口 + $body = [ + 'moOrder' => $moOrder, + 'execDeptCode' => $execDeptCode, + 'execDeptName' => $execDeptName, + 'inpatientNo' => $inpatientNo, + 'hisOrderNo' => $hisOrderNo, + 'comboNo' => $comboNo, + 'itemCode' => $entrustCode, + ]; + + try { + HisController::Post('/roc/api/v1/qhd/common/yjyy/updateExecDept', $body); + } catch (\Exception $e) { + Log::error('HIS 回写接口请求异常', [ + 'body' => $body, + 'error' => $e->getMessage() + ]); + } + } + } + } + //短信提醒 public function SendMsg($infos,$dotype=1) { diff --git a/Laravel/routes/api.php b/Laravel/routes/api.php index 3c13bd2..efd8360 100644 --- a/Laravel/routes/api.php +++ b/Laravel/routes/api.php @@ -203,6 +203,7 @@ Route::group(['middleware'=>['log']],function () { Route::post('/CheckAppointment','App\Http\Controllers\API\Third\YiJiController@CheckAppointment' ); Route::post('/CheckAppointmentTest','App\\Http\\Controllers\\API\\Third\\YiJiController@CheckAppointmentTest' ); + Route::post('/TestHisCallbackParams','App\\Http\\Controllers\\API\\Third\\YiJiController@TestHisCallbackParams' ); Route::post('/PacsSignIn','App\Http\Controllers\API\Third\PacsController@SignIn' );//路径起名字有问题,实际是给报到机的 Route::post('/PacsCancelSignIn','App\Http\Controllers\API\Third\PacsController@CancelSignIn' );//路径起名字有问题,实际是给报到机的 Route::post('/GetEntrustInfo','App\Http\Controllers\API\Third\PacsController@GetEntrustInfo' );