feat(surgery): 增加手术室确认信息和次要手术功能
- 添加手术室确认时间和确认人字段显示 - 实现次要手术的添加、编辑和删除功能 - 增加急诊标志和植入高值耗材开关选项 - 添加手术费用和麻醉费用计算功能 - 实现手术和麻醉项目的远程搜索功能 - 增加第一助手和第二助手选择功能 - 优化医生列表加载逻辑,支持多接口获取 - 添加按钮图标提升界面体验 - 修复encounterId为空时的接口调用问题
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.openhis.web.clinicalmanage.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@@ -8,6 +9,8 @@ import com.core.common.core.domain.entity.SysUser;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.system.service.ISysUserService;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.openhis.administration.domain.ChargeItem;
|
||||
import com.openhis.administration.domain.Encounter;
|
||||
import com.openhis.administration.domain.OperatingRoom;
|
||||
@@ -28,6 +31,8 @@ import com.openhis.common.enums.GenerateSource;
|
||||
import com.openhis.common.enums.RequestStatus;
|
||||
import com.openhis.common.enums.TherapyTimeType;
|
||||
import com.openhis.common.utils.HisQueryUtils;
|
||||
import com.openhis.common.utils.RedisKeys;
|
||||
import com.core.common.core.redis.RedisCache;
|
||||
import com.openhis.document.domain.RequestForm;
|
||||
import com.openhis.document.service.IRequestFormService;
|
||||
import com.openhis.web.clinicalmanage.appservice.ISurgeryAppService;
|
||||
@@ -42,9 +47,8 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.core.framework.datasource.DynamicDataSourceContextHolder.log;
|
||||
|
||||
@@ -90,8 +94,10 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
@Resource
|
||||
private com.openhis.administration.service.IPractitionerService practitionerService;
|
||||
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 分页查询手术列表
|
||||
*
|
||||
* @param surgeryDto 查询条件
|
||||
* @param pageNo 当前页
|
||||
@@ -115,16 +121,52 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
|
||||
/**
|
||||
* 根据ID查询手术详情
|
||||
*
|
||||
*
|
||||
* @param id 手术ID
|
||||
* @return 手术详情
|
||||
*/
|
||||
@Override
|
||||
public R<SurgeryDto> getSurgeryDetail(Long id) {
|
||||
SurgeryDto surgeryDto = surgeryAppMapper.getSurgeryDetail(id);
|
||||
String cacheKey = RedisKeys.getSurgeryKey(id);
|
||||
SurgeryDto surgeryDto = redisCache.getCacheObject(cacheKey);
|
||||
|
||||
// 先从Redis缓存中获取
|
||||
if (surgeryDto != null) {
|
||||
log.info("从Redis缓存中获取手术信息 - surgeryId: {}", id);
|
||||
return R.ok(surgeryDto);
|
||||
}
|
||||
|
||||
// 缓存中没有,从数据库查询
|
||||
surgeryDto = surgeryAppMapper.getSurgeryDetail(id);
|
||||
if (surgeryDto == null) {
|
||||
return R.fail("手术信息不存在");
|
||||
}
|
||||
|
||||
// 从申请单中获取次要手术信息
|
||||
if (surgeryDto.getSurgeryNo() != null) {
|
||||
LambdaQueryWrapper<RequestForm> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(RequestForm::getPrescriptionNo, surgeryDto.getSurgeryNo());
|
||||
RequestForm requestForm = requestFormService.getOne(queryWrapper);
|
||||
if (requestForm != null && requestForm.getDescJson() != null) {
|
||||
try {
|
||||
Map<String, Object> map = new ObjectMapper().readValue(requestForm.getDescJson(), Map.class);
|
||||
if (map.containsKey("secondarySurgeries")) {
|
||||
surgeryDto.setSecondarySurgeries((List<Map<String, Object>>) map.get("secondarySurgeries"));
|
||||
}
|
||||
// 增加手术指征的回显兜底(从JSON中加载)
|
||||
if (map.containsKey("surgeryIndication") && (surgeryDto.getSurgeryIndication() == null || surgeryDto.getSurgeryIndication().isEmpty())) {
|
||||
surgeryDto.setSurgeryIndication((String) map.get("surgeryIndication"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析手术申请单JSON失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将查询结果存入Redis缓存(缓存30分钟)
|
||||
redisCache.setCacheObject(cacheKey, surgeryDto, 30, java.util.concurrent.TimeUnit.MINUTES);
|
||||
log.info("从数据库查询手术信息并存入Redis缓存 - surgeryId: {}", id);
|
||||
|
||||
return R.ok(surgeryDto);
|
||||
}
|
||||
|
||||
@@ -287,6 +329,9 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
chargeItem.setTotalPrice(surgeryDto.getTotalFee() != null ? surgeryDto.getTotalFee() : new BigDecimal("0.0")); // 总价
|
||||
chargeItemService.save(chargeItem);
|
||||
|
||||
// 清除相关缓存
|
||||
clearSurgeryAppCache(surgery);
|
||||
|
||||
return R.ok(surgeryId, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[]{"手术信息"}));
|
||||
}
|
||||
|
||||
@@ -297,13 +342,24 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
* @return JSON字符串
|
||||
*/
|
||||
private String buildDescJson(SurgeryDto surgeryDto) {
|
||||
return String.format(
|
||||
"{\"surgeryName\":\"%s\",\"surgeryLevel\":\"%s\",\"surgeryIndication\":\"%s\",\"preoperativeDiagnosis\":\"%s\"}",
|
||||
surgeryDto.getSurgeryName() != null ? surgeryDto.getSurgeryName() : "",
|
||||
surgeryDto.getSurgeryLevel() != null ? surgeryDto.getSurgeryLevel() : "",
|
||||
surgeryDto.getSurgeryIndication() != null ? surgeryDto.getSurgeryIndication() : "",
|
||||
surgeryDto.getPreoperativeDiagnosis() != null ? surgeryDto.getPreoperativeDiagnosis() : ""
|
||||
);
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("surgeryName", surgeryDto.getSurgeryName() != null ? surgeryDto.getSurgeryName() : "");
|
||||
map.put("surgeryCode", surgeryDto.getSurgeryCode() != null ? surgeryDto.getSurgeryCode() : "");
|
||||
map.put("surgeryLevel", surgeryDto.getSurgeryLevel() != null ? surgeryDto.getSurgeryLevel() : "");
|
||||
map.put("surgeryIndication", surgeryDto.getSurgeryIndication() != null ? surgeryDto.getSurgeryIndication() : "");
|
||||
map.put("preoperativeDiagnosis", surgeryDto.getPreoperativeDiagnosis() != null ? surgeryDto.getPreoperativeDiagnosis() : "");
|
||||
|
||||
// 加入次要手术信息
|
||||
if (surgeryDto.getSecondarySurgeries() != null && !surgeryDto.getSecondarySurgeries().isEmpty()) {
|
||||
map.put("secondarySurgeries", surgeryDto.getSecondarySurgeries());
|
||||
}
|
||||
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(map);
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("构建手术申请单JSON失败", e);
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -340,6 +396,21 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
fillSurgeryNameFields(surgery);
|
||||
|
||||
surgeryService.updateSurgery(surgery);
|
||||
|
||||
// 同步更新申请单中的描述内容
|
||||
if (surgery.getSurgeryNo() != null) {
|
||||
LambdaQueryWrapper<RequestForm> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(RequestForm::getPrescriptionNo, surgery.getSurgeryNo());
|
||||
RequestForm requestForm = requestFormService.getOne(queryWrapper);
|
||||
if (requestForm != null) {
|
||||
requestForm.setDescJson(buildDescJson(surgeryDto));
|
||||
requestFormService.updateById(requestForm);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除相关缓存
|
||||
clearSurgeryAppCache(surgery);
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[]{"手术信息"}));
|
||||
}
|
||||
|
||||
@@ -363,12 +434,16 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
}
|
||||
|
||||
surgeryService.deleteSurgery(id);
|
||||
|
||||
// 清除相关缓存
|
||||
clearSurgeryAppCache(existSurgery);
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[]{"手术信息"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新手术状态
|
||||
*
|
||||
*
|
||||
* @param id 手术ID
|
||||
* @param statusEnum 状态
|
||||
* @return 结果
|
||||
@@ -382,6 +457,10 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
}
|
||||
|
||||
surgeryService.updateSurgeryStatus(id, statusEnum);
|
||||
|
||||
// 清除相关缓存
|
||||
clearSurgeryAppCache(existSurgery);
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"手术状态"}));
|
||||
}
|
||||
|
||||
@@ -504,4 +583,32 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
|
||||
surgery.getPatientName(), surgery.getMainSurgeonName(), surgery.getAnesthetistName(), surgery.getAssistant1Name(),
|
||||
surgery.getAssistant2Name(), surgery.getScrubNurseName(), surgery.getOperatingRoomName(), surgery.getOrgName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除手术相关的Redis缓存
|
||||
*
|
||||
* @param surgery 手术信息
|
||||
*/
|
||||
private void clearSurgeryAppCache(Surgery surgery) {
|
||||
// 清除单个手术缓存
|
||||
if (surgery.getId() != null) {
|
||||
String surgeryKey = RedisKeys.getSurgeryKey(surgery.getId());
|
||||
redisCache.deleteObject(surgeryKey);
|
||||
log.info("清除手术缓存 - surgeryId: {}", surgery.getId());
|
||||
}
|
||||
|
||||
// 清除患者手术列表缓存
|
||||
if (surgery.getPatientId() != null) {
|
||||
String patientKey = RedisKeys.getSurgeryListByPatientKey(surgery.getPatientId());
|
||||
redisCache.deleteObject(patientKey);
|
||||
log.info("清除患者手术列表缓存 - patientId: {}", surgery.getPatientId());
|
||||
}
|
||||
|
||||
// 清除就诊手术列表缓存
|
||||
if (surgery.getEncounterId() != null) {
|
||||
String encounterKey = RedisKeys.getSurgeryListByEncounterKey(surgery.getEncounterId());
|
||||
redisCache.deleteObject(encounterKey);
|
||||
log.info("清除就诊手术列表缓存 - encounterId: {}", surgery.getEncounterId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 手术管理DTO
|
||||
@@ -196,4 +198,19 @@ public class SurgeryDto {
|
||||
|
||||
/** 更新时间 */
|
||||
private Date updateTime;
|
||||
}
|
||||
|
||||
/** 急诊标志 */
|
||||
private Integer emergencyFlag;
|
||||
|
||||
/** 植入高值耗材标志 */
|
||||
private Integer implantFlag;
|
||||
|
||||
/** 手术室确认时间 */
|
||||
private Date operatingRoomConfirmTime;
|
||||
|
||||
/** 手术室确认人 */
|
||||
private String operatingRoomConfirmUser;
|
||||
|
||||
/** 次要手术列表 */
|
||||
private List<Map<String, Object>> secondarySurgeries;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="operatingRoomName" column="operating_room_name" />
|
||||
<result property="orgId" column="org_id" />
|
||||
<result property="orgName" column="org_name" />
|
||||
<result property="surgeryIndication" column="surgery_indication" />
|
||||
<result property="preoperativeDiagnosis" column="preoperative_diagnosis" />
|
||||
<result property="postoperativeDiagnosis" column="postoperative_diagnosis" />
|
||||
<result property="surgeryDescription" column="surgery_description" />
|
||||
@@ -50,6 +51,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="deleteFlag" column="delete_flag" />
|
||||
<result property="emergencyFlag" column="emergency_flag" />
|
||||
<result property="implantFlag" column="implant_flag" />
|
||||
<result property="operatingRoomConfirmTime" column="operating_room_confirm_time" />
|
||||
<result property="operatingRoomConfirmUser" column="operating_room_confirm_user" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSurgeryVo">
|
||||
@@ -59,9 +64,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
main_surgeon_id, main_surgeon_name, assistant_1_id, assistant_1_name, assistant_2_id, assistant_2_name,
|
||||
anesthetist_id, anesthetist_name, scrub_nurse_id, scrub_nurse_name, anesthesia_type_enum,
|
||||
body_site, incision_level, healing_level, operating_room_id, operating_room_name,
|
||||
org_id, org_name, preoperative_diagnosis, postoperative_diagnosis, surgery_description,
|
||||
org_id, org_name, surgery_indication, preoperative_diagnosis, postoperative_diagnosis, surgery_description,
|
||||
postoperative_advice, complications, surgery_fee, anesthesia_fee, total_fee, remark,
|
||||
create_by, create_time, update_by, update_time, delete_flag
|
||||
create_by, create_time, update_by, update_time, delete_flag,
|
||||
emergency_flag, implant_flag, operating_room_confirm_time, operating_room_confirm_user
|
||||
FROM cli_surgery
|
||||
</sql>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="applyDoctorName" column="apply_doctor_name" />
|
||||
<result property="applyDeptId" column="apply_dept_id" />
|
||||
<result property="applyDeptName" column="apply_dept_name" />
|
||||
<result property="surgeryIndication" column="surgery_indication" />
|
||||
<result property="surgeryName" column="surgery_name" />
|
||||
<result property="surgeryCode" column="surgery_code" />
|
||||
<result property="surgeryTypeEnum" column="surgery_type_enum" />
|
||||
@@ -62,6 +63,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="remark" column="remark" />
|
||||
<result property="createTime" column="create_time" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="emergencyFlag" column="emergency_flag" />
|
||||
<result property="implantFlag" column="implant_flag" />
|
||||
<result property="operatingRoomConfirmTime" column="operating_room_confirm_time" />
|
||||
<result property="operatingRoomConfirmUser" column="operating_room_confirm_user" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectSurgeryVo">
|
||||
@@ -153,6 +158,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
ro.name as operating_room_org_name,
|
||||
s.org_id,
|
||||
COALESCE(s.org_name, o.name) as org_name,
|
||||
s.surgery_indication,
|
||||
s.preoperative_diagnosis,
|
||||
s.postoperative_diagnosis,
|
||||
s.surgery_description,
|
||||
@@ -163,7 +169,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
s.total_fee,
|
||||
s.remark,
|
||||
s.create_time,
|
||||
s.update_time
|
||||
s.update_time,
|
||||
s.emergency_flag,
|
||||
s.implant_flag,
|
||||
s.operating_room_confirm_time,
|
||||
s.operating_room_confirm_user
|
||||
FROM cli_surgery s
|
||||
LEFT JOIN adm_patient p ON s.patient_id = p.id
|
||||
LEFT JOIN adm_encounter e ON s.encounter_id = e.id
|
||||
|
||||
Reference in New Issue
Block a user