fix(inpatient): 解决手术申请单数据同步和命名问题

- 在应用表单底部按钮中添加延迟刷新机制,确保后端数据提交完成后再触发刷新事件
- 在手术组件中添加诊疗定义名称字段,完善手术项目信息传递
- 优化手术医嘱生成功能,添加详细的调试日志以便追踪问题
- 修复手术项目名称获取逻辑,优先使用activityList中的手术项目名称
- 完善手术收费项目生成流程,添加异常处理和日志记录
- 在控制器中添加手术申请单保存的日志输出,便于问题排查
This commit is contained in:
2026-04-02 08:15:11 +08:00
parent 5b0acede89
commit 2d7dcb4aeb
4 changed files with 183 additions and 128 deletions

View File

@@ -216,136 +216,186 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
}
// 如果是手术申请单,需要额外生成手术医嘱
if (ActivityDefCategory.PROCEDURE.getCode().equals(typeCode)) {
log.info("开始生成手术医嘱encounterId={}, patientId={}, typeCode={}", encounterId, patientId, typeCode);
// 从 descJson 中解析手术信息
String descJson = requestFormSaveDto.getDescJson();
Map<String, Object> descMap = null;
if (descJson != null && !descJson.isEmpty()) {
try {
ObjectMapper objectMapper = new ObjectMapper();
descMap = objectMapper.readValue(descJson, Map.class);
} catch (Exception e) {
log.error("解析手术申请单 descJson 失败", e);
}
}
// 获取手术信息
String surgeryName = descMap != null ? (String) descMap.get("surgeryName") : null;
String surgeryCode = descMap != null ? (String) descMap.get("surgeryCode") : null;
String surgeryFee = descMap != null ? (String) descMap.get("surgeryFee") : null;
String anesthesiaFee = descMap != null ? (String) descMap.get("anesthesiaFee") : null;
String plannedTime = descMap != null ? (String) descMap.get("plannedTime") : null;
String surgeryIndication = descMap != null ? (String) descMap.get("surgeryIndication") : null;
String preoperativeDiagnosis = descMap != null ? (String) descMap.get("preoperativeDiagnosis") : null;
// 生成手术医嘱
ServiceRequest surgeryServiceRequest = new ServiceRequest();
surgeryServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());
surgeryServiceRequest.setBusNo(String.format("%04d", (int) (Math.random() * 10000)));
surgeryServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
surgeryServiceRequest.setPrescriptionNo(prescriptionNo);
surgeryServiceRequest.setTherapyEnum(TherapyTimeType.TEMPORARY.getValue());
surgeryServiceRequest.setQuantity(BigDecimal.valueOf(1));
surgeryServiceRequest.setUnitCode("");
surgeryServiceRequest.setCategoryEnum(4); // 4-手术
// 优先从 activityList 获取手术 ID如果为空则从 descJson 获取
if (!activityList.isEmpty()) {
surgeryServiceRequest.setActivityId(activityList.get(0).getAdviceDefinitionId());
}
surgeryServiceRequest.setPatientId(patientId);
surgeryServiceRequest.setRequesterId(practitionerId);
surgeryServiceRequest.setEncounterId(encounterId);
surgeryServiceRequest.setAuthoredTime(curDate);
surgeryServiceRequest.setOrgId(orgId);
// 设置手术相关信息到 contentJson 字段
Map<String, String> contentMap = new java.util.HashMap<>();
if (surgeryName != null && !surgeryName.isEmpty()) {
contentMap.put("surgeryName", surgeryName);
}
if (surgeryCode != null && !surgeryCode.isEmpty()) {
contentMap.put("surgeryCode", surgeryCode);
}
if (plannedTime != null && !plannedTime.isEmpty()) {
contentMap.put("plannedTime", plannedTime);
}
if (surgeryIndication != null && !surgeryIndication.isEmpty()) {
contentMap.put("surgeryIndication", surgeryIndication);
}
if (preoperativeDiagnosis != null && !preoperativeDiagnosis.isEmpty()) {
contentMap.put("preoperativeDiagnosis", preoperativeDiagnosis);
}
if (!contentMap.isEmpty()) {
try {
ObjectMapper objectMapper = new ObjectMapper();
surgeryServiceRequest.setContentJson(objectMapper.writeValueAsString(contentMap));
} catch (Exception e) {
log.error("序列化手术信息失败", e);
}
}
iServiceRequestService.save(surgeryServiceRequest);
log.info("手术医嘱生成成功serviceRequestId={}, prescriptionNo={}", surgeryServiceRequest.getId(), prescriptionNo);
// 生成手术收费项目
ChargeItem surgeryChargeItem = new ChargeItem();
surgeryChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
surgeryChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
surgeryChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
surgeryChargeItem.setPatientId(patientId);
surgeryChargeItem.setContextEnum(6); // 6-手术
surgeryChargeItem.setEncounterId(encounterId);
surgeryChargeItem.setEntererId(practitionerId);
surgeryChargeItem.setEnteredDate(curDate);
surgeryChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
surgeryChargeItem.setServiceId(surgeryServiceRequest.getId());
surgeryChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
// 优先从 activityList 获取 productId如果为空则不设置
if (!activityList.isEmpty()) {
surgeryChargeItem.setProductId(activityList.get(0).getAdviceDefinitionId());
}
surgeryChargeItem.setAccountId(activityList.isEmpty() ? null : activityList.get(0).getAccountId());
surgeryChargeItem.setRequestingOrgId(orgId);
surgeryChargeItem.setQuantityValue(BigDecimal.valueOf(1));
surgeryChargeItem.setQuantityUnit("");
// 设置手术费用
if (surgeryFee != null && !surgeryFee.isEmpty()) {
try {
surgeryChargeItem.setUnitPrice(new BigDecimal(surgeryFee));
surgeryChargeItem.setTotalPrice(new BigDecimal(surgeryFee));
} catch (NumberFormatException e) {
log.warn("手术费用格式不正确:{}", surgeryFee);
}
}
iChargeItemService.save(surgeryChargeItem);
// 如果存在麻醉费用,生成麻醉收费项目
if (anesthesiaFee != null && !anesthesiaFee.isEmpty()) {
try {
BigDecimal anesthesiaFeeAmount = new BigDecimal(anesthesiaFee);
if (anesthesiaFeeAmount.compareTo(BigDecimal.ZERO) > 0) {
ChargeItem anesthesiaChargeItem = new ChargeItem();
anesthesiaChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
anesthesiaChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
anesthesiaChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
anesthesiaChargeItem.setPatientId(patientId);
anesthesiaChargeItem.setContextEnum(3); // 3-诊疗
anesthesiaChargeItem.setEncounterId(encounterId);
anesthesiaChargeItem.setEntererId(practitionerId);
anesthesiaChargeItem.setEnteredDate(curDate);
anesthesiaChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
anesthesiaChargeItem.setServiceId(surgeryServiceRequest.getId());
anesthesiaChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
anesthesiaChargeItem.setRequestingOrgId(orgId);
anesthesiaChargeItem.setQuantityValue(BigDecimal.valueOf(1));
anesthesiaChargeItem.setQuantityUnit("");
anesthesiaChargeItem.setUnitPrice(anesthesiaFeeAmount);
anesthesiaChargeItem.setTotalPrice(anesthesiaFeeAmount);
iChargeItemService.save(anesthesiaChargeItem);
log.info("【调试】判断手术医嘱生成条件: typeCode={}, PROCEDURE.code={}, typeCode类型={}, PROCEDURE.code类型={}",
typeCode, ActivityDefCategory.PROCEDURE.getCode(),
typeCode != null ? typeCode.getClass().getName() : "null",
ActivityDefCategory.PROCEDURE.getCode().getClass().getName());
boolean isProcedure = ActivityDefCategory.PROCEDURE.getCode().equals(typeCode);
log.info("【调试】判断结果: isProcedure={}, typeCode字符串={}, PROCEDURE.code字符串={}",
isProcedure,
typeCode != null ? "'" + typeCode + "'" : "null",
"'" + ActivityDefCategory.PROCEDURE.getCode() + "'");
if (isProcedure) {
log.info("开始生成手术医嘱encounterId={}, patientId={}, typeCode={}, activityListSize={}",
encounterId, patientId, typeCode, activityList != null ? activityList.size() : 0);
try {
// 从 descJson 中解析手术信息
String descJson = requestFormSaveDto.getDescJson();
Map<String, Object> descMap = null;
if (descJson != null && !descJson.isEmpty()) {
try {
ObjectMapper objectMapper = new ObjectMapper();
descMap = objectMapper.readValue(descJson, Map.class);
log.info("解析手术申请单 descJson 成功: {}", descMap);
} catch (Exception e) {
log.error("解析手术申请单 descJson 失败: {}", descJson, e);
}
} catch (NumberFormatException e) {
log.warn("麻醉费用格式不正确:{}", anesthesiaFee);
} else {
log.warn("手术申请单 descJson 为空");
}
// 获取手术信息
String surgeryName = descMap != null ? (String) descMap.get("surgeryName") : null;
String surgeryCode = descMap != null ? (String) descMap.get("surgeryCode") : null;
String surgeryFee = descMap != null ? (String) descMap.get("surgeryFee") : null;
String anesthesiaFee = descMap != null ? (String) descMap.get("anesthesiaFee") : null;
String plannedTime = descMap != null ? (String) descMap.get("plannedTime") : null;
String surgeryIndication = descMap != null ? (String) descMap.get("surgeryIndication") : null;
String preoperativeDiagnosis = descMap != null ? (String) descMap.get("preoperativeDiagnosis") : null;
// 🔧 BugFix#318: 从 activityList 获取手术项目名称
String adviceDefinitionName = null;
if (activityList != null && !activityList.isEmpty()) {
adviceDefinitionName = activityList.get(0).getAdviceDefinitionName();
log.info("从 activityList 获取手术项目名称: {}", adviceDefinitionName);
}
log.info("手术信息: surgeryName={}, surgeryCode={}, surgeryFee={}, anesthesiaFee={}, adviceDefinitionName={}",
surgeryName, surgeryCode, surgeryFee, anesthesiaFee, adviceDefinitionName);
// 生成手术医嘱
ServiceRequest surgeryServiceRequest = new ServiceRequest();
surgeryServiceRequest.setStatusEnum(RequestStatus.DRAFT.getValue());
surgeryServiceRequest.setBusNo(String.format("%04d", (int) (Math.random() * 10000)));
surgeryServiceRequest.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
surgeryServiceRequest.setPrescriptionNo(prescriptionNo);
surgeryServiceRequest.setTherapyEnum(TherapyTimeType.TEMPORARY.getValue());
surgeryServiceRequest.setQuantity(BigDecimal.valueOf(1));
surgeryServiceRequest.setUnitCode("");
surgeryServiceRequest.setCategoryEnum(4); // 4-手术
// 优先从 activityList 获取手术 ID
if (activityList != null && !activityList.isEmpty()) {
Long activityId = activityList.get(0).getAdviceDefinitionId();
surgeryServiceRequest.setActivityId(activityId);
log.info("从 activityList 获取手术ID: {}", activityId);
} else {
log.warn("activityList 为空无法获取手术ID");
}
surgeryServiceRequest.setPatientId(patientId);
surgeryServiceRequest.setRequesterId(practitionerId);
surgeryServiceRequest.setEncounterId(encounterId);
surgeryServiceRequest.setAuthoredTime(curDate);
surgeryServiceRequest.setOrgId(orgId);
// 设置手术相关信息到 contentJson 字段
Map<String, String> contentMap = new java.util.HashMap<>();
// 🔧 BugFix#318: 优先使用 activityList 中的手术项目名称
if (adviceDefinitionName != null && !adviceDefinitionName.isEmpty()) {
contentMap.put("surgeryName", adviceDefinitionName);
} else if (surgeryName != null && !surgeryName.isEmpty()) {
contentMap.put("surgeryName", surgeryName);
}
if (surgeryCode != null && !surgeryCode.isEmpty()) {
contentMap.put("surgeryCode", surgeryCode);
}
if (plannedTime != null && !plannedTime.isEmpty()) {
contentMap.put("plannedTime", plannedTime);
}
if (surgeryIndication != null && !surgeryIndication.isEmpty()) {
contentMap.put("surgeryIndication", surgeryIndication);
}
if (preoperativeDiagnosis != null && !preoperativeDiagnosis.isEmpty()) {
contentMap.put("preoperativeDiagnosis", preoperativeDiagnosis);
}
if (!contentMap.isEmpty()) {
try {
ObjectMapper objectMapper = new ObjectMapper();
surgeryServiceRequest.setContentJson(objectMapper.writeValueAsString(contentMap));
} catch (Exception e) {
log.error("序列化手术信息失败", e);
}
}
try {
iServiceRequestService.save(surgeryServiceRequest);
log.info("手术医嘱生成成功serviceRequestId={}, prescriptionNo={}", surgeryServiceRequest.getId(), prescriptionNo);
} catch (Exception e) {
log.error("保存手术医嘱失败", e);
throw new ServiceException("保存手术医嘱失败: " + e.getMessage());
}
// 生成手术收费项目
try {
ChargeItem surgeryChargeItem = new ChargeItem();
surgeryChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
surgeryChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
surgeryChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
surgeryChargeItem.setPatientId(patientId);
surgeryChargeItem.setContextEnum(6); // 6-手术
surgeryChargeItem.setEncounterId(encounterId);
surgeryChargeItem.setEntererId(practitionerId);
surgeryChargeItem.setEnteredDate(curDate);
surgeryChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
surgeryChargeItem.setServiceId(surgeryServiceRequest.getId());
surgeryChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
// 优先从 activityList 获取 productId
if (activityList != null && !activityList.isEmpty()) {
surgeryChargeItem.setProductId(activityList.get(0).getAdviceDefinitionId());
surgeryChargeItem.setAccountId(activityList.get(0).getAccountId());
}
surgeryChargeItem.setRequestingOrgId(orgId);
surgeryChargeItem.setQuantityValue(BigDecimal.valueOf(1));
surgeryChargeItem.setQuantityUnit("");
// 设置手术费用
if (surgeryFee != null && !surgeryFee.isEmpty()) {
try {
surgeryChargeItem.setUnitPrice(new BigDecimal(surgeryFee));
surgeryChargeItem.setTotalPrice(new BigDecimal(surgeryFee));
} catch (NumberFormatException e) {
log.warn("手术费用格式不正确:{}", surgeryFee);
}
}
iChargeItemService.save(surgeryChargeItem);
log.info("手术收费项目生成成功chargeItemId={}", surgeryChargeItem.getId());
} catch (Exception e) {
log.error("生成手术收费项目失败", e);
throw new ServiceException("生成手术收费项目失败: " + e.getMessage());
}
// 如果存在麻醉费用,生成麻醉收费项目
if (anesthesiaFee != null && !anesthesiaFee.isEmpty()) {
try {
BigDecimal anesthesiaFeeAmount = new BigDecimal(anesthesiaFee);
if (anesthesiaFeeAmount.compareTo(BigDecimal.ZERO) > 0) {
ChargeItem anesthesiaChargeItem = new ChargeItem();
anesthesiaChargeItem.setStatusEnum(ChargeItemStatus.DRAFT.getValue());
anesthesiaChargeItem.setBusNo(AssignSeqEnum.CHARGE_ITEM_NO.getPrefix().concat(surgeryServiceRequest.getBusNo()));
anesthesiaChargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
anesthesiaChargeItem.setPatientId(patientId);
anesthesiaChargeItem.setContextEnum(3); // 3-诊疗
anesthesiaChargeItem.setEncounterId(encounterId);
anesthesiaChargeItem.setEntererId(practitionerId);
anesthesiaChargeItem.setEnteredDate(curDate);
anesthesiaChargeItem.setServiceTable(CommonConstants.TableName.WOR_SERVICE_REQUEST);
anesthesiaChargeItem.setServiceId(surgeryServiceRequest.getId());
anesthesiaChargeItem.setProductTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION);
anesthesiaChargeItem.setRequestingOrgId(orgId);
anesthesiaChargeItem.setQuantityValue(BigDecimal.valueOf(1));
anesthesiaChargeItem.setQuantityUnit("");
anesthesiaChargeItem.setUnitPrice(anesthesiaFeeAmount);
anesthesiaChargeItem.setTotalPrice(anesthesiaFeeAmount);
iChargeItemService.save(anesthesiaChargeItem);
log.info("麻醉收费项目生成成功");
}
} catch (NumberFormatException e) {
log.warn("麻醉费用格式不正确:{}", anesthesiaFee);
}
}
} catch (Exception e) {
log.error("生成手术医嘱过程中发生异常", e);
throw e;
}
} else {
log.info("不是手术申请单跳过手术医嘱生成typeCode={}", typeCode);
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"申请单"}));

View File

@@ -72,6 +72,7 @@ public class RequestFormManageController {
*/
@PostMapping(value = "/save-surgery")
public R<?> saveSurgeryRequestForm(@RequestBody RequestFormSaveDto requestFormSaveDto) {
log.info("【Controller】保存手术申请单typeCode={}", ActivityDefCategory.PROCEDURE.getCode());
return iRequestFormManageAppService.saveRequestForm(requestFormSaveDto,
ActivityDefCategory.PROCEDURE.getCode());
}

View File

@@ -141,7 +141,10 @@ const submitApplicationForm = () => {
const submitOk = () => {
applicationFormDialogVisible.value = false;
applicationFormName.value = null;
emits('refResh');
// 🔧 BugFix#318: 延迟刷新,确保后端数据已提交
setTimeout(() => {
emits('refResh');
}, 500);
};
defineExpose({ state });
</script>

View File

@@ -215,6 +215,7 @@ const submit = () => {
applicationListAllFilter = applicationListAllFilter.map((item) => {
return {
adviceDefinitionId: item.adviceDefinitionId /** 诊疗定义id */,
adviceDefinitionName: item.adviceDefinitionName /** 诊疗定义名称(手术项目名称) */,
quantity: 1, // /** 请求数量 */
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
unitPrice: item.priceList[0].price /** 单价 */,