|
@@ -0,0 +1,361 @@
|
|
|
+<?php
|
|
|
+declare(strict_types=1);
|
|
|
+
|
|
|
+namespace app\service;
|
|
|
+
|
|
|
+use app\controller\Cdss;
|
|
|
+use app\controller\PatientAuxiliary;
|
|
|
+use app\model\CdssDisease;
|
|
|
+use app\model\CdssInspection;
|
|
|
+use app\model\CdssXyDisease;
|
|
|
+use app\model\DiseasesKeyword;
|
|
|
+use app\model\KnowledgeRule;
|
|
|
+use app\model\Symptom;
|
|
|
+use app\model\SymptomDictionary;
|
|
|
+use think\helper\Arr;
|
|
|
+
|
|
|
+require_once app()->getRootPath() . 'vendor/autoload.php';
|
|
|
+
|
|
|
+class XyCdssService
|
|
|
+{
|
|
|
+ private static $instance;
|
|
|
+
|
|
|
+ public static function getInstance(){
|
|
|
+ if(!self::$instance instanceof self){
|
|
|
+ self::$instance = new self();
|
|
|
+ }
|
|
|
+ return self::$instance;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public function getResult($params){
|
|
|
+
|
|
|
+ $chief = Arr::get($params,'data.chief',''); //主诉
|
|
|
+ $presentHistory = Arr::get($params,'data.presentHistory',''); //现病史
|
|
|
+ $patientBirthday = Arr::get($params,'patientMes.patientBirthday',''); //出生年月
|
|
|
+ $sex = Arr::get($params,'patientMes.patientGender','');
|
|
|
+ $age = Arr::get($params,'patientMes.patientAge');
|
|
|
+
|
|
|
+ // if($sex == '男性'){
|
|
|
+ // $sex = 1;
|
|
|
+ // }elseif($sex == '女性'){
|
|
|
+ // $sex = 2;
|
|
|
+ // }else{
|
|
|
+ // $sex = 0;
|
|
|
+ // }
|
|
|
+
|
|
|
+ $age = $age ?: ($patientBirthday ? date("Y") - explode('-',$patientBirthday)[0] : 0) ;
|
|
|
+
|
|
|
+ $result = [];
|
|
|
+
|
|
|
+// if($chief){
|
|
|
+// $dictionary = SymptomDictionary::field('symptom')->whereRaw("'".$chief."'".' LIKE CONCAT("%", symptom, "%")')->select()->toArray();
|
|
|
+// $chief = $dictionary ? implode(',',array_column($dictionary,'symptom')) : '';
|
|
|
+// }
|
|
|
+
|
|
|
+ $name = '';
|
|
|
+ if(isset($params['lisAdvices']) || isset($params['pacsAdvices'])){
|
|
|
+ $name = Arr::get($params,'lisAdvices.0.itemName','') ?: Arr::get($params,'pacsAdvices.0.itemName','');
|
|
|
+ }if(isset($params['lisCol']) || isset($params['pacsCol'])){
|
|
|
+ $name = Arr::get($params,'lisCol.0.lisName','') ?: Arr::get($params,'pacsCol.0.examName','');
|
|
|
+ }
|
|
|
+
|
|
|
+ return (new PatientAuxiliary(app()))->savePatientAuxiliaryInfoInterfece([
|
|
|
+ 'ZYH' => Arr::get($params,'patientMes.treatmentCode',''),
|
|
|
+ 'ZSZZ' => $chief,
|
|
|
+ 'name' => $name,
|
|
|
+ 'tag' => Arr::get($params,'patientMes.patientType','Inspection'),
|
|
|
+ 'XB' => $sex,
|
|
|
+ 'NL' => $age,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 废弃 ——————————————————————————————————————————————————————————————————————————————————————————
|
|
|
+ */
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 疑似诊断
|
|
|
+ */
|
|
|
+ if($chief){
|
|
|
+ $res = $this->getCdssXyDisease($chief);
|
|
|
+ if(empty($res)) $res = $this->getSymptom($chief);
|
|
|
+
|
|
|
+ $this->getSexFilter($res,$sex);//根据性别筛选
|
|
|
+
|
|
|
+ $res = $this->getAgeFilter($res,$age); //根据年龄筛选
|
|
|
+
|
|
|
+ $this->getAboutDiseasesByKeywordCount($res,$chief);
|
|
|
+ foreach ($res as $k => $v){
|
|
|
+ //获取鉴别诊断
|
|
|
+ $res[$k]['antidiastole'] = CdssDisease::where('name' , $v['name'])->value('antidiastole');
|
|
|
+
|
|
|
+ //获取检查检验
|
|
|
+ $disease = CdssXyDisease::where('name',$v['name'])->find();
|
|
|
+ $inspection = $disease->inspection;
|
|
|
+ $inspectionList = explode(',', $inspection);
|
|
|
+ foreach ($inspectionList as $key => $value) {
|
|
|
+ $res[$k]['inspection_list'][$key]['name'] = $value;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取治疗方案
|
|
|
+ $res[$k]['treatment'] = $disease->inspection;
|
|
|
+ }
|
|
|
+
|
|
|
+ $result['suspectedDiagnosis'] = $res;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 鉴别诊断、推荐检查检验、治疗方案
|
|
|
+ */
|
|
|
+ if(isset($params['diagnoses'])){
|
|
|
+ $result['diagnoses'] = $this->diagnoses(Arr::get($params,'diagnoses',[]));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查检验合理性判断、
|
|
|
+ */
|
|
|
+ if(isset($params['lisAdvices']) || isset($params['pacsAdvices'])){
|
|
|
+ $result['RationalityCheck'] = $this->pacsLisRationalityCheck(Arr::get($params,'lisAdvices',[]),Arr::get($params,'pacsAdvices',[]),$sex);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 检查检验报告解读、检验检查异常值
|
|
|
+ */
|
|
|
+ if(isset($params['lisCol']) || isset($params['pacsCol'])){
|
|
|
+ $result['ReportInterpretation'] = $this->pacsLisReportInterpretation(Arr::get($params,'lisCol',[]),Arr::get($params,'pacsCol',[]));
|
|
|
+ }
|
|
|
+
|
|
|
+ return $result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取鉴别诊断、推荐检查检验、推荐评估表、治疗方案
|
|
|
+ * @param $aboutDiseases
|
|
|
+ * @throws \think\db\exception\DataNotFoundException
|
|
|
+ * @throws \think\db\exception\DbException
|
|
|
+ * @throws \think\db\exception\ModelNotFoundException
|
|
|
+ */
|
|
|
+ private function diagnoses($aboutDiseases){
|
|
|
+ foreach ($aboutDiseases as $k => $v){
|
|
|
+ //获取鉴别诊断
|
|
|
+ $cdssDisease = CdssDisease::where('name' , $v['name'])->value('antidiastole');
|
|
|
+ if($cdssDisease){
|
|
|
+ $aboutDiseases[$k]['antidiastole'] = $cdssDisease;
|
|
|
+ }else{
|
|
|
+ $aboutDiseases[$k]['antidiastole'] = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取检查检验
|
|
|
+ $disease = CdssXyDisease::where('name',$v['name'])->find();
|
|
|
+ if($disease){
|
|
|
+ $inspection = $disease->inspection;
|
|
|
+ $inspectionList = explode(',', $inspection);
|
|
|
+ foreach ($inspectionList as $key => $value) {
|
|
|
+ $aboutDiseases[$k]['inspection_list'][$key]['name'] = $value;
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取治疗方案
|
|
|
+ $aboutDiseases[$k]['treatment'] = $disease->inspection;
|
|
|
+ }else{
|
|
|
+ $aboutDiseases[$k]['inspection_list'] = [];
|
|
|
+ $aboutDiseases[$k]['treatment'] = '';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $aboutDiseases;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function pacsLisRationalityCheck($lisAdvices,$pacsAdvices,$sex){
|
|
|
+ $res['lis_rationality_check'] = $res['pace_rationality_check'] = [];
|
|
|
+
|
|
|
+ foreach ($lisAdvices as $val){
|
|
|
+ $lis_rationality_check = KnowledgeRule::field('name,rule_level,rule_tip')->whereLike('name',"%{$val['itemName']}%")->where('gender',$sex)->find();
|
|
|
+ if($lis_rationality_check) $res['lis_rationality_check'][] = $lis_rationality_check;
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($pacsAdvices as $val){
|
|
|
+ $pacs_rationality_check = KnowledgeRule::field('name,rule_level,rule_tip')->whereLike('name',"%{$val['itemName']}%")->where('gender',$sex)->find();
|
|
|
+ if($pacs_rationality_check) $res['pace_rationality_check'][] = $pacs_rationality_check;
|
|
|
+ }
|
|
|
+ return $res;
|
|
|
+ }
|
|
|
+
|
|
|
+ private function pacsLisReportInterpretation($lisCol,$pacsCol){
|
|
|
+ $res['lis_report_interpretation'] = $res['pacs_report_interpretation'] = [];
|
|
|
+ $field = 'name,overview,principle,reagent,operation,clinicalSignificance,normalValue,annotation,precautions,donghua_name,zhonglian_name,process,related_symptoms,related_diseases,haoze_name,sex';
|
|
|
+ foreach ($lisCol as $key => $val){
|
|
|
+ $res['lis_report_interpretation'][$key]['name'] = $val['lisName'];
|
|
|
+ foreach ($val['lisItems'] as $v) {
|
|
|
+ $lis_report_interpretation = CdssInspection::field($field)->whereLike('name', "%{$v['itemName']}%")->find();
|
|
|
+ if ($lis_report_interpretation) {
|
|
|
+ $res['lis_report_interpretation'][$key]['list'][] = $lis_report_interpretation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach ($pacsCol as $v){
|
|
|
+ $pacs_report_interpretation = CdssInspection::field($field)->whereLike('name',"%{$v['examName']}%")->find();
|
|
|
+ if($pacs_report_interpretation){
|
|
|
+ $res['pacs_report_interpretation'][] = $pacs_report_interpretation;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return $res;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 疑似诊断
|
|
|
+ * @param $values
|
|
|
+ * @return array
|
|
|
+ * @throws \think\db\exception\DataNotFoundException
|
|
|
+ * @throws \think\db\exception\DbException
|
|
|
+ * @throws \think\db\exception\ModelNotFoundException
|
|
|
+ */
|
|
|
+ private function getCdssXyDisease($values){
|
|
|
+ /**
|
|
|
+ * 从疾病的临床表现属性匹配症状
|
|
|
+ * 单个或多条件匹配
|
|
|
+ */
|
|
|
+ $query = CdssXyDisease::field('name,pathogenesis,clinicalFeature')->where('1=1');
|
|
|
+
|
|
|
+ if (stripos($values, ',') !== false) {
|
|
|
+ $symptoms = explode(',', $values);
|
|
|
+
|
|
|
+ // 使用AND连接多个症状条件
|
|
|
+ foreach ($symptoms as $symptom) {
|
|
|
+ $query = $query->where('clinicalFeature', 'like', '%' . $symptom . '%');
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ $query->whereLike('clinicalFeature', '%' . $values . '%');
|
|
|
+ }
|
|
|
+ $aboutDiseases = $query->limit(200)->select()->toArray();
|
|
|
+
|
|
|
+ return $aboutDiseases;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private function getSymptom($values){
|
|
|
+ $aboutDiseases = [];
|
|
|
+ if (stripos($values, ',') !== false) {
|
|
|
+ $symptoms = explode(',', $values);
|
|
|
+ foreach ($symptoms as $key => $symptom) {
|
|
|
+ $diseases[] = Symptom::field('disease')->where('name', 'like', $symptom . '%')->select()->toArray();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ $diseases = Symptom::field('disease')->whereLike('name', $values . '%')->select()->toArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (empty($diseases)) return [];
|
|
|
+
|
|
|
+ $diseases = array_column($diseases, 'disease');
|
|
|
+
|
|
|
+ foreach ($diseases as $k => $disease) {
|
|
|
+ $diseases[$k] = str_replace('||', ',', $disease);
|
|
|
+ }
|
|
|
+ $diseases = implode(',', $diseases);
|
|
|
+ $diseasesArr = explode(',', $diseases);
|
|
|
+
|
|
|
+ foreach ($diseasesArr as $key => $val){
|
|
|
+ $aboutDiseases[$key]['name'] = $diseasesArr[$val];
|
|
|
+ $aboutDiseases[$key]['pathogenesis'] = '';
|
|
|
+ $aboutDiseases[$key]['clinicalFeature'] = '';
|
|
|
+ }
|
|
|
+
|
|
|
+ return $aboutDiseases ?? [];
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public function getSexFilter(&$aboutDiseases,$sex){
|
|
|
+
|
|
|
+ switch ($sex){
|
|
|
+ case 2:
|
|
|
+ $tag = 4;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ default:
|
|
|
+ $tag = 3;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ $sexDiseasesKeywords = DiseasesKeyword::where('tag', $tag)->value('keyword');
|
|
|
+ if ($sexDiseasesKeywords) {
|
|
|
+ $sexDiseasesKeywords = explode(',', $sexDiseasesKeywords);
|
|
|
+ foreach ($aboutDiseases as $k => $v) {
|
|
|
+ foreach ($sexDiseasesKeywords as $sexDiseasesKeyword) {
|
|
|
+ if (stripos($v['name'], $sexDiseasesKeyword) !== false) {
|
|
|
+ unset($aboutDiseases[$k]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public function getAgeFilter($aboutDiseases,$age){
|
|
|
+
|
|
|
+ $age = (int) $age;
|
|
|
+ $childDiseasesKeyword = DiseasesKeyword::where('tag', DiseasesKeyword::CHILDTAG)->find();
|
|
|
+ $oldDiseasesKeyword = DiseasesKeyword::where('tag', DiseasesKeyword::OLDTAG)->find();
|
|
|
+
|
|
|
+ $childAboutDiseasesKeyword = $childDiseasesKeyword['keyword'];
|
|
|
+ $oldAboutDiseasesKeyword = $oldDiseasesKeyword['keyword'];
|
|
|
+
|
|
|
+ $ageAboutDiseases = [];
|
|
|
+ foreach ($aboutDiseases as $k => $v) {
|
|
|
+ if($age > 14 && $age < 60){
|
|
|
+ $merge = array_merge($childAboutDiseasesKeyword, $oldAboutDiseasesKeyword);
|
|
|
+ for ($i = 0; $i < count($merge); $i++) {
|
|
|
+ if (stripos($v['name'], $merge[$i]) !== false) {
|
|
|
+ unset($aboutDiseases[$k]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ $ageAboutDiseases = array_values($aboutDiseases);
|
|
|
+ }else{
|
|
|
+ $diseasesKeyword = ($age < 60) ? $childAboutDiseasesKeyword : $oldAboutDiseasesKeyword;
|
|
|
+ for ($i = 0; $i < count($diseasesKeyword); $i++) {
|
|
|
+ if (stripos($v['name'], $diseasesKeyword[$i]) !== false) {
|
|
|
+ $ageAboutDiseases[] = $v;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $ageAboutDiseases;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private function getAboutDiseasesByKeywordCount(&$aboutDiseases, $keyword)
|
|
|
+ {
|
|
|
+ if (stripos($keyword, ',') !== false) {
|
|
|
+ foreach ($aboutDiseases as $key => $value) {
|
|
|
+ $aboutDiseases[$key]['keyword_count'] = $this->getKeywordTotalCount($value['clinicalFeature'], $keyword);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ foreach ($aboutDiseases as $key => $value) {
|
|
|
+ $aboutDiseases[$key]['keyword_count'] = substr_count($value['clinicalFeature'], $keyword);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (count($aboutDiseases) > 1) {
|
|
|
+ $keyword_count = array_column($aboutDiseases, 'keyword_count');
|
|
|
+ array_multisort($keyword_count, SORT_DESC, $aboutDiseases);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private function getKeywordTotalCount($clinicalFeature, $keyword): int
|
|
|
+ {
|
|
|
+ $keywordArray = array_values(array_filter(explode(',', $keyword)));
|
|
|
+ $keywordArrayCount = count($keywordArray);
|
|
|
+
|
|
|
+ $totalCount = 0;
|
|
|
+ for ($i = 0; $i < $keywordArrayCount; $i++) {
|
|
|
+ if ($clinicalFeature) {
|
|
|
+ $totalCount += substr_count($clinicalFeature, $keywordArray[$i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return $totalCount;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|