# apply/step2 接口实现说明 ## 接口信息 **接口路径**: `POST /api/apply/step2` **功能说明**: 保存或更新远程申请的病例资料(第二步),完善患者临床信息 --- ## PHP项目核心逻辑分析 ### 1. Controller 层 (ApplyController.php) ```php public function step2(ApplicationService $service) { try{ $params = $this->getParams(); // 验证参数(id必填) ApplicationValidate::checkId($params); // 处理参数(将id改为exam_id) $param = $service->handle_save($params); // 保存申请单,状态设置为step3(3=完善病例资料保存继续) $return = $service->save_application($param, Config::get('remote_status')['step3']); return $this->success($return); }catch(\Exception $e){ $this->throwError($e->getMessage(),0001); } } ``` ### 2. Service 层 (ApplicationService.php) #### 2.1 handle_save 方法 ```php public function handle_save($params) { $info = $params; $info['exam_id'] = $params['id']; // 将id改为exam_id unset($info['id']); $info['createdAt'] = date('Y-m-d H:i:s', time()); return $info; } ``` #### 2.2 save_application 方法(核心逻辑) ```php public function save_application($param, $status) { $id = UUIDUtils::uuid(); $application_id = $param['application_id'] ?? ''; // 获取申请单ID(编辑时传入) // 1. 准备更新数据 $info = array(); // 患者基本信息 $info['name'] = $param['name']; $sex = $this->getSex($param['sex']); // 性别转换 $info['sex'] = $sex; $info['age'] = $param['age']; $info['phone'] = $param['phone']; $info['patient_num'] = $param['patient_num']; $info['accession_num'] = $param['accession_num']; $info['birthday'] = $param['birthday']; $info['card_num'] = $param['card_num']; // 检查信息 $info['exam_datetime'] = $param['exam_datetime']; $info['exam_class'] = $param['exam_class']; $info['exam_project'] = $param['exam_project']; $info['exam_sub_class'] = $param['exam_sub_class']; $info['body_part'] = $param['body_part']; $info['body_part_text'] = $param['body_part_text'] ?? ''; $info['exam_id'] = $param['exam_id']; $info['study_id'] = $param['study_id']; // 临床信息 $info['illness_desc'] = $param['illness_desc'] ?? ''; // 患者主诉 $info['phys_sign'] = $param['phys_sign'] ?? ''; // 体征 $info['clin_symp'] = $param['clin_symp'] ?? ''; // 症状 $info['anamnesis'] = $param['anamnesis'] ?? ''; // 疾病史 $info['family_ill'] = $param['family_ill'] ?? ''; // 家族史 $info['clin_diag'] = $param['clin_diag'] ?? ''; // 初步诊断 $info['more'] = $param['more'] ?? ''; // 补充说明 $info['remote_department'] = $param['remote_department'] ?? ''; // 申请科室 // 附件信息 $info['attachment'] = $param['attachment'] ?? ''; // 补充资料 $info['attachment_type'] = $param['attachment_type'] ?? 1; // 附件存储类型 $info['remark'] = $param['remark'] ?? ''; // 备注 // 从exams表查询相关字段 $node = $this->application->getExam($param['exam_id'], 'node_type'); $info['node_type'] = $node['node_type']; $hopitalized = $this->application->getExam($param['exam_id'], 'hopitalized_no'); $info['hopitalized_no'] = $hopitalized['hopitalized_no']; // 状态设置为3(完善病例资料保存继续) $info['report_status'] = $status; // 2. 更新exams表的手机号 $this->application->updateExam($param['exam_id'], $param['phone']); // 3. 保存或更新remote_application if (!empty($application_id)) { // 存在则更新 $return = $this->application->updateApplication($info, $application_id); $return_id = $application_id; } else { // 不存在则新建 $info['id'] = $id; $return = $this->application->insertAplication($info); $return_id = $id; } // 4. 返回申请单ID和检查类别 $r['id'] = $return_id; $r['class'] = $param['exam_class']; return $r; } ``` --- ## 请求参数 ### Step2RequestVO ```java @Data public class ApplyStep2RequestVO { @NotBlank(message = "检查ID不能为空") private String id; // exam_id private String applicationId; // 申请单ID(编辑时传入) // 患者基本信息 @NotBlank(message = "患者姓名不能为空") private String name; @NotBlank(message = "性别不能为空") private String sex; @NotBlank(message = "年龄不能为空") private String age; private String phone; private String patientNum; private String accessionNum; private String birthday; private String cardNum; // 检查信息 private String examDatetime; @NotBlank(message = "检查类别不能为空") private String examClass; private String examProject; private String examSubClass; private String bodyPart; private String bodyPartText; private String studyId; // 临床信息 private String illnessDesc; // 患者主诉 private String physSign; // 体征 private String clinSymp; // 症状 private String anamnesis; // 疾病史 private String familyIll; // 家族史 private String clinDiag; // 初步诊断 private String more; // 补充说明 private String remoteDepartment; // 申请科室 // 附件信息 private String attachment; // 补充资料 private Integer attachmentType; // 附件存储类型:1=本地,2=移动云 private String remark; // 备注 } ``` --- ## 响应数据 ### Step2ResponseDTO ```java @Data public class ApplyStep2ResponseDTO { @Schema(description = "申请单ID") private String id; @Schema(description = "检查类别") private String examClass; } ``` --- ## Java项目实现方案 ### 1. Service 实现 ```java @Override @Transactional(rollbackFor = Exception.class) public ApplyStep2ResponseDTO saveStep2(ApplyStep2RequestVO requestVO) { String examId = requestVO.getId(); String applicationId = requestVO.getApplicationId(); // 1. 性别转换 String sex = StrUtils.formatSex(requestVO.getSex()); // 2. 查询exams表获取node_type和hopitalized_no Exams exam = examsMapper.selectById(examId); if (exam == null) { throw new RuntimeException("检查不存在"); } // 3. 准备remote_application数据 RemoteApplication application = new RemoteApplication(); // 患者基本信息 application.setName(requestVO.getName()); application.setSex(sex); application.setAge(requestVO.getAge()); application.setPhone(requestVO.getPhone()); application.setPatientNum(requestVO.getPatientNum()); application.setAccessionNum(requestVO.getAccessionNum()); application.setBirthday(requestVO.getBirthday()); application.setCardNum(requestVO.getCardNum()); // 检查信息 application.setExamDatetime(requestVO.getExamDatetime()); application.setExamClass(requestVO.getExamClass()); application.setExamProject(requestVO.getExamProject()); application.setExamSubClass(requestVO.getExamSubClass()); application.setBodyPart(requestVO.getBodyPart()); application.setBodyPartText(requestVO.getBodyPartText()); application.setExamId(examId); application.setStudyId(requestVO.getStudyId()); application.setNodeType(exam.getNodeType()); application.setHopitalizedNo(exam.getHopitalizedNo()); // 临床信息 application.setIllnessDesc(requestVO.getIllnessDesc()); application.setPhysSign(requestVO.getPhysSign()); application.setClinSymp(requestVO.getClinSymp()); application.setAnamnesis(requestVO.getAnamnesis()); application.setFamilyIll(requestVO.getFamilyIll()); application.setClinDiag(requestVO.getClinDiag()); application.setMore(requestVO.getMore()); application.setRemoteDepartment(requestVO.getRemoteDepartment()); // 附件信息 application.setAttachment(requestVO.getAttachment()); application.setAttachmentType(requestVO.getAttachmentType() != null ? requestVO.getAttachmentType() : 1); application.setRemark(requestVO.getRemark()); // 状态设置为3(完善病例资料保存继续) application.setReportStatus(3); // 4. 更新exams表的手机号 Exams updateExam = new Exams(); updateExam.setId(examId); updateExam.setPhone(requestVO.getPhone()); examsMapper.updateById(updateExam); // 5. 保存或更新remote_application String returnId; if (StringUtils.isNotBlank(applicationId)) { // 编辑:更新现有申请单 application.setId(applicationId); remoteApplicationMapper.updateById(application); returnId = applicationId; log.info("更新远程申请成功,applicationId={}", applicationId); } else { // 新建:创建申请单 remoteApplicationMapper.insert(application); // MyBatis-Plus自动生成UUID returnId = application.getId(); log.info("创建远程申请成功,applicationId={}", returnId); } // 6. 返回结果 ApplyStep2ResponseDTO response = new ApplyStep2ResponseDTO(); response.setId(returnId); response.setExamClass(requestVO.getExamClass()); return response; } ``` ### 2. Controller 实现 ```java @PostMapping("/step2") @Operation(summary = "保存病例资料", description = "远程申请第二步:保存或更新病例资料") @SystemLogHandler("保存病例资料|保存") public RestResult saveStep2(@RequestBody @Valid ApplyStep2RequestVO requestVO) { try { ApplyStep2ResponseDTO response = remoteApplicationService.saveStep2(requestVO); return RestResult.ok("保存成功", response); } catch (RuntimeException e) { return RestResult.error(e.getMessage()); } catch (Exception e) { return RestResult.error("保存失败:" + e.getMessage()); } } ``` --- ## 状态说明 ### remote_application.report_status | 状态值 | 说明 | 对应步骤 | |-------|------|---------| | 1 | 初始创建 | step1 | | 2 | 保存完善病例资料 | step2(中间状态) | | 3 | 完善病例资料保存继续 | step2(完成状态) | | 4 | 选择医院发起申请 | step3 | | 5 | 驳回申请 | reject | | 6 | 接收申请 | agree | | 7 | 写报告 | save | | 8 | 审核报告 | audit | | 9 | 最终完成报告 | - | | 10 | 确认报告 | confirm | | 11 | 撤回报告 | - | --- ## 核心业务逻辑 1. **参数处理**:将 `id` 字段转换为 `exam_id` 2. **性别转换**:统一转换为标准格式(M/F) 3. **查询关联数据**:从 `exams` 表获取 `node_type` 和 `hopitalized_no` 4. **更新exams表**:同步更新患者手机号 5. **保存或更新申请单**: - 有 `application_id`:更新现有申请单 - 无 `application_id`:创建新申请单 6. **状态设置**:`report_status = 3`(完善病例资料保存继续) 7. **返回数据**:返回 `application_id` 和 `exam_class` --- ## 注意事项 1. **字段完整性**:step2保存了大量临床信息,这些信息在后续步骤中会被使用 2. **幂等性**:通过 `application_id` 判断是新建还是更新,支持多次提交 3. **数据同步**:需要同时更新 `exams` 表和 `remote_application` 表 4. **状态流转**:step2 完成后状态为3,为 step3(发起申请)做准备 5. **附件处理**:支持本地和移动云两种存储方式