linkDao = $linkDao; } public function getPacsInstitutionExam() { $institution = $this->linkDao->getAllIns(); $allIns = []; foreach ($institution as $k=>$v) { $allIns[$v['id']] = $v['name']; } $exam = $this->linkDao->getinsExam(); rsort($exam); $arr = []; foreach ($exam as $k=>$v) { if(empty($allIns[$v['institution_id']] ?? '')) { continue; } $arr[] = ['name'=>$allIns[$v['institution_id']] ,'num'=> $v['num']]; } return $arr; } public function getPacsAgeExam() { $data = $this->linkDao->getPacsAgeExam(); $arr = $this->statisticsAge($data); return $arr; } public function getPacsDateExam() { $data = $this->linkDao->getPacsDateExam(); return $data; } /** * 统计年龄分布 */ function statisticsAge($data) { $ageStats = []; foreach ($data as $row) { $age = $this->normalizeAge($row['age']); $count = (int)$row['row_cnt']; // 跳过无效年龄 if ($age === null) { continue; } // 累加相同年龄的数量 if (!isset($ageStats[$age])) { $ageStats[$age] = 0; } $ageStats[$age] += $count; } // 转换为所需格式并按年龄排序 $result = []; ksort($ageStats); foreach ($ageStats as $age => $count) { $result[] = [ 'age' => $age, 'count' => $count ]; } return $result; } function normalizeAge($ageStr) { if (empty($ageStr) || $ageStr === 'NULL' || $ageStr === '不详') { return null; } $ageStr = trim($ageStr); // 处理 Y 结尾的年龄(如 27Y, 83Y) if (preg_match('/^(\d+)Y$/i', $ageStr, $matches)) { return (int)$matches[1]; } // 处理"岁"结尾的年龄(如 31岁, 72岁) if (preg_match('/^(\d+)岁/', $ageStr, $matches)) { return (int)$matches[1]; } // 处理小数格式(如 74.00, 64.00) if (preg_match('/^(\d+)\.?\d*$/', $ageStr, $matches)) { return (int)$matches[1]; } // 处理纯数字(如 48, 179) if (is_numeric($ageStr)) { return (int)$ageStr; } // 处理月份(如 3月28天, 10M)- 转换为 0 岁 if (preg_match('/月|M$/i', $ageStr)) { return 0; } // 处理天数或小时(如 19天, 0小时19分钟)- 转换为 0 岁 if (preg_match('/天|小时|分钟|D$/i', $ageStr)) { return 0; } // 其他无法识别的格式返回 null return null; } public function getPacsCount() { $info = Db::query("SELECT TRUNC(createdAt,'MM') AS month_begin,COUNT(*) AS cnt FROM pacs.query_study_logs GROUP BY TRUNC(createdAt,'MM') ORDER BY month_begin"); $all = 0; foreach ($info as $k=>$v) { $info[$k]['month_begin'] = (explode(' ',$v['month_begin'])[0] ?? ''); $all += $v['cnt']; } $project = $this->linkDao->countExam(); $data = ['image'=>$all,'project'=>$project,'list'=>$info]; return $data; } public function getPacsResult() { $arr = $this->linkDao->getReportResult(); $data = ['阴性'=>0,'阳性'=>0,'其他'=>0]; foreach ($arr as $k=>$v) { if($v['report_result'] == '1') { $data['阴性'] += $v['cnt']; }elseif ($v['report_result'] == '2') { $data['阳性'] += $v['cnt']; }else{ $data['其他'] += $v['cnt']; } } $return = $this->makeData($data); return $return; } public function makeData($arr) { $data = []; foreach ($arr as $k=>$v) { $data[] = ['name'=>$k,'value'=>$v]; } return $data; } public function getPacsSex() { $arr = $this->linkDao->getSexData(); $data = ['男'=>0,'女'=>0,'其他'=>0]; foreach ($arr as $k=>$v) { if($v['sex'] == 'M' || $v['sex'] == '男' ) { $data['男'] += $v['cnt']; }elseif ($v['sex'] == 'F' || $v['sex'] == '女') { $data['女'] += $v['cnt']; }else{ $data['其他'] += $v['cnt']; } } $return = $this->makeData($data); return $return; } public function getMiddleProjectList() { $list = $this->linkDao->getMiddleProjectList(); foreach ($list as $k=>$v) { if(!empty($v['name'])) { $name = $v['name']; $nameLen = mb_strlen($name, 'UTF-8'); if ($nameLen > 1) { $list[$k]['name'] = mb_substr($name, 0, 1, 'UTF-8') . str_repeat('*', $nameLen - 1); } } } return $list; } public function getPacsMapExam() { $institution = $this->linkDao->getAllIns(); $allIns = []; foreach ($institution as $k=>$v) { $allIns[$v['id']] = $v; } $exam = $this->linkDao->getInsExam(); rsort($exam); $arr = []; foreach ($exam as $k=>$v) { if(empty($allIns[$v['institution_id']] ?? '')) { continue; } $arr[] = ['num'=>$v['num'],'lng'=>$allIns[$v['institution_id']]['lng'],'lat'=>$allIns[$v['institution_id']]['lat'],'NAME'=>$allIns[$v['institution_id']]['name']]; } return $arr; } public function getShareToken($param) { if(empty($param['B'])) { $this->throwError('证件号不能为空','-1'); } $token = UUIDUtils::uuid(); $this->setCache($token,$param,32400); return $token; } public function getViewDetail($info) { $cardNum = $info['B']; $cardWhere = ['card_num'=>$cardNum]; $where = []; if($info['H'] == 1) { $where['institution_id'] = $info['C']; } $data = $this->linkDao->getExamData($where,$cardWhere); if(!empty($data)) { $patient = []; $report = []; $examReport = []; foreach ($data as $k=>$v) { switch ($v['sex']) { case 'M': $sex = '男'; break; case 'F': $sex = '女'; break; default: $sex = '未知'; } $patient = [ 'BIRTH_DATE'=>$v['birthday'], 'CARDNUM'=>$v['card_num'], 'GENDER'=>$sex, 'ID_CARDNUM'=>$v['card_num'], 'MPI'=>$v['accession_num'], 'NAME'=>$v['name'], 'PATIENTNAME'=>$v['name'], 'AGE'=>$v['age'] ]; $report = $this->linkDao->getReportData(['exam_id'=>$v['id']]); $info = []; $institution = $this->linkDao->getInsData(['id'=>$v['institution_id']]); switch ($report['report_result'] ?? '') { case '1': $result = '阴性'; break; case '2': $result = '阳性'; break; default: $result = '未知'; } $info['EXAM_REPORT'][] = [ 'ACCESSION_NUM'=>$v['accession_num'], 'AUDITNAME'=>$report['review_doctor_name'] ?? '', 'BODYSITE'=>$v['body_part'], 'DEPTNAME'=>$v['application_department'], 'DEVICETYPE_CODE'=>$v['exam_class'], 'EXAM_ITEMNAME'=>$v['exam_project'], 'OBSERVATIONS_COMMENT'=>$report['description'] ?? '', 'OBSERVATIONS_RESULT'=>$report['impression'] ?? '', 'ORGNAME'=>$institution['name'], 'REPORTTIME'=>$report['report_datetime'] ?? '', 'RESULT_STATUS'=>$result, 'STUDYTIME'=>$v['exam_datetime'], 'STUDY_ID'=>$v['study_id'], ]; //患者来源 //'1'=>'急诊号 '2'=>住院号', '3'=>'门诊号' '4'=>'体检号' switch ($v['patient_source']) { case '1': $source = '急诊'; break; case '2': $source = '住院'; break; case '3': $source = '门诊'; break; case '4': $source = '体检'; break; default: $source = ''; } $info['MEDICAL_INFORMATION'] = [ 'AGE'=>$v['age'], 'CHIEFCOMPLAINT'=>$v['clin_diag'], 'CLASS'=>$source, 'DEPTNAME'=>$v['application_department'], 'DIAGNOSENAME'=>$v['clin_diag'], 'DOCTORNAME'=>$v['application_doctor'], 'ENCOUNTER_DATE'=>$v['exam_datetime'], 'GENDER'=>$sex, 'NAME'=>$v['name'], 'ORGCODE'=>$v['institution_id'], 'ORGNAME'=>$institution['name'], 'PATIENT_CODE'=>$v['accession_num'] ]; $examReport[] = $info; } $return = ['data'=>$examReport,'patient'=>$patient]; return $return; }else{ return []; } } public function getPatientList($param) { $param['code'] = openssl_decrypt(base64_decode($param['code']), 'AES-128-ECB', Config::get('chengde')['key']); // $param['institution_id'] = openssl_decrypt(base64_decode($param['institution_id']), 'AES-128-ECB', Config::get('chengde')['key']); if(empty($param['code'])) { $this->throwError('数据解密失败','1210'); } if(empty($param['type']) || empty($param['code'])) { $this->throwError('没有相应的类型','1211'); } // $insIds = explode(',',$param['institution_id']); $type = explode(',',$param['type']); $code = explode(',',$param['code']); $where = []; $institution = []; // $institution[] = ['institution_id','in',$insIds]; $whereTime = []; if(count($type) == 1&& count($code) !== 1) { //1个type多个code if(!(Config::get('institution_docking')[$type[0]] ?? null)) { $this->throwError('没有相应的类型','1211'); } $field = Config::get('institution_docking')[$type[0]]; if($field == 'name') { $field = 'e.name'; } $where[] = [$field,'in',$code]; }else{ foreach ($type as $k=>$v) { $field = Config::get('institution_docking')[$v]; if(empty($field) /*|| empty($code[$k])*/){ continue; } if($field == 'name') { $field = 'e.name'; } if($field == 'exam_datetime') { $whereTime['exam_datetime'] = $code[$k]; }else{ if(empty($code[$k])) { if(!empty($code[0])) { $where[$field] = $code[0]; } }else{ $where[$field] = $code[$k]; } } } } if(empty($where) && empty($whereTime)) { return []; } if(($param['check'] ?? null)) { switch ($param['check']) { case 1: $value = 'card_num'; break; case 2: $value = 'phone'; break; default: $value = ''; $this->throwError('验证错误','1223'); break; } $data = $this->linkDao->getExamsCheck($where,$institution,$value); if(empty($data)) { $this->throwError('验证错误','1223'); } $str = substr($data,-4); if($param['checkcode'] !== $str) { $this->throwError('验证码错误','1224'); } } $info = $this->linkDao->getPatientReportList($where,$institution,$whereTime,[]); foreach ($info as $k=>$v) { $info[$k]['insConfig'] = ''; $info[$k]['config_number'] = ''; $config = Config::get('hospital_config'); foreach ($config as $key=>$value) { if(isset($v[$key]) && !empty($v[$key])) { $info[$k]['insConfig'] = $value; $info[$k]['config_number'] = $v[$key]; } } if(!empty($v['patient_source'])) { $sourceArr = Config::get('patient_source'); $sourceInfo = $sourceArr[$v['patient_source']] ?? []; if(!empty($sourceInfo)) { $info[$k]['insConfig'] = $sourceInfo['name']; $info[$k]['config_number'] = $v[$sourceInfo['field']]; } } } return $info; } public function getAnotherPatientList($param) { $param['code'] = openssl_decrypt(base64_decode($param['code']), 'AES-128-ECB', Config::get('chengde')['key']); // $param['institution_id'] = openssl_decrypt(base64_decode($param['institution_id']), 'AES-128-ECB', Config::get('chengde')['key']); if(empty($param['code'])) { $this->throwError('数据解密失败','1210'); } if(empty($param['type']) || empty($param['code'])) { $this->throwError('没有相应的类型','1211'); } // $insIds = explode(',',$param['institution_id']); $type = explode(',',$param['type']); $code = explode(',',$param['code']); $where = []; $institution = []; // $institution[] = ['institution_id','in',$insIds]; $whereTime = []; if(count($type) == 1&& count($code) !== 1) { //1个type多个code if(!(Config::get('institution_docking')[$type[0]] ?? null)) { $this->throwError('没有相应的类型','1211'); } $field = Config::get('institution_docking')[$type[0]]; if($field == 'name') { $field = 'e.name'; } $where[] = [$field,'in',$code]; }else{ foreach ($type as $k=>$v) { $field = Config::get('institution_docking')[$v]; if(empty($field) /*|| empty($code[$k])*/){ continue; } if($field == 'name') { $field = 'e.name'; } if($field == 'exam_datetime') { $whereTime['exam_datetime'] = $code[$k]; }else{ if(empty($code[$k])) { if(!empty($code[0])) { $where[$field] = $code[0]; } }else{ $where[$field] = $code[$k]; } } } } if(empty($where) && empty($whereTime)) { return []; } if(($param['check'] ?? null)) { switch ($param['check']) { case 1: $value = 'card_num'; break; case 2: $value = 'phone'; break; default: $value = ''; $this->throwError('验证错误','1223'); break; } $data = $this->linkDao->getExamsCheck($where,$institution,$value); if(empty($data)) { $this->throwError('验证错误','1223'); } $str = substr($data,-4); if($param['checkcode'] !== $str) { $this->throwError('验证码错误','1224'); } } $must_where = []; if(isset($param['must']) && !empty($param['must'])) { $must = $param['must']; $must_type = Config::get('institution_docking')[$must['key']]; if($must_type == 'name') { $must_type = 'e.name'; } $must_code = $must['value']; $must_where = [$must_type=>$must_code]; } $info = $this->linkDao->getPatientReportList($where,$institution,$whereTime,$must_where); foreach ($info as $k=>$v) { $info[$k]['insConfig'] = ''; $info[$k]['config_number'] = ''; $config = Config::get('hospital_config'); foreach ($config as $key=>$value) { if(isset($v[$key]) && !empty($v[$key])) { $info[$k]['insConfig'] = $value; $info[$k]['config_number'] = $v[$key]; } } if(!empty($v['patient_source'])) { $sourceArr = Config::get('patient_source'); $sourceInfo = $sourceArr[$v['patient_source']] ?? []; if(!empty($sourceInfo)) { $info[$k]['insConfig'] = $sourceInfo['name']; $info[$k]['config_number'] = $v[$sourceInfo['field']]; } } } return $info; } public function getPatientInfo($params) { $info = $this->linkDao->getConfirmReportInfo($params['exam_id']); foreach ($info as $k=>$v) { $info[$k]['insConfig'] = ''; $info[$k]['config_number'] = ''; $config = Config::get('hospital_config'); foreach ($config as $key=>$value) { if(isset($v[$key]) && !empty($v[$key])) { $info[$k]['insConfig'] = $value; $info[$k]['config_number'] = $v[$key]; } $info[$k]['age'] = str_replace('W','周',str_replace('D','天',str_replace('M','月',str_replace('Y','岁',ltrim($info[$k]['age'],'0'))))); } } return $info; } public function getJm($param) { return base64_encode(openssl_encrypt($param['code'], 'AES-128-ECB', Config::get('chengde')['key'])); } }