reportDao = $reportDao;
$this->xz = $xzDao;
}
public function check($token,$status)
{
$user = $this->reportDao->getUser($token);
$user_id = $user['id'];
$save = $this->reportAuthentication($user_id, 'save', $user['institution_id'],2);
$audit = $this->reportAuthentication($user_id, 'audit', $user['institution_id'],2);
$confirm = $this->reportAuthentication($user_id, 'confirm', $user['institution_id'],2);
if($status != 9)
{
if(!($save || $audit || $confirm))
{
return '2';
}
}
return '1';
}
public function getReportDetail($examId,$isRemote,$token,$ra_id)
{
if(empty($ra_id)){
//本地报告详情
$detail = $this->reportDao->getReportInfo($examId);
$data = json_decode(json_encode($detail),true);
if(!isset($data['report_id']) || $data['report_id'] == ''){
$report_info = [
'id'=>UUIDUtils::uuid(),
'exam_id'=>$examId,
'createdAt'=>date('Y-m-d H:i:s',time()),
'type'=>1
];
$this->reportDao->InsertReport($report_info);
// $url = 'http://wechat.pacsonline.cn/wx_patient/api/unifyGetWxQrcode?reportId='.$report_info['id'].'&version=3';
// $this->curl_get($url);
$detail['report_id'] = $report_info['id'];
}
}else{
//远程报告详情
$detail = $this->reportDao->getRemoteReportInfo($ra_id);
}
$institution = $this->reportDao->getInstitutionData(['id'=>$detail['institution_id']],['id','report_subtitle','report_title']);
$detail['report_title'] = $institution['report_title'];
$detail['report_subtitle'] = $institution['report_subtitle'];
$time = date('Y-m-d H:i:s',time());
//过期时间 大于当前 则 还没过期
$where = "effective_date > '$time'";
$dcm = $this->reportDao->getDcmPathData($where,$detail['study_id']);
$detail['dcm_path'] = $dcm['dcm_path'] ?? '';
$detail['dcm_type'] = $dcm['dcm_type'] ?? '1';
if($detail['dcm_type'] != 1)
{
$detail['dcm_path'] = $this->makeFileUrl($dcm['dcm_path'],$dcm['dcm_type']);
}
// 医生姓名
$detail['report_doctor_id'] = $detail['report_doctor_id'] ?? '';
$detail['review_doctor_id'] = $detail['review_doctor_id'] ?? '';
$detail['confirm_doctor_id'] = $detail['confirm_doctor_id'] ?? '';
$detail['local_institution_name'] = $detail['local_institution_name'] ?? '';
$detail['req_doctor_name'] = $detail['req_doctor_name'] ?? '';
$detail['remote_department'] = $detail['remote_department'] ?? '';
$detail['report_id'] = $detail['report_id'] ?? '';
$detail['report_doctor_name'] = $detail['report_doctor_name'] ?? '';
$detail['review_doctor_name'] = $detail['review_doctor_name'] ?? '';
$detail['confirm_doctor_name'] = $detail['confirm_doctor_name'] ?? '';
$detail['remote_application_id'] = $detail['remote_application_id'] ?? '';
$detail['report_use_autograph'] = $detail['report_use_autograph'] ?? '0';
$detail['review_use_autograph'] = $detail['review_use_autograph'] ?? '0';
$detail['confirm_use_autograph'] = $detail['confirm_use_autograph'] ?? '0';
$detail['report_autograph'] = ($detail['report_use_autograph'] == 1) ? (empty($detail['report_autograph']) ? '' : $this->makeFileUrl($detail['report_autograph'],$detail['report_autograph_type'])) : '';
$detail['review_autograph'] = ($detail['review_use_autograph'] == 1) ? (empty($detail['review_autograph']) ? '' : $this->makeFileUrl($detail['review_autograph'],$detail['review_autograph_type'])) : '';
$detail['confirm_autograph'] = ($detail['confirm_use_autograph'] == 1) ? (empty($detail['confirm_autograph']) ? '' : $this->makeFileUrl($detail['confirm_autograph'],$detail['confirm_autograph_type'])) : '';
if(!empty($detail['report_doctor_id'])){
$insName = $this->reportDao->getInstitution($detail['report_doctor_id']);
$detail['institution'] = $insName['name'];
$detail['introduce'] = $insName['introduce'];
}else{
$detail['institution'] = '';
$detail['introduce'] = '';
}
$detail['exam_id'] = $examId;
$detail['is_remote'] = $isRemote;
// 操作痕迹
if(empty($detail['report_id'])){
$trace = [];
}else{
$trace = $this->reportDao->getTrace($detail['report_id']);
}
if(!isset($detail['exam_status'])){
$detail['exam_status'] = '';
}
$detail['trace'] = $trace;
// 当报告处于完成状态时 不在显示暂存的草稿
if($detail['exam_status'] ?? '') {
if ($detail['exam_status'] == 9)
{
return $detail;
}
}
if($detail['report_status'] ?? '')
{
if ($detail['report_status'] == 9)
{
return $detail;
}
}
// 草稿存储
$userId = $this->reportDao->getUserId($token);
$cacheToken = $this->getStageKey($detail['report_id'],$userId);
$stage = $this->reportDao->getStage($cacheToken);
if(!empty($stage)){
$detail['impression'] = $stage['impression'];
$detail['description'] = $stage['description'];
}
return $detail;
}
public function getWjDetail($examId,$isRemote)
{
if($isRemote == 1){
//远程
$remote = 'not null';
}else{
$remote = 'null';
}
$detail = $this->reportDao->getReportInfo($examId/**,$remote*/);
// 医生姓名
if(empty($detail)){
$detail['report_doctor_id'] = '';
$detail['review_doctor_id'] = '';
$detail['confirm_doctor_id'] = '';
$detail['report_id'] = '';
$detail['report_doctor_name'] = '';
$detail['review_doctor_name'] = '';
$detail['confirm_doctor_name'] = '';
}
if(!empty($detail['report_doctor_id'])){
$insName = $this->reportDao->getInstitution($detail['report_doctor_id']);
$detail['institution'] = $insName['name'];
$detail['introduce'] = $insName['introduce'];
}else{
$detail['institution'] = '';
$detail['introduce'] = '';
}
$detail['exam_id'] = $examId;
$detail['is_remote'] = $isRemote;
if(!isset($detail['exam_status'])){
$detail['exam_status'] = '';
}
$detail['trace'] = '';
return $detail;
}
public function save_progress($id,$token,$content,$type)
{
$doctor = $this->reportDao->getUser($token);
$bbs = [
'id'=>UUIDUtils::uuid(),
'initiator'=>$doctor['id'],
'remote_application_id'=>$id,
'content'=>$doctor['realname'].$content,
'createdAt'=>date('Y-m-d H:i:s',time()),
'type'=>$type
];
$this->reportDao->saveBbs($bbs);
}
public function updateReport($examId, $data, $type, $reportType, $token , $ra_id = null )
{
// Db::startTrans();
try{
// 判断报告权限
$exam = $this->reportDao->getExam($examId);
$phone = $exam['phone'] ?? '';
$studyId = $exam['study_id'];
$user = $this->reportDao->getUser($token);
$user_id = $user['id'];
$result = $this->reportAuthentication($user_id, $type, $exam['institution_id'],$reportType);
if(!$result){
$this->throwError('权限未分配,请联系管理员',0005);
}
$rt = ($reportType == 1) ? 2 : 1;
$report = $this->reportDao->getReport($examId,$rt,$ra_id);
$report = json_decode(json_encode($report,true),true);
$reportId = $report['id'] ?? null;
// 书写报告时新增report表数据
if(empty($reportId)){
if($type == 'save'){
$insert_data = [
'id' => UUIDUtils::uuid(),
'exam_id' => $examId,
'createdAt' => date('Y-m-d H:i:s'),
'report_result' => 1,
'type' => $rt,
'remote_application_id' => $ra_id
];
$insert_res = $this->reportDao->insertReport($insert_data);
// $url = 'http://wechat.pacsonline.cn/wx_patient/api/unifyGetWxQrcode?reportId='.$insert_data['id'].'&version=3';
// $this->curl_get($url);
if($insert_res == false){
// Db::rollback();
$this->throwError('insert_report_error',0004);
}
$reportId = $insert_data['id'];
}
}else{
switch ($type)
{
case 'save':
//已写报告 禁止其他医生点击书写按钮
if ($user_id !== $report['report_doctor_id'] && !empty($report['report_doctor_id']))
{
$this->throwError('该报告已被其他医师书写,请刷新当前有页面进行查看!',0712);
}
break;
case 'audit':
//已审报告 禁止其他医生点击审核按钮
if ($user_id !== $report['review_doctor_id'] && !empty($report['review_doctor_id']))
{
$this->throwError('该报告已被其他医师审核,请刷新当前有页面进行查看!',0712);
}
break;
}
}
if($user['institution_id'] == '43600001')
{
if($type == 'save' || $type == 'audit')
{
// 添加锁定状态
$middle = [
'institution_id'=>$user['institution_id'],
'status'=>0,
'doctor_id'=>$user['id'],
'doctor_name'=>$user['realname'],
'exam_id'=>$examId,
'is_sync'=>0,
'report_id'=>$reportId
];
$middleInfo = $this->reportDao->getMiddle(['exam_id'=>$examId]);
$middleWhere = [];
if($middleInfo)
{
unset($middle['is_sync']);
$middleWhere = ['exam_id'=>$examId];
}
$this->reportDao->saveRmiddle($middle,$middleWhere);
}elseif($type == 'confirm'){
$middleWhere = ['exam_id'=>$examId];
$middleInfo = $this->reportDao->getMiddle(['exam_id'=>$examId]);
if($middleInfo)
{
$middle = [
'status'=>1,
'is_sync'=>0
];
$this->reportDao->saveRmiddle($middle,$middleWhere);
}else{
$middle = [
'institution_id'=>$user['institution_id'],
'status'=>1,
'doctor_id'=>$user['id'],
'doctor_name'=>$user['realname'],
'exam_id'=>$examId,
'is_sync'=>0,
'report_id'=>$reportId
];
$this->reportDao->saveRmiddle($middle);
}
}
}
// 修改基本信息
$notUpdateType = [
'confirm'
];
// 不需要更改的类型
if(!in_array($type, $notUpdateType)){
switch ($data['sex']){
case 'M':
case '男':
$sex = 'M';
break;
case 'F':
case '女':
$sex = 'F';
break;
default:
$sex = $data['sex'];
break;
}
$update = [
'name' => $data['name'],
'sex' => $sex,
'age' => $data['age'],
'exam_class' => $data['exam_class'],
'exam_project' => $data['exam_project'] ?? null,
];
if($rt == 1){
$update['phone'] = $data['phone'];
$exam_res = $this->reportDao->updateExamMsg($examId, $exam['patient_id'], $update);
if($exam_res == false){
// Db::rollback();
$this->throwError('update_msg_error',0003);
}
}else{
$update['phone'] = $data['phone'];
$remote_res = $this->reportDao->updateRemote($ra_id, $update);
if($remote_res == false){
// Db::rollback();
$this->throwError('update_msg_error',0003);
}
}
}
// 修改报告数据
$report_up = [
'impression' => $data['impression'] ?? null,
'description' => $data['description'] ?? null,
'report_result' => $data['report_result'] ?? null
];
$sms = $this->reportDao->getInstitutionSms($user['institution_id']);
switch ($reportType){
case '2':
// 本地报告
$report_res = $this->updateReportData($examId, $report_up, $type, $exam['exam_status'], $user, $reportType);
break;
case '1':
// 远程报告
$report_res = $this->updateReportData($examId, $report_up, $type, $exam['exam_status'], $user, $reportType , $ra_id);
break;
default :
$report_res = false;
break;
}
if($type == 'confirm'){
$this->reportDao->delCache($reportId.'_local');
if($sms == '1' && !empty($phone)){
$insName = $this->reportDao->getInstitutionName($user['institution_id']);
// 发送确认短信
$sms = $this->sendSms($phone,$reportId,$examId,$studyId,$insName,$user['institution_id']);
}
$wechat_url = Config::get('wechat_url');
// 二维码生成
$url = $wechat_url.'/wx_patient/api/unifyGetWxQrcode?reportId='.$reportId.'&version=3';
$this->curl_get($url);
if($reportType == 1 && !empty($ra_id)){
//远程确认区间
$money = $this->reportDao->getOrderMoney($ra_id);
if($money != 0){
$current_money = $this->reportDao->getCurrentMoney($user['institution_id']);
$max_money = $current_money + $money;
$this->reportDao->updateInstititonMoney($user['institution_id'],$max_money);
}
//修改订单状态为已确认
$this->reportDao->updateOrder($ra_id,Config::get('ORDER_STATUS')['CONFIRM']);
$wechat = New WechatService();
$order_id = $this->reportDao->getOrderId($ra_id);
// 微信推送确认
$w = $wechat->pushWechatComplete($order_id);
}
//确认推送微信公众号
if(!empty($exam['id'])){
$data = $this->xz->getPushInfo($exam['id']);
$pushType = 6;
$cont = [
'name'=>$exam['name'],
'exam_id'=>$exam['id'],
'modality'=>$exam['exam_class'],
'examDate'=>$exam['exam_datetime'],
'report_id'=>$reportId
];
$content = json_encode($cont,true);
$openids = $this->xz->getOpenId($data);
foreach ($openids as $k=>$v){
// 推送4.0公众号消息
$this->new_wechat_push($v,$pushType,$content);
}
}
}
if($report_res == false){
// Db::rollback();
$this->throwError('update_report_error',0006);
}
if(isset($reportId) && !empty($reportId)){
// 草稿
$key = $this->getStageKey($reportId, $user_id);
$stage = $this->reportDao->getStage($key);
if($stage){
$this->reportDao->delStage($key);
}
}
// 成功
// Db::commit();
// if($type == 'confirm'){
// $this->getExamPush($examId);
// }
return true;
} catch (Exception $exception){
$this->throwError($exception->getMessage(),0001);
}
}
public function rejectAudit($id,$reason,$user)
{
$field = ['report_doctor_id','exam_id'];
$write = $this->reportDao->getReportById($id,$field);
//获取当前医生账号权限
$now_authority = $this->reportDao->getDoctorClass($user['id']);
$now_authority = explode(',',$now_authority);
if(!in_array('3',$now_authority))
{
$this->throwError('do_not_have_permission',0005);
}
$update = ['report'];
// 更改状态为审核驳回
$this->reportDao->updateExamStatus($write['exam_id'],12);
$this->reportDao->updateReport($write['exam_id'],1,['review_doctor_id'=>null,'review_doctor_name'=>null,'review_datetime'=>null]);
$data = [
'id' => UUIDUtils::uuid(),
'title' => '您写的报告有最新消息,请注意查收',
'content' => $user['realname'].'医师驳回了您写得报告,驳回原因是:'.$reason,
'count' => '1',
'type' => '9',
'ctime' => date('Y-m-d H:i:s', time()),
'exam_id' => $write['exam_id'],
'doctor_id'=>$write['report_doctor_id']
];
$this->reportDao->insertMessage($data);
return true;
}
public function sendSms($phone,$reportId,$examId,$studyId,$institution,$insId)
{
$code = rand(0,9).rand(0,9).rand(0,9).rand(0,9);
$id = UUIDUtils::uuid();
if(empty($phone)){
$send_message = 0;
}else{
//发送短信
$note = [
'long_url'=>'https://wc.pacsonline.cn/#/jump?id='.$id
];
$noteId = $this->reportDao->insertNote($note);
$nid = base64_encode(str_pad(base_convert($noteId,10,36),6,'0',STR_PAD_LEFT));
if($insId == '43600001')
{
$send = send_message::sendEZShortMessage($phone,$code,$nid);
}elseif($insId == '03060002'){
$send = send_message::sendReportShortMessage($phone,$institution);
}else{
$send = send_message::sendExam2ShortPatient($phone,$code,$institution,$nid);
}
$data = json_decode(json_encode($send),true);
if($data['Code'] == 'OK'){
$send_message = 1;
}else{
$send_message = 0;
}
}
// $share = [
// 'id'=>$id,
// 'report_id'=>$reportId,
// 'exam_id'=>$examId,
// 'code'=>$code,
// 'send_time'=>time(),
// 'expires_time'=>time()+86400*7,
// 'send_message'=>$send_message,
// 'url'=>'',
// 'phone'=>$phone,
// 'study_id'=> $studyId
// ];
$share = [
'id'=>$id,
'examId'=>$examId,
'status'=>1,
'overdueTime'=>7,
'code'=>$code,
'short_url'=>'',
'phone'=>$phone,
'report_isset'=>1,
'study_id'=>$studyId,
'send_message'=>$send_message,
];
$this->reportDao->insertShare($share);
}
public function getExamPush($id)
{
try{
$xzData = $this->reportDao->getXzData($id);
$report = $this->reportDao->getReport($id,1);
$reportName = $this->reportDao->getDoctorName($report['report_doctor_id']);
$reviewName = $this->reportDao->getDoctorName($report['review_doctor_id']);
$studyUid = $this->reportDao->getUid($id);
$accessionNum = $this->reportDao->getAccession($id);
$info = [
'report'=>[
'department'=>$xzData['department'],
'clinicalDoctor'=>$xzData['clinicalDoctor'],
'symptom'=>$xzData['symptom'],
'reportDate'=>$report['report_datetime'],
'description'=>$report['description'],
'impression'=>$report['impression'],
'reportDoctor'=>$reportName,
'reviewDoctor'=>$reviewName,
'studyInstanceUId'=>$studyUid,
'modality'=>$xzData['modality'],
'accessionNumber'=>$accessionNum
],
'applicationFormNo'=>$xzData['applicationFormNo'],
'clinicId'=>$xzData['clinicId'],
];
$data = json_encode($info);
$url = 'http://wjw.yidab.cn:801/pacs/pushExamReport.do';
// $url = 'http://wjw.yidab.cn:801/wjw-test/pacs/pushExamReport.do';
$return = $this->curlJsonPost($url,$data);
return $return;
}catch(\Exception $e){
return json_encode(['code'=>'1','message'=>$e->getMessage()]);
}
}
public function reportAuthentication($user_id, $type, $institution_id = null,$type_report)
{
// 获取权限列表
$doctor_authority = [
'clinical' => 1, // 临床医生
'report' => 2, // 报告医生
'audit' => 3, // 审核医生
'confirm' => 4, // 确认医生
'register' => 5, // 登记医生
'remote_apply' => 6, // 远程申请医生
'remote_report' => 7, // 远程报告医生
'remote_audit' => 8, // 远程审核医生
'local_reject' => 9, // 本地完成状态打回已写医生
'local_del' => 10, // 本地影像删除
];
// 当前账号权限
$now_authority = $this->reportDao->getDoctorClass($user_id);
if(empty($now_authority)){
return false;
}
$now_authority = explode(',', $now_authority);
// 判断权限
switch ($type){
case 'save':
if($type_report == '2'){
$require = $doctor_authority['report'];
}else{
$require = $doctor_authority['remote_report'];
}
if(!in_array($require, $now_authority)){
return false;
}
break;
case 'audit':
if($type_report == '2'){
$require = $doctor_authority['audit'];
}else{
$require = $doctor_authority['remote_audit'];
}
if(!in_array($require, $now_authority)){
return false;
}
break;
case 'confirm':
$require = $doctor_authority['confirm'];
if(!in_array($require, $now_authority)){
return false;
}
break;
case 'reject':
$require = $doctor_authority['local_reject'];
if(!in_array($require, $now_authority)){
return false;
}
break;
case 'del':
$require = $doctor_authority['local_del'];
if(!in_array($require, $now_authority)){
return false;
}
break;
default :
return false;
}
// 成功
return true;
}
public function stageReport($exam_id, $token, $data, $isRemote,$report_id)
{
try{
if($isRemote == 2){
// 本地
$remote = 1;
}else{
// 远程 1区间
$remote = 2;
}
if(!$report_id){
// 创建一条数据
$insert_data = [
'id' => UUIDUtils::uuid(),
'exam_id' => $exam_id,
'createdAt' => date('Y-m-d H:i:s'),
'report_result' => 1,
'type' => $remote
];
if($remote == 2){ //远程进入
$applicationId = $this->reportDao->getApplicationId($exam_id);
$insert_data['remote_application_id'] = $applicationId;
}
$res = $this->reportDao->insertReport($insert_data);
// $url = 'http://wechat.pacsonline.cn/wx_patient/api/unifyGetWxQrcode?reportId='.$insert_data['id'].'&version=3';
// $this->curl_get($url);
if($res == false){
$this->throwError('insert_report_error',0006);
}
$report_id = $insert_data['id'];
}
// 存储
$user_id = $this->reportDao->getUserId($token);
$key = $this->getStageKey($report_id, $user_id);
$this->reportDao->saveCache($key,$data,604800);
// 成功
return $key;
} catch (Exception $exception){
$this->throwError($exception->getMessage(),0001);
}
}
public function getPrintData($reportId,$is_remote)
{
try{
$wechat = Config::get('wechat_url');
$url = $wechat.'/wx_patient/api/unifyGetWxQrcode?reportId='.$reportId.'&version=3';
$this->curl_get($url);
$detail = $this->reportDao->getPrintInfo($reportId,$is_remote);
$field = ['IS_USE_AUTOGRAPH AS is_use_autograph','AUTOGRAPH AS autograph','AUTOGRAPH_TYPE AS autograph_type'];
if(empty($detail['report_doctor_id']))
{
$detail['report_use_autograph'] = '';
$detail['report_autograph'] = '';
}else{
$report_autograph = $this->reportDao->getDoctorInfo($detail['report_doctor_id'],$field);
$detail['report_use_autograph'] = $report_autograph['is_use_autograph'] ?? '';
$detail['report_autograph'] = empty($report_autograph['autograph'] ?? '') ? '' : $this->makeFileUrl($report_autograph['autograph'],$report_autograph['autograph_type']);
$detail['report_autograph_type'] = $report_autograph['autograph_type'];
}
if(empty($detail['review_doctor_id']))
{
$detail['review_use_autograph'] = '';
$detail['review_autograph'] = '';
}else{
$review_autograph = $this->reportDao->getDoctorInfo($detail['review_doctor_id'],$field);
$detail['review_use_autograph'] = $review_autograph['is_use_autograph'] ?? '';
$detail['review_autograph'] = empty($review_autograph['autograph'] ?? '') ? '' : $this->makeFileUrl($review_autograph['autograph'],$review_autograph['autograph_type']);
$detail['review_autograph_type'] = $review_autograph['autograph_type'];
}
if($detail['exam_class'] == 'DX' && ($detail['institution_id'] ?? '') == '73000003')
{
$detail['exam_class'] = 'DR';
}
$detail['age'] = str_replace('W','周',str_replace('D','天',str_replace('M','月',str_replace('Y','岁',ltrim($detail['age'],'0')))));
return $detail;
} catch (Exception $exception){
$this->throwError($exception->getMessage(),0001);
}
}
public function makeChineseData($data)
{
switch ($data['sex'])
{
case 'F':
$sex = '女';
break;
case 'M':
$sex = '男';
break;
default:
$sex = '未知';
}
$arr = [
'医院名称'=>$data['institution_name'],
'地址'=>'',
'科室名称'=>'',
'检查设备名称'=>'',
'检查时间'=>$data['exam_datetime'],
'审核时间'=>$data['review_datetime'],
'姓名'=>$data['name'],
'性别'=>$sex,
'年龄'=>$data['age'],
'检查号'=>$data['accession_num'],
'病案号'=>'',
'检查项目'=>$data['exam_project'],
'检查方法'=>$data['exam_class'],
'检查部位'=>$data['body_part'],
'检查参数'=>'',
'征象描述'=>$data['description'],
'结论和建议'=>$data['impression'],
];
return $arr;
}
public function getQrCode($code,$examId)
{
$url = 'https://wechat.pacsonline.cn/wx_patient/api/unifyGetWxQrcode?examId='.$examId.'&version=3';
if(empty($code))
{
$qrCode = $this->curl_get($url);
}else{
$arr = json_decode($code,true);
$time = strtotime($arr['expipy']);
if(time() > $time)
{
$qrCode = $this->curl_get($url);
}else{
$qrCode = $code;
}
}
return json_decode($qrCode,true);
}
public function updateReportData($exam_id, $data, $type, $exam_status, $user, $report_type,$id = null)
{
try{
$status = '';
$doctorId = '';
if($id !== null){
$remote = $this->reportDao->getReportStatus($id);
$status = $remote['report_status'];
$doctorId = $remote['remote_doctor_id'];
}
// 判断类型
switch ($type){
case 'save': // 本地保存
if($report_type == 2){
$write = $this->reportDao->getExam($exam_id);
if($write['write_report'] != 1)
{
//不等于1 则走正常流程
if($exam_status != 3 && $exam_status != 7 && $exam_status != 12){
$this->throwError('流程顺序错误,无法书写报告','0033');
}
}
}else{
// 远程
if($doctorId != $user['id']){
$this->throwError('非受邀医生无法书写报告','0034');
}
if($status != 6 && $status != 7){
$this->throwError('流程顺序错误,无法书写报告','0033');
}
$this->saveProgressLog($user,6,$id);
}
$update = [
'impression' => $data['impression'],
'description' => $data['description'],
'report_result' => $data['report_result'],
'report_datetime' => date('Y-m-d H:i:s'),
'report_doctor_id'=> $user['id'],
'report_doctor_name' =>$user['realname']
];
$exam_up_status = 7;
$trace_type = 1;
break;
case 'audit':
if($report_type == 2){
if($exam_status != 8 && $exam_status != 7){
$this->throwError('流程顺序错误,无法审核报告','0033');
}
}else{
if($status != 8 && $status != 7){
$this->throwError('流程顺序错误,无法审核报告','0033');
}
$this->saveProgressLog($user,7,$id);
}
$update = [
'impression' => $data['impression'],
'description' => $data['description'],
'report_result' => $data['report_result'],
'review_datetime' => date('Y-m-d H:i:s'),
'review_doctor_id'=> $user['id'],
'review_doctor_name'=>$user['realname']
];
$exam_up_status = 8;
$trace_type = 2;
break; // 本地审核
case 'confirm':
if($report_type == 2){
if($exam_status != 8){
$this->throwError('流程顺序错误,无法确认报告','0033');
}
}else{
if($status != 10){
$this->throwError('流程顺序错误,无法确认报告','0033');
}
$this->saveProgressLog($user,9,$id);
}
if(!empty($id)){
$this->reportDao->readMessage($id);
}
$update = [
'confirm_datetime' => date('Y-m-d H:i:s'),
'confirm_doctor_id'=> $user['id'],
'confirm_doctor_name'=>$user['realname']
];
$exam_up_status = 9;
$trace_type = 3;
break; // 本地确认
default:
return false;
}
// 判断远程还是本地
switch ($report_type){
case '2'; //本地
$result = $this->reportDao->updateReport($exam_id,1,$update);
// 修改状态
$this->reportDao->updateExamStatus($exam_id,$exam_up_status);
break;
case '1':
$result = $this->reportDao->updateRemoteReport($id,$update);
// 修改远程状态
$this->reportDao->updateRemoteStauts($id,$exam_up_status);
$this->reportDao->updateremoteExamStatus($exam_id,$exam_up_status);
break;
default :
return false;
}
if(!$result){
return false;
}
if($report_type == '2'){
$rid = $this->reportDao->getReportId($exam_id,1);
}else{
$rid = $this->reportDao->getRemoteReportId($id);
}
/*$detail = $this->reportDao->getReport($exam_id,$report_type);
$cacheToken = $this->getStageKey($rid,$user_id,$detail['exam_status']);
$stage = $this->reportDao->remoteStage($cacheToken);*/
// 添加报告痕迹
$trace = [
'id' => UUIDUtils::uuid(),
'impression' => $update['impression'] ?? '',
'description' => $update['description'] ?? '',
'report_result' => $update['report_result'] ?? '',
'report_id' => $rid,
'createdAt' => date('Y-m-d H:i:s'),
'doctor_id' => $user['id'],
'type' => $trace_type
];
$result = $this->reportDao->insertReportRecord($trace);
if(!$result){
return false;
}
// 成功
return true;
} catch (DbException $exception){
$this->throwError($exception->getMessage(),0001);
}
}
public function saveProgressLog($doctor,$step,$id)
{
$pay_log = [
'id'=>UUIDUtils::uuid(),
'operator_id'=>$doctor['id'],
'operator_name'=>$doctor['realname'],
'current_step'=>$step,
'application_id'=>$id
];
$this->reportDao->savePregressLog($pay_log);
}
public function save_video_url($params)
{
$data = [
'exam_id'=>$params['exam_id'],
'status'=>1
];
$where = ['id'=>$params['id']];
$return = $this->reportDao->saveVideo($data,$where);
return $return;
}
public function cancel_video($id)
{
$info = $this->reportDao->cancel_video($id);
return $info;
}
public function getVideo($params)
{
$id = $params['exam_id'] ?? null;
if(!$id)
{
$this->throwError('无效的id值','0064');
}
$video = $this->reportDao->getVideo($id);
foreach ($video as $k=>$v)
{
$video[$k]['video_url'] = $this->makeFileUrl($v['video_url'],$v['video_type'],'inline');
}
return $video;
}
public function checkWrite($params,$doctor,$cache)
{
$data = ['id'=>$params['report_id'],'name'=>$doctor['realname'],'did'=>$doctor['id']];
if(empty($cache))
{
$this->reportDao->setCache($params['report_id'].'_local',$data,7200);
}else{
if($doctor['id'] !== $cache['did'])
{
//当前医生不属于第一个进入且存储的医生
$this->throwError($cache['name'],'0067');
}
}
return true;
}
// https://query.pacsonline.cn/query/url?&study_id='.$study.'&version=V1.2.0.0
public function getDcmZip($study,$email='',$come='',$examId='',$examClass='')
{
ignore_user_abort(true); // 后台运行,不受前端断开连接影响
set_time_limit(0); //
ob_end_clean();//清除之前的缓冲内容,这是必需的,如果之前的缓存不为空的话,里面可能有http头或者其它内容,导致后面的内容不能及时的输出
header("Connection: close");//告诉浏览器,连接关闭了,这样浏览器就不用等待服务器的响应
header("HTTP/1.1 200 OK"); //可以发送200状态码,以这些请求是成功的,要不然可能浏览器会重试,特别是有代理的情况下
ob_start();//开始当前代码缓冲
if(empty($come))
{
$result = [
'code' => 0,
'msg' => '请求成功',
'data' => '文件生成中',
'error' => null,
'timestamp' => time(),
'random' => null,
'signature' => null,
'request_timestamp' => ZskkDefaultRequest::instance()->header()['zskk-timestamp'] ?? null
];
echo json_encode($result);
}
//下面输出http的一些头信息
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();//输出当前缓冲
flush();//输出PHP缓冲
//在Yii2框架下,上面代码可能不会立即返回给客户端,所以需要加如下的代码,即可实现立即返回给客户端
//具体可查看此文章:http://www.lampnick.com/php/375
if (function_exists("fastcgi_finish_request")) {
fastcgi_finish_request(); /* 响应完成, 关闭连接 */
}
ignore_user_abort(true); // 后台运行,这个只是运行浏览器关闭,并不是直接就中止返回200状态。
try {
set_time_limit(0);
ini_set('memory_limit','1280M');
$study = str_replace('&node_type=1','',$study);
$this->reportDao->insertDcmCompress(['status'=>1,'study_id'=>$study]);
$path = $this->runRack($study,1);
$typeData = $this->reportDao->getDcmPathData([],$study);
$type = $typeData['dcm_type'] ?? 1;
if(strrpos($path,'zip') !== false && file_exists($path))
{
$type = $this->uploadZip($path,$study);
}
if(!empty($email) /* && $come == 'weChat' */)
{
if(strrpos($path,'zip') !== false)
{
$name = $this->reportDao->getPatientName($study);
// 存在zip压缩文件
$this->sendEmail($email,$path,$name,$type);
$this->reportDao->insertDcmCompress(['status'=>9,'study_id'=>$study]);
log::record('邮件发送完毕');
$this->reportDao->updateEmailStatus($email,$study);
}
}
if($come == 'ai')
{
if(strrpos($path,'zip') !== false)
{
// 存在zip压缩文件
$url = 'http://deeplearning.lib.sjtu.edu.cn/';
// $url = 'http://127.0.0.1:5000/';
$data = [
'zip' => new \CURLFile(APP_PATH.'/'.$path),
'exam_id'=>$examId,'exam_class'=>$examClass];
$re = $this->curlPost($url,$data);
if($re == false)
{
log::record("返回值为false");
return "返回值为false";
}
$reData = json_decode($re,true);
if(empty($reData[0] ?? null))
{
log::record('ai接口返回错误,返回信息'.$re);
return $re;
}
$reportData = [
'id'=>UUIDUtils::uuid(),
'impression'=>$reData[0]['diagnosis'],
'description'=>$reData[0]['describe'],
'type'=>3,
'exam_id'=>$examId,
'report_doctor_name'=>'ai报告医生',
'review_doctor_name'=>'ai报告医生',
'confirm_doctor_name'=>'ai报告医生',
'report_datetime'=>date('Y-m-d H:i:s'),
'review_datetime'=>date('Y-m-d H:i:s'),
'confirm_datetime'=>date('Y-m-d H:i:s')
];
$aiData = $this->reportDao->getReport($examId,3);
if($aiData)
{
//修改ai报告
$this->reportDao->updateReport($examId,3,$reportData);
}else{
$this->reportDao->insertReport($reportData);
}
return $re;
}
}
}catch (\think\Exception $e)
{
try {
$this->reportDao->insertDcmCompress(['status'=>999,'study_id'=>$study,'msg'=>$e->getMessage(),'email'=>$email]);
}catch (\think\Exception $exception)
{
$this->reportDao->insertDcmCompress(['status'=>998,'study_id'=>$study,'msg'=>mb_convert_encoding($e->getMessage(), 'UTF-8', 'GBK'),'email'=>$email]);
}
}
}
public function sendDcm($sendData,$study,$examId='',$examClass='')
{
$this->reportDao->saveDcmReportData($sendData,$examId,1,$this->ts_time());
$exam = $this->reportDao->getExam($examId);
$url = 'http://deeplearning.lib.sjtu.edu.cn/';
// $url = 'http://127.0.0.1:5000/';
// $url = 'http://49.7.230.34:5000/';
$query = Config::get('query_url');
$data = [
'down_url' => $query.'/query/down?&study_id='.$study.'&version=V1.2.0.0',
// 'zip' => new \CURLFile(APP_PATH.'/'.$path),
'exam_id'=>$examId,
'exam_class'=>$examClass,
'exam_project'=>empty($exam['exam_project']) ? '' : $exam['exam_project'],
'is_chest'=>($exam['body_part'] == 'CHEST' || strpos($exam['body_part'],'胸') !== false) ? 1 : 0
];
$this->reportDao->saveDcmReportData(json_encode($data),$examId,2,$this->ts_time());
$re = $this->curlPost($url,$data);
$this->reportDao->saveDcmReportData('',$examId,3,$this->ts_time());
$this->reportDao->saveDcmReportData('',$examId,4,$this->ts_time());
return $re;
}
public function testGetDcmZip($study,$email='',$come='',$examId='',$examClass='')
{
$path = $this->runDirRack($study,$examId);
if($come == 'ai')
{
if(strrpos($path,'zip') !== false)
{
// 存在zip压缩文件
$url = 'http://deeplearning.lib.sjtu.edu.cn/';
// $url = 'http://127.0.0.1:5000/';
$data = [
'zip' => new \CURLFile(APP_PATH.'/'.$path),
'exam_id'=>$examId,'exam_class'=>$examClass];
$re = $this->curlPost($url,$data);
if($re == false)
{
log::record("返回值为false");
return "返回值为false";
}
$reData = json_decode($re,true);
if(empty($reData[0] ?? null))
{
log::record('ai接口返回错误,返回信息'.$re);
return $re;
}
$reportData = [
'id'=>UUIDUtils::uuid(),
'impression'=>$reData[0]['diagnosis'],
'description'=>$reData[0]['describe'],
'type'=>3,
'exam_id'=>$examId,
'report_doctor_name'=>'ai报告医生',
'review_doctor_name'=>'ai报告医生',
'confirm_doctor_name'=>'ai报告医生',
'report_datetime'=>date('Y-m-d H:i:s'),
'review_datetime'=>date('Y-m-d H:i:s'),
'confirm_datetime'=>date('Y-m-d H:i:s')
];
$aiData = $this->reportDao->getReport($examId,3);
if($aiData)
{
//修改ai报告
$this->reportDao->updateReport($examId,3,$reportData);
}else{
$this->reportDao->insertReport($reportData);
}
return $re;
}else{
return $path;
}
}
return '生成压缩文件失败,返回'.$path.',请联系开发人员';
}
public function runDirRack($study,$examId)
{
$dcm = $this->getCache($study.'_zip');
if(!empty($dcm))
{
Log::record('已生成过'.$dcm);
return '生成中';
}
ini_set('max_execution_time', 6000);
$time = date('Y-m-d H:i:s',time());
//过期时间 大于当前 则 还没过期
$where = "effective_date > '$time'";
$dcm = $this->reportDao->getDcmPath($where,$study);
if(!empty($dcm))
{
log::record('存在历史dcm地址'.$dcm);
return $dcm;
}
$this->setCache($study.'_zip',$study,600);
log::record('不存在历史地址则继续'.$study);
$query = Config::get('query_url');
//外网地址 需要network 走带宽
$url = $query."/query/down?network=1&study_id=$study&version=V1.2.0.0";
//内网地址
// $url = 'https://query.pacsonline.cn/query/down?&study_id='.$study.'&version=V1.2.0.0';
$data = $this->curl_get($url);
$data = json_decode($data);
if(empty($data))
{
log::record('没有找到dcm信息');
return 'dcm信息没有找到';
}
$date = time();
$create = ROOT_PATH . 'public' . DS . 'download'.DS.$date;
log::record('压缩中');
$path = $this->zipDir($data,$create,$date,$study,$examId);
log::record('压缩成功');
return $path;
}
public function zipDir($data,$create,$date,$study,$examId)
{
ini_set('max_execution_time', 6000);
$fileList = [];
foreach ($data as $k=>$v)
{
$v = (array)$v;
$path = $this->downLoad($v['url'],$create.DS.$v['seriesuid'].DS.$k,$create.DS.$v['seriesuid']);
$fileList[] = ['path'=>$path,'series'=>$v['seriesuid']];
}
$zipPath = ROOT_PATH . 'public' . DS .'zip';
$filename = $zipPath.DS."$examId.zip";
if (!file_exists($zipPath)) {
mkdir($zipPath, 0777,true);
@chmod($zipPath, 0777);
}
$zip = new \ZipArchive();
$zip->open($filename,\ZipArchive::CREATE); //打开压缩包
foreach($fileList as $file){
$zip->addFile($file['path'],$file['series'].DS.basename($file['path'])); //向压缩包中添加文件
}
$zip->close(); //关闭压缩包
$insert = [
'dcm_path'=>'zip/'.$examId.".zip",
'study_id'=>$study,
'effective_date'=>date('Y-m-d H:i:s',time()+864000), //10天有效期
];
$this->reportDao->insertDcmPath($insert);
return 'zip/'.$examId.".zip";
}
public function runRack($study,$come='')
{
if($come != 1)
{
$dcm = $this->getCache($study.'_zip');
if(!empty($dcm))
{
Log::record('已生成过'.$dcm);
return '生成中';
}
}
ini_set('max_execution_time', 6000);
$time = date('Y-m-d H:i:s',time());
//过期时间 大于当前 则 还没过期
$where = "effective_date > '$time'";
$dcm = $this->reportDao->getDcmPath($where,$study);
if(!empty($dcm))
{
log::record('存在历史dcm地址'.$dcm);
return $dcm;
}
$this->setCache($study.'_zip',$study,600);
log::record('不存在历史地址则继续'.$study);
$query = Config::get('query_url');
//外网地址 需要network 走带宽
// $url = "https://query.pacsonline.cn/query/url?network=1&study_id=$study&version=V1.2.0.0";
//内网地址
$url = $query.'/query/url?&study_id='.$study.'&version=V1.2.0.0';
$data = $this->curl_get($url);
$data = json_decode($data);
if(empty($data))
{
log::record('没有找到dcm信息');
return '';
}
$this->reportDao->insertDcmCompress(['status'=>2,'study_id'=>$study]);
$date = time();
$create = ROOT_PATH . 'public' . DS . 'download'.DS.$date;
log::record('压缩中');
$path = $this->zip($data,$create,$date,$study);
log::record('压缩成功');
return $path;
}
public function zip($data,$create,$date,$study)
{
ini_set('max_execution_time', 6000);
$fileList = [];
$exam = $this->reportDao->getExamByStudy($study);
$this->reportDao->insertDcmCompress(['status'=>3,'study_id'=>$study]);
if($exam['institution_id'] == '06300009')
{
$patient_num = $exam['patient_num'];
$name = $exam['name'];
//工人医院需要解密
if (!file_exists($create)) {
mkdir($create, 0777,true);
@chmod($create, 0777);
}
$ts = system("python3.8 /data/code/ris_server/utils/down/main.py '$patient_num' '$study' '$name' $date");
if($ts)
{
$files = scandir($create);
foreach ($files as $v)
{
if($v == '.' || $v == '..')
{
continue;
}
$fileList[] = $create.DS.$v;
}
}
}else{
foreach ($data as $k=>$v)
{
$path = $this->downLoad($v,$create.DS.$k,$create);
$fileList[] = $path;
}
$zipPath = ROOT_PATH . 'public' . DS .'zip';
$filename = $zipPath.DS."$date.zip";
if (!file_exists($zipPath)) {
mkdir($zipPath, 0777,true);
@chmod($zipPath, 0777);
}
$this->reportDao->insertDcmCompress(['status'=>4,'study_id'=>$study]);
$zip = new \ZipArchive();
$zip->open($filename,\ZipArchive::CREATE); //打开压缩包
foreach($fileList as $file){
$zip->addFile($file,basename($file)); //向压缩包中添加文件
}
$zip->close(); //关闭压缩包
$filesDcm = scandir($create);
foreach ($filesDcm as $file) {
if ($file != '.' && $file != '..') {
$pathDcm = $create . '/' . $file;
@unlink($pathDcm);
}
}
@rmdir($create);
}
$this->reportDao->insertDcmCompress(['status'=>5,'study_id'=>$study]);
$path_url = 'zip/'.$date.".zip";
$insert = [
'dcm_path'=>$path_url,
'study_id'=>$study,
'effective_date'=>date('Y-m-d H:i:s',time()+864000), //10天有效期
];
$this->reportDao->insertDcmPath($insert);
$this->delCache($study.'_zip');
$this->reportDao->insertDcmCompress(['status'=>6,'study_id'=>$study]);
return $path_url;
}
public function uploadZip($path_url,$study)
{
$this->reportDao->insertDcmCompress(['status'=>7,'study_id'=>$study]);
$upload = new uploadToCloud();
$s = $upload->upload($path_url,$path_url,'3','2','2','2');
if(($s['@metadata']['statusCode'] ?? '') == '200')
{
$this->reportDao->insertDcmCompress(['status'=>8,'study_id'=>$study]);
gc_collect_cycles();
$this->reportDao->updateDcmPath(['study_id'=>$study],['dcm_type'=>4]);
unlink($path_url);
return 4;
}
return '1';
}
public function changeReport($param,$token)
{
$user = $this->reportDao->getUser($token);
$result = $this->reportAuthentication($user['id'], 'reject', $user['institution_id'],2);
if(!$result){
$this->throwError('权限未分配,请联系管理员',0005);
}
$id = $param['id'];
$info = $this->reportDao->updateExamStatus($id,7);
$this->reportDao->updateReport($id,1,['review_doctor_id'=>null]);
$data = [
'exam_id'=>$id,
'doctor_id'=>$user['id'],
'doctor_name'=>$user['realname']
];
$this->reportDao->insertReject($data);
return $info;
}
public function checkLock($params,$token)
{
return '';
$user = $this->getCache($token);
$id = $params['id'];
$info = $this->reportDao->checkLock($id);
if($user['id'] == $info['doctor_id'])
{
return '';
}else{
return $info['doctor_name'];
}
}
public function sendEmail($email,$dcmPath,$name,$type=1)
{
$mail = new PHPMailer(true); // Passing `true` enables exceptions
try {
//服务器配置
$mail->CharSet ="UTF-8"; //设定邮件编码
$mail->SMTPDebug = 0; // 调试模式输出
$mail->isSMTP(); // 使用SMTP
$mail->Host = 'smtp.exmail.qq.com'; // SMTP服务器
$mail->SMTPAuth = true; // 允许 SMTP 认证
$mail->Username = 'company@pacsonline.cn'; // SMTP 用户名 即邮箱的用户名
$mail->Password = 'Zskk1234'; // SMTP 密码 部分邮箱是授权码(例如163邮箱)
$mail->SMTPSecure = 'ssl'; // 允许 TLS 或者ssl协议
$mail->Port = 465;
// $mail->SMTPOptions = [
// 'ssl' => [
// 'verify_peer' => false,
// 'verify_peer_name' => false,
// 'allow_self_signed' => true
// ]
// ];
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
// 服务器端口 25 或者465 具体要看邮箱服务器支持
$mail->setFrom('company@pacsonline.cn', '冠医云'); //发件人
$mail->addAddress($email, ''); // 收件人
//$mail->addAddress('ellen@example.com'); // 可添加多个收件人
$mail->addReplyTo('company@pacsonline.cn', '冠医云'); //回复的时候回复给哪个邮箱 建议和发件人一致
//$mail->addCC('cc@example.com'); //抄送
//$mail->addBCC('bcc@example.com'); //密送
$zipPath = ROOT_PATH . 'public';
// $maxsize = 45 * 1024 * 1024;
$mail->Subject = $name.'影像';
// if(filesize($zipPath.'/'.$dcmPath) < $maxsize)
// {
// //发送附件
//// $mail->addAttachment($zipPath.'a.zip'); // 添加附件
// $mail->addAttachment($zipPath.'/'.$dcmPath, $name.'.zip'); // 发送附件并且重命名
// $mail->Body = "链接将于".date('Y-m-d',time()+10*24*3600)."失效,请即时下载";
// $mail->AltBody = "链接将于".date('Y-m-d',time()+10*24*3600)."失效,请即时下载";
// }else{
//发送链接地址
//Content
$mail->isHTML(true); // 是否以HTML文档格式发送 发送后客户端可直接显示对应HTML内容
if($type == 4)
{
$dcmPath = $this->makeFileUrl($dcmPath,$type,'attachment','+3 days');
$dcmPath = ltrim($dcmPath,'/');
$mail->Body = "下载".$name."影像"."
链接将于".date('Y-m-d',time()+3*24*3600)."失效,请及时下载";
}else
{
$mail->Body = "下载".$name."影像"."
链接将于".date('Y-m-d',time()+3*24*3600)."失效,请及时下载";
}
// $mail->AltBody = '如果邮件客户端不支持HTML则显示此内容';
// }
$mail->send();
return '邮件发送成功';
} catch (Exception $e) {
// return '邮件发送失败: ';
return '邮件发送失败: '.$mail->ErrorInfo;
}
}
public function getAiReport($param)
{
$id = $param['exam_id'];
$data = $this->reportDao->getReport($id,3);
return $data;
}
public function deleteAiReport($param)
{
$id = $param['exam_id'];
$data = $this->reportDao->deleteAiReport($id,3);
return $data;
}
}