/report/save 方法完整操作流程 1. 控制器层 (ReportController.php:45-56) public function save(ReportService $service) { $params = $this->getParams(); ReportValidate::checkSave($params); // 参数验证 $token = $this->getToken(); $result = $service->updateReport($params['exam_id'], $params, 'save', '2', $token); return $this->success($result); } 参数说明: - exam_id:检查ID - params:所有表单参数 - 'save':操作类型(保存) - '2':报告类型(2=本地报告,1=远程报告) - token:用户token 2. 核心业务逻辑 (ReportService.php:214-413) 2.1 权限验证 // 1. 获取检查信息 $exam = $this->reportDao->getExam($examId); $phone = $exam['phone'] ?? ''; $studyId = $exam['study_id']; // 2. 获取用户信息 $user = $this->reportDao->getUser($token); $user_id = $user['id']; // 3. 验证报告权限 $result = $this->reportAuthentication($user_id, $type, $exam['institution_id'], $reportType); if(!$result){ throw '权限未分配,请联系管理员'; } 2.2 获取或创建报告记录 $rt = ($reportType == 1) ? 2 : 1; $report = $this->reportDao->getReport($examId, $rt, $ra_id); $reportId = $report['id'] ?? null; // 如果报告不存在,创建新报告 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); $reportId = $insert_data['id']; } } 2.3 检查报告锁定状态 // 检查是否被其他医生锁定 if ($user_id !== $report['report_doctor_id'] && !empty($report['report_doctor_id'])) { throw '该报告已被其他医师书写,请刷新当前有页面进行查看!'; } 2.4 添加报告锁定记录(特定机构) // 如果是特定机构(43600001),添加锁定状态 if($user['institution_id'] == '43600001') { if($type == 'save' || $type == 'audit') { $middle = [ 'institution_id' => $user['institution_id'], 'status' => 0, // 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]); if($middleInfo) { unset($middle['is_sync']); $middleWhere = ['exam_id'=>$examId]; } $this->reportDao->saveRmiddle($middle, $middleWhere); } } 2.5 更新检查基本信息 // 处理性别字段 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, 'phone' => $data['phone'] ]; if($rt == 1){ $exam_res = $this->reportDao->updateExamMsg($examId, $exam['patient_id'], $update); }else{ $remote_res = $this->reportDao->updateRemote($ra_id, $update); } 2.6 更新报告内容 $report_up = [ 'impression' => $data['impression'] ?? null, // 诊断意见 'description' => $data['description'] ?? null, // 报告描述 'report_result' => $data['report_result'] ?? null, // 报告结果 'hr_status' => $data['hr_status'] ?? 1 // 高危状态 ]; 2.7 调用 updateReportData 方法 (ReportService.php:782-922) 2.7.1 验证流程状态 // 本地保存 if($report_type == 2){ $write = $this->reportDao->getExam($exam_id); if($write['write_report'] != 1) { // 检查状态:必须是3、7或12才能书写 if($exam_status != 3 && $exam_status != 7 && $exam_status != 12){ throw '流程顺序错误,无法书写报告'; } } } 2.7.2 更新报告数据 $update = [ 'impression' => $data['impression'], 'description' => $data['description'], 'hr_status' => $data['hr_status'], 'report_result' => $data['report_result'], 'report_datetime' => date('Y-m-d H:i:s'), // 书写时间 'report_doctor_id' => $user['id'], // 书写医生ID 'report_doctor_name' => $user['realname'] // 书写医生姓名 ]; // 更新报告表 $result = $this->reportDao->updateReport($exam_id, 1, $update); // 更新检查状态为7(已书写) $this->reportDao->updateExamStatus($exam_id, 7); 2.7.3 插入报告痕迹记录 $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' => 1 // 1=书写 ]; $result = $this->reportDao->insertReportRecord($trace); 涉及的数据库表操作 1. report 表 - INSERT:创建新报告记录(如果不存在) - UPDATE:更新报告内容(impression、description、report_result、hr_status、report_datetime、report_doctor_id、report_doctor_name) 2. exam 表 - SELECT:查询检查信息 - UPDATE:更新患者基本信息(name、sex、age、exam_class、exam_project、phone) - UPDATE:更新检查状态为7(已书写) 3. rmiddle 表(报告锁定中间表,仅特定机构) - INSERT/UPDATE:保存报告锁定记录 4. report_record 表(报告痕迹表) - INSERT:插入报告操作痕迹记录 5. patient 表 - UPDATE:更新患者信息(通过 exam_id 关联) 6. remote_application 表(远程报告,如果是远程类型) - UPDATE:更新远程申请单信息 操作总结 /report/save 方法执行以下操作: 1. ✅ 参数验证 2. ✅ 权限验证:检查用户是否有报告书写权限 3. ✅ 获取/创建报告:如果报告不存在则创建新记录 4. ✅ 锁定检查:防止多个医生同时编辑同一报告 5. ✅ 添加锁定记录:为特定机构添加报告锁定状态 6. ✅ 更新患者基本信息:姓名、性别、年龄、检查类型、手机号等 7. ✅ 更新报告内容:诊断意见、报告描述、报告结果、高危状态 8. ✅ 更新书写医生信息:记录书写医生ID和姓名 9. ✅ 更新书写时间:记录报告书写时间 10. ✅ 更新检查状态:将检查状态更新为7(已书写) 11. ✅ 插入报告痕迹:保存报告修改历史记录 关键状态码 - exam_status: - 3:待书写 - 7:已书写 - 8:已审核 - 9:已确认 - 12:特殊状态(允许书写) - report 锁定状态: - 0:锁定中 - 1:已解锁 这个方法实现了完整的报告保存流程,包括权限控制、并发控制、数据更新和历史记录等功能。