Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2cedcefacb | ||
|
|
4feac503a0 | ||
|
|
d747b0b380 | ||
|
|
af0a0957d0 | ||
|
|
6964f4f0a0 | ||
|
|
b8d663d5fa | ||
|
|
e32ef40f48 | ||
|
|
04903dc0b9 | ||
|
|
cd9dddb948 | ||
|
|
14ebcea2e6 | ||
|
|
7694122409 | ||
|
|
dd0cdf0af3 | ||
|
|
c6a29aa7f4 | ||
|
|
19b3bf5f3a | ||
|
|
51a75a6787 | ||
|
|
79a91f0a77 | ||
|
|
f1e30bb3a7 | ||
|
|
49a2313d7a | ||
|
|
677106afc2 | ||
|
|
925f3dde41 | ||
|
|
ae805eb89c |
@@ -7,6 +7,7 @@ import com.core.common.utils.MessageUtils;
|
|||||||
import com.openhis.administration.domain.Location;
|
import com.openhis.administration.domain.Location;
|
||||||
import com.openhis.administration.domain.Organization;
|
import com.openhis.administration.domain.Organization;
|
||||||
import com.openhis.administration.domain.OrganizationLocation;
|
import com.openhis.administration.domain.OrganizationLocation;
|
||||||
|
import com.openhis.workflow.domain.ActivityDefinition;
|
||||||
import com.openhis.administration.mapper.OrganizationLocationMapper;
|
import com.openhis.administration.mapper.OrganizationLocationMapper;
|
||||||
import com.openhis.administration.service.ILocationService;
|
import com.openhis.administration.service.ILocationService;
|
||||||
import com.openhis.administration.service.IOrganizationLocationService;
|
import com.openhis.administration.service.IOrganizationLocationService;
|
||||||
@@ -70,6 +71,7 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
// 获取科室下拉选列表
|
// 获取科室下拉选列表
|
||||||
List<Organization> organizationList = organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null);
|
List<Organization> organizationList = organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null);
|
||||||
List<OrgLocInitDto.departmentOption> organizationOptions = organizationList.stream()
|
List<OrgLocInitDto.departmentOption> organizationOptions = organizationList.stream()
|
||||||
|
.filter(organization -> organization != null && organization.getName() != null)
|
||||||
.map(organization -> new OrgLocInitDto.departmentOption(organization.getId(), organization.getName()))
|
.map(organization -> new OrgLocInitDto.departmentOption(organization.getId(), organization.getName()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
initDto.setLocationFormOptions(chargeItemStatusOptions).setDepartmentOptions(organizationOptions);
|
initDto.setLocationFormOptions(chargeItemStatusOptions).setDepartmentOptions(organizationOptions);
|
||||||
@@ -131,12 +133,18 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
@Override
|
@Override
|
||||||
public R<?> addOrEditOrgLoc(OrgLocQueryDto orgLocQueryDto) {
|
public R<?> addOrEditOrgLoc(OrgLocQueryDto orgLocQueryDto) {
|
||||||
|
|
||||||
|
// Validate required fields before processing
|
||||||
|
if (orgLocQueryDto.getOrganizationId() == null) {
|
||||||
|
return R.fail("请选择执行科室");
|
||||||
|
}
|
||||||
|
|
||||||
OrganizationLocation orgLoc = new OrganizationLocation();
|
OrganizationLocation orgLoc = new OrganizationLocation();
|
||||||
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
||||||
|
|
||||||
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
||||||
String activityName = activityDefinitionId != null
|
ActivityDefinition activityDef = activityDefinitionId != null
|
||||||
? activityDefinitionMapper.selectById(activityDefinitionId).getName() : "";
|
? activityDefinitionMapper.selectById(activityDefinitionId) : null;
|
||||||
|
String activityName = activityDef != null ? activityDef.getName() : "";
|
||||||
|
|
||||||
List<OrganizationLocation> organizationLocationList =
|
List<OrganizationLocation> organizationLocationList =
|
||||||
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||||
|
|||||||
@@ -274,27 +274,8 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
return R.fail("非就诊中患者不能完诊");
|
return R.fail("非就诊中患者不能完诊");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 获取 pool_id 和 slot_id:从 encounter → order_main → adm_schedule_slot 链路获取
|
// 2. 查找队列项(限定当天,避免复诊患者匹配到历史队列记录)
|
||||||
// 确保 div_log 中的值与排班主表一致,不依赖 triage_queue_item(队列项可能不存在或值错误)
|
|
||||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
||||||
Long divPoolId = null;
|
|
||||||
Long divSlotId = null;
|
|
||||||
if (encounter.getOrderId() != null) {
|
|
||||||
try {
|
|
||||||
Order order = iOrderService.getById(encounter.getOrderId());
|
|
||||||
if (order != null && order.getSlotId() != null) {
|
|
||||||
divSlotId = order.getSlotId();
|
|
||||||
ScheduleSlot slot = scheduleSlotMapper.selectById(divSlotId);
|
|
||||||
if (slot != null) {
|
|
||||||
divPoolId = slot.getPoolId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("获取完诊div_log的pool_id/slot_id失败,encounterId={}", encounterId, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 查找队列项(限定当天,避免复诊患者匹配到历史队列记录)
|
|
||||||
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
TriageQueueItem queueItem = triageQueueItemService.getOne(
|
||||||
new LambdaQueryWrapper<TriageQueueItem>()
|
new LambdaQueryWrapper<TriageQueueItem>()
|
||||||
.eq(TriageQueueItem::getTenantId, tenantId)
|
.eq(TriageQueueItem::getTenantId, tenantId)
|
||||||
@@ -319,14 +300,41 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 3. 获取 pool_id 和 slot_id:优先使用 triage_queue_item(挂号时录入的号源信息,为权威来源)
|
||||||
|
// 队列项不存在或值缺失时,回退使用 encounter → order_main → adm_schedule_slot 链路
|
||||||
|
Long divPoolId = null;
|
||||||
|
Long divSlotId = null;
|
||||||
|
if (queueItem != null && queueItem.getPoolId() != null && queueItem.getSlotId() != null) {
|
||||||
|
divPoolId = queueItem.getPoolId();
|
||||||
|
divSlotId = queueItem.getSlotId();
|
||||||
|
} else if (encounter.getOrderId() != null) {
|
||||||
|
try {
|
||||||
|
Order order = iOrderService.getById(encounter.getOrderId());
|
||||||
|
if (order != null && order.getSlotId() != null) {
|
||||||
|
divSlotId = order.getSlotId();
|
||||||
|
ScheduleSlot slot = scheduleSlotMapper.selectById(divSlotId);
|
||||||
|
if (slot != null) {
|
||||||
|
divPoolId = slot.getPoolId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("回退获取完诊div_log的pool_id/slot_id失败,encounterId={}", encounterId, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 如果队列项存在且未完成,更新队列状态为已完成
|
// 如果队列项存在且未完成,更新队列状态为已完成
|
||||||
// 使用排除法而非白名单:只要不是"已完成"就可以完诊,覆盖跳过、等待等非标准流转状态
|
// 使用排除法而非白名单:只要不是"已完成"就可以完诊,覆盖跳过、等待等非标准流转状态
|
||||||
if (queueItem != null &&
|
if (queueItem != null &&
|
||||||
!TriageQueueStatus.COMPLETED.getValue().equals(queueItem.getStatus())) {
|
!TriageQueueStatus.COMPLETED.getValue().equals(queueItem.getStatus())) {
|
||||||
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
java.time.LocalDateTime nowLocal = java.time.LocalDateTime.now().truncatedTo(ChronoUnit.SECONDS);
|
||||||
queueItem.setStatus(TriageQueueStatus.COMPLETED.getValue());
|
// 使用 LambdaUpdateWrapper 直接更新,确保 status 字段必定写入数据库
|
||||||
queueItem.setUpdateTime(nowLocal);
|
boolean queueUpdate = triageQueueItemService.update(new LambdaUpdateWrapper<TriageQueueItem>()
|
||||||
triageQueueItemService.updateById(queueItem);
|
.eq(TriageQueueItem::getId, queueItem.getId())
|
||||||
|
.set(TriageQueueItem::getStatus, TriageQueueStatus.COMPLETED.getValue())
|
||||||
|
.set(TriageQueueItem::getUpdateTime, nowLocal));
|
||||||
|
if (!queueUpdate) {
|
||||||
|
log.error("完诊:triage_queue_item 状态更新失败,queueItemId={}", queueItem.getId());
|
||||||
|
}
|
||||||
} else if (queueItem == null) {
|
} else if (queueItem == null) {
|
||||||
log.error("完诊:未找到任何 triage_queue_item 记录,encounterId={}, tenantId={}",
|
log.error("完诊:未找到任何 triage_queue_item 记录,encounterId={}, tenantId={}",
|
||||||
encounterId, tenantId);
|
encounterId, tenantId);
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ public interface IRequestFormManageAppService {
|
|||||||
*/
|
*/
|
||||||
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate);
|
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询申请单(支持筛选+状态+关键字)
|
||||||
|
*
|
||||||
|
* @param encounterId 就诊id
|
||||||
|
* @param typeCode 申请单类型
|
||||||
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
|
* @param status 单据状态(可选)
|
||||||
|
* @param keyword 关键字(可选,申请单号/项目名称模糊匹配)
|
||||||
|
* @return 申请单列表
|
||||||
|
*/
|
||||||
|
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status, String keyword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询申请单
|
* 分页查询申请单
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -341,6 +341,28 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
|||||||
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 防重复保存:对新增医嘱进行去重,避免签发单条长期医嘱时产生重复记录
|
||||||
|
Set<String> longUniqueKeySet = new HashSet<>();
|
||||||
|
List<RegAdviceSaveDto> longUniqueList = new ArrayList<>();
|
||||||
|
for (RegAdviceSaveDto adviceSaveDto : longInsertOrUpdateList) {
|
||||||
|
String uniqueKey = adviceSaveDto.getPatientId() + "_"
|
||||||
|
+ adviceSaveDto.getEncounterId() + "_"
|
||||||
|
+ adviceSaveDto.getAdviceDefinitionId() + "_"
|
||||||
|
+ adviceSaveDto.getDose() + "_"
|
||||||
|
+ adviceSaveDto.getMethodCode() + "_"
|
||||||
|
+ adviceSaveDto.getRateCode();
|
||||||
|
if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && longUniqueKeySet.contains(uniqueKey)) {
|
||||||
|
log.warn("防重复保存:检测到重复长期医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}",
|
||||||
|
adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(),
|
||||||
|
adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
longUniqueKeySet.add(uniqueKey);
|
||||||
|
longUniqueList.add(adviceSaveDto);
|
||||||
|
}
|
||||||
|
log.info("防重复保存(长期):去重前{}条,去重后{}条", longInsertOrUpdateList.size(), longUniqueList.size());
|
||||||
|
longInsertOrUpdateList = longUniqueList;
|
||||||
|
|
||||||
for (RegAdviceSaveDto regAdviceSaveDto : longInsertOrUpdateList) {
|
for (RegAdviceSaveDto regAdviceSaveDto : longInsertOrUpdateList) {
|
||||||
boolean firstTimeSave = false;// 第一次保存
|
boolean firstTimeSave = false;// 第一次保存
|
||||||
longMedicationRequest = new MedicationRequest();
|
longMedicationRequest = new MedicationRequest();
|
||||||
@@ -406,6 +428,29 @@ public class AdviceManageAppServiceImpl implements IAdviceManageAppService {
|
|||||||
.getValue().equals(e.getTherapyEnum())
|
.getValue().equals(e.getTherapyEnum())
|
||||||
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
&& (DbOpType.INSERT.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 防重复保存:对新增医嘱进行去重
|
||||||
|
Set<String> tempUniqueKeySet = new HashSet<>();
|
||||||
|
List<RegAdviceSaveDto> tempUniqueList = new ArrayList<>();
|
||||||
|
for (RegAdviceSaveDto adviceSaveDto : tempInsertOrUpdateList) {
|
||||||
|
String uniqueKey = adviceSaveDto.getPatientId() + "_"
|
||||||
|
+ adviceSaveDto.getEncounterId() + "_"
|
||||||
|
+ adviceSaveDto.getAdviceDefinitionId() + "_"
|
||||||
|
+ adviceSaveDto.getDose() + "_"
|
||||||
|
+ adviceSaveDto.getMethodCode() + "_"
|
||||||
|
+ adviceSaveDto.getRateCode();
|
||||||
|
if (DbOpType.INSERT.getCode().equals(adviceSaveDto.getDbOpType()) && tempUniqueKeySet.contains(uniqueKey)) {
|
||||||
|
log.warn("防重复保存:检测到重复临时医嘱,跳过保存 - patientId={}, encounterId={}, adviceDefinitionId={}, dose={}",
|
||||||
|
adviceSaveDto.getPatientId(), adviceSaveDto.getEncounterId(),
|
||||||
|
adviceSaveDto.getAdviceDefinitionId(), adviceSaveDto.getDose());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempUniqueKeySet.add(uniqueKey);
|
||||||
|
tempUniqueList.add(adviceSaveDto);
|
||||||
|
}
|
||||||
|
log.info("防重复保存(临时):去重前{}条,去重后{}条", tempInsertOrUpdateList.size(), tempUniqueList.size());
|
||||||
|
tempInsertOrUpdateList = tempUniqueList;
|
||||||
|
|
||||||
for (RegAdviceSaveDto regAdviceSaveDto : tempInsertOrUpdateList) {
|
for (RegAdviceSaveDto regAdviceSaveDto : tempInsertOrUpdateList) {
|
||||||
boolean firstTimeSave = false;// 第一次保存
|
boolean firstTimeSave = false;// 第一次保存
|
||||||
tempMedicationRequest = new MedicationRequest();
|
tempMedicationRequest = new MedicationRequest();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -91,8 +92,10 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
return R.fail("无待签发的医嘱,该申请单不可编辑");
|
return R.fail("无待签发的医嘱,该申请单不可编辑");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 诊疗处方号
|
// 检查申请单号:JC(检查)+ Z(住院标识)+ yyMMdd(日期)+ 5位顺序号
|
||||||
prescriptionNo = assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_PSYCHOTROPIC_NO.getPrefix(), 8);
|
String dateStr = new java.text.SimpleDateFormat("yyMMdd").format(new Date());
|
||||||
|
int seq = assignSeqUtil.getSeqNoByDay(AssignSeqEnum.CHECK_APPLY_NO.getPrefix());
|
||||||
|
prescriptionNo = "JCZ" + dateStr + String.format("%05d", seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 当前时间
|
// 当前时间
|
||||||
@@ -428,12 +431,28 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate) {
|
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate) {
|
||||||
|
return getRequestForm(encounterId, typeCode, startDate, endDate, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询申请单(支持筛选+状态+关键字)
|
||||||
|
*
|
||||||
|
* @param encounterId 就诊id
|
||||||
|
* @param typeCode 申请单类型
|
||||||
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
|
* @param status 单据状态(可选)
|
||||||
|
* @param keyword 关键字(可选,申请单号/项目名称模糊匹配)
|
||||||
|
* @return 申请单列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status, String keyword) {
|
||||||
// 检查参数
|
// 检查参数
|
||||||
if (encounterId == null) {
|
if (encounterId == null) {
|
||||||
return new java.util.ArrayList<>();
|
return new java.util.ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate,null,null);
|
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate, status, keyword);
|
||||||
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
||||||
// 查询处方详情
|
// 查询处方详情
|
||||||
List<RequestFormDetailQueryDto> requestFormDetail =
|
List<RequestFormDetailQueryDto> requestFormDetail =
|
||||||
|
|||||||
@@ -98,6 +98,7 @@ public class RequestFormManageController {
|
|||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param status 单据状态(可选)
|
* @param status 单据状态(可选)
|
||||||
|
* @param keyword 关键字(可选,申请单号/检验项目模糊匹配)
|
||||||
* @return 检验申请单
|
* @return 检验申请单
|
||||||
*/
|
*/
|
||||||
@GetMapping(value = "/get-inspection")
|
@GetMapping(value = "/get-inspection")
|
||||||
@@ -105,11 +106,12 @@ public class RequestFormManageController {
|
|||||||
@RequestParam(required = false) Long encounterId,
|
@RequestParam(required = false) Long encounterId,
|
||||||
@RequestParam(required = false) String startDate,
|
@RequestParam(required = false) String startDate,
|
||||||
@RequestParam(required = false) String endDate,
|
@RequestParam(required = false) String endDate,
|
||||||
@RequestParam(required = false) String status) {
|
@RequestParam(required = false) String status,
|
||||||
|
@RequestParam(required = false) String keyword) {
|
||||||
if (encounterId == null) {
|
if (encounterId == null) {
|
||||||
return R.fail("就诊ID不能为空");
|
return R.fail("就诊ID不能为空");
|
||||||
}
|
}
|
||||||
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROOF.getCode(), startDate, endDate));
|
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROOF.getCode(), startDate, endDate, status, keyword));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -100,6 +100,7 @@
|
|||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
|
WHEN T1.context_enum = #{activity} AND T1.service_table = 'wor_service_request' THEN COALESCE(T9.surgery_name, wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{medication} THEN T3."name"
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
WHEN T1.context_enum = #{device} THEN T4."name"
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
@@ -225,6 +226,7 @@
|
|||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
|
WHEN T1.context_enum = #{activity} AND T1.service_table = 'wor_service_request' THEN COALESCE(T9.surgery_name, wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{medication} THEN T3."name"
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
WHEN T1.context_enum = #{device} THEN T4."name"
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
|
|||||||
@@ -541,9 +541,9 @@
|
|||||||
CI.service_id AS request_id,
|
CI.service_id AS request_id,
|
||||||
CI.service_id || '-ci-dev' AS unique_key,
|
CI.service_id || '-ci-dev' AS unique_key,
|
||||||
'' AS prescription_no,
|
'' AS prescription_no,
|
||||||
CI.enterer_id AS requester_id,
|
COALESCE(DR.requester_id, CI.enterer_id) AS requester_id,
|
||||||
CI.entered_date AS request_time,
|
CI.entered_date AS request_time,
|
||||||
CASE WHEN CI.enterer_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
CASE WHEN COALESCE(DR.requester_id, CI.enterer_id) = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
DR.content_json AS content_json,
|
DR.content_json AS content_json,
|
||||||
NULL AS skin_test_flag,
|
NULL AS skin_test_flag,
|
||||||
NULL AS inject_flag,
|
NULL AS inject_flag,
|
||||||
|
|||||||
@@ -231,7 +231,7 @@
|
|||||||
ae.priority_enum,
|
ae.priority_enum,
|
||||||
ae.organization_id,
|
ae.organization_id,
|
||||||
ae.start_time AS in_hos_time,
|
ae.start_time AS in_hos_time,
|
||||||
bed.start_time,
|
COALESCE(bed.start_time, ae.start_time) AS start_time,
|
||||||
bed.location_id AS bed_id,
|
bed.location_id AS bed_id,
|
||||||
bed.location_name AS bed_name,
|
bed.location_name AS bed_name,
|
||||||
house.location_id AS house_id,
|
house.location_id AS house_id,
|
||||||
|
|||||||
@@ -12,12 +12,24 @@
|
|||||||
drf.desc_json,
|
drf.desc_json,
|
||||||
drf.requester_id,
|
drf.requester_id,
|
||||||
drf.create_time,
|
drf.create_time,
|
||||||
ap.NAME AS patient_name
|
ap.NAME AS patient_name,
|
||||||
|
CASE MIN(wsr.status_enum)
|
||||||
|
WHEN 1 THEN 0
|
||||||
|
WHEN 2 THEN 1
|
||||||
|
WHEN 3 THEN 4
|
||||||
|
WHEN 4 THEN 4
|
||||||
|
WHEN 5 THEN 5
|
||||||
|
WHEN 6 THEN 5
|
||||||
|
WHEN 7 THEN 5
|
||||||
|
ELSE NULL
|
||||||
|
END AS status
|
||||||
FROM doc_request_form AS drf
|
FROM doc_request_form AS drf
|
||||||
LEFT JOIN adm_encounter AS ae ON ae.ID = drf.encounter_id
|
LEFT JOIN adm_encounter AS ae ON ae.ID = drf.encounter_id
|
||||||
AND ae.delete_flag = '0'
|
AND ae.delete_flag = '0'
|
||||||
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
||||||
AND ap.delete_flag = '0'
|
AND ap.delete_flag = '0'
|
||||||
|
LEFT JOIN wor_service_request AS wsr ON wsr.prescription_no = drf.prescription_no
|
||||||
|
AND wsr.delete_flag = '0'
|
||||||
WHERE drf.delete_flag = '0'
|
WHERE drf.delete_flag = '0'
|
||||||
AND drf.encounter_id = #{encounterId}
|
AND drf.encounter_id = #{encounterId}
|
||||||
AND drf.type_code = #{typeCode}
|
AND drf.type_code = #{typeCode}
|
||||||
@@ -27,6 +39,33 @@
|
|||||||
<if test="endDate != null and endDate != ''">
|
<if test="endDate != null and endDate != ''">
|
||||||
AND drf.create_time <= (#{endDate}::date + INTERVAL '1 day' - INTERVAL '1 second')
|
AND drf.create_time <= (#{endDate}::date + INTERVAL '1 day' - INTERVAL '1 second')
|
||||||
</if>
|
</if>
|
||||||
|
<if test="status != null and status != ''">
|
||||||
|
AND CASE MIN(wsr.status_enum)
|
||||||
|
WHEN 1 THEN 0
|
||||||
|
WHEN 2 THEN 1
|
||||||
|
WHEN 3 THEN 4
|
||||||
|
WHEN 4 THEN 4
|
||||||
|
WHEN 5 THEN 5
|
||||||
|
WHEN 6 THEN 5
|
||||||
|
WHEN 7 THEN 5
|
||||||
|
ELSE NULL
|
||||||
|
END = #{status}::integer
|
||||||
|
</if>
|
||||||
|
<if test="keyword != null and keyword != ''">
|
||||||
|
AND (drf.prescription_no ILIKE '%' || #{keyword} || '%'
|
||||||
|
OR EXISTS (
|
||||||
|
SELECT 1 FROM wor_service_request wsr2
|
||||||
|
WHERE wsr2.prescription_no = drf.prescription_no
|
||||||
|
AND wsr2.delete_flag = '0'
|
||||||
|
AND wsr2.activity_id IN (
|
||||||
|
SELECT id FROM wor_activity_definition wad
|
||||||
|
WHERE wad.delete_flag = '0'
|
||||||
|
AND wad.name ILIKE '%' || #{keyword} || '%'
|
||||||
|
)
|
||||||
|
))
|
||||||
|
</if>
|
||||||
|
GROUP BY drf.id, drf.encounter_id, drf.prescription_no, drf.name, drf.desc_json,
|
||||||
|
drf.requester_id, drf.create_time, ap.name
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getRequestFormDetail" resultType="com.openhis.web.regdoctorstation.dto.RequestFormDetailQueryDto">
|
<select id="getRequestFormDetail" resultType="com.openhis.web.regdoctorstation.dto.RequestFormDetailQueryDto">
|
||||||
|
|||||||
@@ -270,6 +270,10 @@ public enum AssignSeqEnum {
|
|||||||
* 诊疗处方号
|
* 诊疗处方号
|
||||||
*/
|
*/
|
||||||
ACTIVITY_PSYCHOTROPIC_NO("62", "诊疗处方号", "PAR"),
|
ACTIVITY_PSYCHOTROPIC_NO("62", "诊疗处方号", "PAR"),
|
||||||
|
/**
|
||||||
|
* 检查申请单号(住院)
|
||||||
|
*/
|
||||||
|
CHECK_APPLY_NO("72", "检查申请单号", "JCZ"),
|
||||||
/**
|
/**
|
||||||
* b 病历文书
|
* b 病历文书
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -475,8 +475,13 @@ function calculateTotalPrice() {
|
|||||||
});
|
});
|
||||||
totalPrice.value = sum.toFixed(2);
|
totalPrice.value = sum.toFixed(2);
|
||||||
// Bug #464: 零售价与诊疗子项合计总价实时同步
|
// Bug #464: 零售价与诊疗子项合计总价实时同步
|
||||||
if (treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId !== '') {
|
const hasValidItem = treatmentItems.value.some(
|
||||||
|
(item) => item.adviceDefinitionId && item.adviceDefinitionId !== ''
|
||||||
|
);
|
||||||
|
if (hasValidItem) {
|
||||||
form.value.retailPrice = parseFloat(totalPrice.value);
|
form.value.retailPrice = parseFloat(totalPrice.value);
|
||||||
|
} else {
|
||||||
|
form.value.retailPrice = undefined;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
totalPrice.value = '0.00';
|
totalPrice.value = '0.00';
|
||||||
@@ -486,7 +491,7 @@ function calculateTotalPrice() {
|
|||||||
|
|
||||||
// 添加表单项
|
// 添加表单项
|
||||||
function addItem() {
|
function addItem() {
|
||||||
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1, retailPrice: 0 });
|
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1, name: '', retailPrice: 0 });
|
||||||
// 使用nextTick确保DOM更新后再计算
|
// 使用nextTick确保DOM更新后再计算
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
calculateTotalPrice();
|
calculateTotalPrice();
|
||||||
@@ -647,12 +652,15 @@ async function submitForm() {
|
|||||||
form.value.ybMatchFlag ? (form.value.ybMatchFlag = 1) : (form.value.ybMatchFlag = 0);
|
form.value.ybMatchFlag ? (form.value.ybMatchFlag = 1) : (form.value.ybMatchFlag = 0);
|
||||||
form.value.ruleId ? (form.value.ruleId = 1) : (form.value.ruleId = 0);
|
form.value.ruleId ? (form.value.ruleId = 1) : (form.value.ruleId = 0);
|
||||||
form.value.childrenJson =
|
form.value.childrenJson =
|
||||||
treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId != ''
|
treatmentItems.value.some((item) => item.adviceDefinitionId != '' && item.adviceDefinitionId)
|
||||||
? JSON.stringify(treatmentItems.value)
|
? JSON.stringify(treatmentItems.value)
|
||||||
: undefined;
|
: undefined;
|
||||||
// Bug #464 修复:零售价自动与诊疗子项合计总价同步
|
// Bug #464 修复:零售价自动与诊疗子项合计总价同步
|
||||||
// 当有子项时,零售价自动设置为子项合计总价
|
// 当有子项时,零售价自动设置为子项合计总价
|
||||||
if (treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId != '') {
|
const hasValidItem = treatmentItems.value.some(
|
||||||
|
(item) => item.adviceDefinitionId && item.adviceDefinitionId !== ''
|
||||||
|
);
|
||||||
|
if (hasValidItem) {
|
||||||
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
||||||
}
|
}
|
||||||
proxy.$refs['diagnosisTreatmentRef'].validate(async (valid) => {
|
proxy.$refs['diagnosisTreatmentRef'].validate(async (valid) => {
|
||||||
|
|||||||
@@ -69,13 +69,14 @@ const throttledGetList = throttle(
|
|||||||
watch(
|
watch(
|
||||||
() => props.adviceQueryParams,
|
() => props.adviceQueryParams,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
// 只有在弹窗打开时才响应 adviceQueryParams 的变化,避免选择项目后弹窗关闭时触发不必要的请求
|
// 始终同步参数到 queryParams,避免弹窗打开时使用旧参数
|
||||||
if (!props.popoverVisible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
queryParams.value.searchKey = newValue?.searchKey;
|
queryParams.value.searchKey = newValue?.searchKey;
|
||||||
queryParams.value.adviceType = newValue?.adviceType;
|
queryParams.value.adviceType = newValue?.adviceType;
|
||||||
queryParams.value.categoryCode = newValue?.categoryCode;
|
queryParams.value.categoryCode = newValue?.categoryCode;
|
||||||
|
// 只有在弹窗打开时才触发 API 请求
|
||||||
|
if (!props.popoverVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
throttledGetList();
|
throttledGetList();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
|
|||||||
@@ -1318,7 +1318,11 @@ async function show(diagnosisData) {
|
|||||||
// 系统关联信息
|
// 系统关联信息
|
||||||
encounterId: patientInfo.encounterId || '', // 就诊ID
|
encounterId: patientInfo.encounterId || '', // 就诊ID
|
||||||
patientId: patientInfo.patientId || '', // 患者ID
|
patientId: patientInfo.patientId || '', // 患者ID
|
||||||
diagnosisId: diagnosisData?.conditionId || diagnosisData?.definitionId || '', // 诊断ID
|
diagnosisId: (diagnosisData?.conditionId != null && diagnosisData?.conditionId !== '')
|
||||||
|
? diagnosisData.conditionId
|
||||||
|
: (diagnosisData?.definitionId != null && diagnosisData?.definitionId !== '')
|
||||||
|
? diagnosisData.definitionId
|
||||||
|
: '', // 诊断ID
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新selectedDiseases数组
|
// 更新selectedDiseases数组
|
||||||
@@ -1373,7 +1377,7 @@ async function buildSubmitData() {
|
|||||||
const submitData = {
|
const submitData = {
|
||||||
cardNo: formData.cardNo,
|
cardNo: formData.cardNo,
|
||||||
visitId: props.patientInfo?.encounterId || formData.encounterId || null,
|
visitId: props.patientInfo?.encounterId || formData.encounterId || null,
|
||||||
diagId: formData.diagnosisId || null,
|
diagId: formData.diagnosisId ? Number(formData.diagnosisId) : null,
|
||||||
patId: formData.patientId || null,
|
patId: formData.patientId || null,
|
||||||
idType: 1, // 默认身份证
|
idType: 1, // 默认身份证
|
||||||
idNo: formData.idNo,
|
idNo: formData.idNo,
|
||||||
@@ -1539,6 +1543,12 @@ async function handleSubmit() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查诊断ID是否有效(后端 @NotNull 校验要求)
|
||||||
|
if (!form.value.diagnosisId) {
|
||||||
|
proxy.$modal.msgError('诊断信息不完整,请重新选择诊断后重试');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 开始加载状态,防止重复提交
|
// 开始加载状态,防止重复提交
|
||||||
submitLoading.value = true;
|
submitLoading.value = true;
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,7 @@
|
|||||||
<span class="cat-title">{{ cat.categoryName }}</span>
|
<span class="cat-title">{{ cat.categoryName }}</span>
|
||||||
<span v-if="categoryLoadingSet.has(cat.typeId)" class="loading-dot"></span>
|
<span v-if="categoryLoadingSet.has(cat.typeId)" class="loading-dot"></span>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- 检查项目(部位/项目列表) -->
|
||||||
<div
|
<div
|
||||||
v-for="item in cat.items"
|
v-for="item in cat.items"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -333,6 +334,27 @@
|
|||||||
<div v-if="categoryLoadingSet.has(cat.typeId)" class="category-loading-hint">
|
<div v-if="categoryLoadingSet.has(cat.typeId)" class="category-loading-hint">
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
|
<!-- Bug #428修复: 渲染分类联动加载的检查方法列表 -->
|
||||||
|
<div
|
||||||
|
v-if="cat.methods && cat.methods.length > 0"
|
||||||
|
class="method-section"
|
||||||
|
>
|
||||||
|
<div class="method-section-title">检查方法</div>
|
||||||
|
<div
|
||||||
|
v-for="method in cat.methods"
|
||||||
|
:key="method.id"
|
||||||
|
class="method-row"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
:model-value="isMethodSelected(method, cat)"
|
||||||
|
@change="(val) => handleMethodSelect(val, method, cat)"
|
||||||
|
class="method-checkbox"
|
||||||
|
>
|
||||||
|
{{ method.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
<span class="method-price-tag">¥{{ method.packagePrice || method.price || 0 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</div>
|
</div>
|
||||||
@@ -660,6 +682,7 @@ async function handleCategoryExpand(cat) {
|
|||||||
code: m.code,
|
code: m.code,
|
||||||
price: m.price || 0,
|
price: m.price || 0,
|
||||||
packageName: m.packageName || '',
|
packageName: m.packageName || '',
|
||||||
|
packageId: m.packageId || null,
|
||||||
packagePrice: m.packagePrice || null,
|
packagePrice: m.packagePrice || null,
|
||||||
serviceFee: m.serviceFee || null
|
serviceFee: m.serviceFee || null
|
||||||
}));
|
}));
|
||||||
@@ -1003,12 +1026,18 @@ function handleRowClick(row) {
|
|||||||
code: md.code,
|
code: md.code,
|
||||||
price: m.itemFee || 0, // fallback 到已保存的价格
|
price: m.itemFee || 0, // fallback 到已保存的价格
|
||||||
packageName: md.packageName || '',
|
packageName: md.packageName || '',
|
||||||
|
packageId: md.packageId || null,
|
||||||
packagePrice: md.packagePrice || null, // Bug #384修复: 套餐价格
|
packagePrice: md.packagePrice || null, // Bug #384修复: 套餐价格
|
||||||
serviceFee: md.serviceFee || null
|
serviceFee: md.serviceFee || null
|
||||||
}));
|
}));
|
||||||
// 如果有已保存的检查方法信息,尝试匹配
|
// 如果有已保存的检查方法信息,尝试匹配
|
||||||
if (m.checkMethodId) {
|
if (m.checkMethodId) {
|
||||||
item.selectedMethod = item.methods.find(md => md.id === m.checkMethodId) || null;
|
item.selectedMethod = item.methods.find(md => md.id === m.checkMethodId) || null;
|
||||||
|
// 从已保存的方法中获取套餐信息
|
||||||
|
if (item.selectedMethod?.packageId) {
|
||||||
|
item.isPackage = true;
|
||||||
|
item.packageId = item.selectedMethod.packageId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -1047,6 +1076,92 @@ function handleDelete(row) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bug #428修复: 判断某个检查方法是否已被选中(任意项目关联了该方法)
|
||||||
|
function isMethodSelected(method, cat) {
|
||||||
|
return selectedItems.value.some(item =>
|
||||||
|
item.selectedMethod?.id === method.id && item.checkType === cat.typeName
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug #428修复: 勾选检查方法
|
||||||
|
async function handleMethodSelect(checked, method, cat) {
|
||||||
|
if (checked) {
|
||||||
|
// 找到该方法所属的第一个检查项目
|
||||||
|
const targetItem = cat.items[0];
|
||||||
|
if (!targetItem) {
|
||||||
|
// 如果分类下没有项目,尝试从其他分类找同名项目或创建
|
||||||
|
console.warn('分类下没有检查项目,无法关联方法');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果该项目已存在,只更新 selectedMethod
|
||||||
|
const existingItem = selectedItems.value.find(s => s.id === targetItem.id);
|
||||||
|
if (existingItem) {
|
||||||
|
existingItem.selectedMethod = method;
|
||||||
|
// 从方法中获取套餐信息
|
||||||
|
if (method.packageId) {
|
||||||
|
existingItem.isPackage = true;
|
||||||
|
existingItem.packageId = method.packageId;
|
||||||
|
// 预加载套餐明细
|
||||||
|
loadPackageDetailsForItem(existingItem);
|
||||||
|
}
|
||||||
|
updateMethodDisplay();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果该项目不存在,创建一个并关联方法
|
||||||
|
if (selectedItems.value.length > 0) {
|
||||||
|
const currentCategory = selectedItems.value[0].checkType;
|
||||||
|
const newCategory = cat.typeCode || '';
|
||||||
|
if (currentCategory !== newCategory) {
|
||||||
|
ElMessage.warning('一个检查单不能同时选择多个项目类型的检查项目');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const newItem = {
|
||||||
|
id: targetItem.id, name: targetItem.name,
|
||||||
|
price: targetItem.price, quantity: 1,
|
||||||
|
serviceFee: targetItem.serviceFee || 0,
|
||||||
|
unit: targetItem.unit || '次',
|
||||||
|
applyPart: targetItem.name,
|
||||||
|
checkType: cat.typeName,
|
||||||
|
nationalCode: targetItem.nationalCode || '',
|
||||||
|
checked: true,
|
||||||
|
methods: [method],
|
||||||
|
selectedMethod: method,
|
||||||
|
expanded: false,
|
||||||
|
// 从方法中获取套餐信息(优先级高于项目本身的 packageName)
|
||||||
|
isPackage: !!method.packageId || !!targetItem.packageName,
|
||||||
|
packageId: method.packageId || targetItem.packageId || null
|
||||||
|
};
|
||||||
|
selectedItems.value.push(newItem);
|
||||||
|
|
||||||
|
// 如果是套餐,预加载套餐明细
|
||||||
|
if (newItem.isPackage && newItem.packageId) {
|
||||||
|
loadPackageDetailsForItem(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 自动回填执行科室
|
||||||
|
if (selectedItems.value.length === 1 && cat?.performDeptName) {
|
||||||
|
form.performDeptCode = cat.performDeptName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同时勾选左侧项目的 checkbox
|
||||||
|
targetItem.checked = true;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// 取消选择方法:将 selectedItems 中关联该方法的项的 selectedMethod 清空
|
||||||
|
const itemsWithMethod = selectedItems.value.filter(
|
||||||
|
item => item.selectedMethod?.id === method.id
|
||||||
|
);
|
||||||
|
for (const item of itemsWithMethod) {
|
||||||
|
item.selectedMethod = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateMethodDisplay();
|
||||||
|
}
|
||||||
|
|
||||||
// ====== 勾选逻辑 ======
|
// ====== 勾选逻辑 ======
|
||||||
async function handleItemSelect(checked, item, cat) {
|
async function handleItemSelect(checked, item, cat) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
@@ -1070,6 +1185,7 @@ async function handleItemSelect(checked, item, cat) {
|
|||||||
code: m.code,
|
code: m.code,
|
||||||
price: m.price || item.price, // fallback 到项目价格
|
price: m.price || item.price, // fallback 到项目价格
|
||||||
packageName: m.packageName || '',
|
packageName: m.packageName || '',
|
||||||
|
packageId: m.packageId || null,
|
||||||
packagePrice: m.packagePrice || null, // Bug #384修复: 套餐价格
|
packagePrice: m.packagePrice || null, // Bug #384修复: 套餐价格
|
||||||
serviceFee: m.serviceFee || null // Bug #384修复: 服务费
|
serviceFee: m.serviceFee || null // Bug #384修复: 服务费
|
||||||
}));
|
}));
|
||||||
@@ -1367,6 +1483,53 @@ defineExpose({ getList });
|
|||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bug #428修复: 分类下检查方法区域样式 */
|
||||||
|
.method-section {
|
||||||
|
padding: 6px 8px;
|
||||||
|
background: #f0f7ff;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-section-title {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #409eff;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
border-bottom: 1px dashed #d9ecff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 3px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-row:hover {
|
||||||
|
background: #e8f4ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-checkbox {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-checkbox :deep(.el-checkbox__label) {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
|
||||||
|
.method-price-tag {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #e6a23c;
|
||||||
|
font-weight: 500;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 已选择 tags */
|
/* 已选择 tags */
|
||||||
.selected-panel {
|
.selected-panel {
|
||||||
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
||||||
@@ -1438,6 +1601,41 @@ defineExpose({ getList });
|
|||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bug #428修复: 套餐明细列表样式 */
|
||||||
|
.package-details-list {
|
||||||
|
padding: 6px 10px;
|
||||||
|
background: #fffbe6;
|
||||||
|
border-top: 1px solid #ffe58f;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 11px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row:hover {
|
||||||
|
background: #fff9e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-name {
|
||||||
|
color: #303133;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-info {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
/* Bug #384修复: 检查方法勾选框列表 */
|
/* Bug #384修复: 检查方法勾选框列表 */
|
||||||
.method-list {
|
.method-list {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
|
|||||||
@@ -1021,7 +1021,21 @@ const mapAdviceTypeLabel = (type, adviceTableName) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const found = adviceTypeList.value.find((item) => item.value === type);
|
const found = adviceTypeList.value.find((item) => item.value === type);
|
||||||
return found ? found.label : '';
|
if (found) {
|
||||||
|
return found.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔧 Bug #458 Fix: 诊疗/手术类型字典缺失时的兜底,避免保存后"医嘱类型"列显示为空
|
||||||
|
if (adviceTableName === 'wor_activity_definition' || adviceTableName === 'wor_service_request') {
|
||||||
|
if (type === 6) return '手术';
|
||||||
|
if (type === 4) return '手术';
|
||||||
|
if (type === 1) return '检验';
|
||||||
|
if (type === 2) return '检查';
|
||||||
|
if (type === 5) return '其他';
|
||||||
|
return '诊疗';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
// 西药处方管理相关变量
|
// 西药处方管理相关变量
|
||||||
|
|||||||
@@ -79,7 +79,7 @@
|
|||||||
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
<el-table-column prop="patientName" label="患者姓名" width="120" />
|
||||||
<el-table-column prop="name" label="申请单名称" width="140" />
|
<el-table-column prop="name" label="申请单名称" width="140" />
|
||||||
<el-table-column prop="createTime" label="创建时间" width="160" />
|
<el-table-column prop="createTime" label="创建时间" width="160" />
|
||||||
<el-table-column prop="prescriptionNo" label="处方号" width="140" />
|
<el-table-column prop="prescriptionNo" label="申请单号" width="140" />
|
||||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||||
<el-table-column label="申请单状态" width="120" align="center">
|
<el-table-column label="申请单状态" width="120" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<el-descriptions-item label="创建时间">{{
|
<el-descriptions-item label="创建时间">{{
|
||||||
currentDetail.createTime || '-'
|
currentDetail.createTime || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="处方号">{{
|
<el-descriptions-item label="申请单号">{{
|
||||||
currentDetail.prescriptionNo || '-'
|
currentDetail.prescriptionNo || '-'
|
||||||
}}</el-descriptions-item>
|
}}</el-descriptions-item>
|
||||||
<el-descriptions-item label="申请者">{{
|
<el-descriptions-item label="申请者">{{
|
||||||
@@ -168,7 +168,7 @@ import {computed, getCurrentInstance, ref, watch} from 'vue';
|
|||||||
import {Refresh, Search} from '@element-plus/icons-vue';
|
import {Refresh, Search} from '@element-plus/icons-vue';
|
||||||
import {patientInfo} from '../../store/patient.js';
|
import {patientInfo} from '../../store/patient.js';
|
||||||
import {getCheck} from './api';
|
import {getCheck} from './api';
|
||||||
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
import {getDepartmentList} from '@/api/public.js';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
@@ -293,8 +293,8 @@ const hasMatchedFields = computed(() => {
|
|||||||
|
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = () => {
|
||||||
getOrgList().then((res) => {
|
getDepartmentList().then((res) => {
|
||||||
orgOptions.value = res.data.records;
|
orgOptions.value = res.data || [];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -306,6 +306,7 @@ const recursionFun = (targetDepartment) => {
|
|||||||
name = obj.name;
|
name = obj.name;
|
||||||
}
|
}
|
||||||
const subObjArray = obj['children'];
|
const subObjArray = obj['children'];
|
||||||
|
if (subObjArray && subObjArray.length > 0) {
|
||||||
for (let index = 0; index < subObjArray.length; index++) {
|
for (let index = 0; index < subObjArray.length; index++) {
|
||||||
const item = subObjArray[index];
|
const item = subObjArray[index];
|
||||||
if (item.id == targetDepartment) {
|
if (item.id == targetDepartment) {
|
||||||
@@ -313,10 +314,11 @@ const recursionFun = (targetDepartment) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = (row) => {
|
const handleViewDetail = async (row) => {
|
||||||
console.log('targetDepartment========>', JSON.stringify(row));
|
console.log('targetDepartment========>', JSON.stringify(row));
|
||||||
|
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
@@ -324,6 +326,15 @@ const handleViewDetail = (row) => {
|
|||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
try {
|
try {
|
||||||
const obj = JSON.parse(row.descJson);
|
const obj = JSON.parse(row.descJson);
|
||||||
|
// 确保科室数据已加载
|
||||||
|
if (!orgOptions.value || orgOptions.value.length === 0) {
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
getDepartmentList().then((res) => {
|
||||||
|
orgOptions.value = res.data || [];
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||||
descJsonData.value = obj;
|
descJsonData.value = obj;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -41,8 +41,6 @@
|
|||||||
<el-option label="全部" value="" />
|
<el-option label="全部" value="" />
|
||||||
<el-option label="待签发" value="0" />
|
<el-option label="待签发" value="0" />
|
||||||
<el-option label="已签发" value="1" />
|
<el-option label="已签发" value="1" />
|
||||||
<el-option label="已采集" value="2" />
|
|
||||||
<el-option label="已收样" value="3" />
|
|
||||||
<el-option label="报告已出" value="4" />
|
<el-option label="报告已出" value="4" />
|
||||||
<el-option label="已作废" value="5" />
|
<el-option label="已作废" value="5" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -298,8 +296,6 @@ const parseBillStatus = (status) => {
|
|||||||
const statusMap = {
|
const statusMap = {
|
||||||
'0': '待签发',
|
'0': '待签发',
|
||||||
'1': '已签发',
|
'1': '已签发',
|
||||||
'2': '已采集',
|
|
||||||
'3': '已收样',
|
|
||||||
'4': '报告已出',
|
'4': '报告已出',
|
||||||
'5': '已作废',
|
'5': '已作废',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ onMounted(() => {
|
|||||||
* type(1:watch监听类型 2:点击保存类型)
|
* type(1:watch监听类型 2:点击保存类型)
|
||||||
* selectProjectIds(选中项目的id数组)
|
* selectProjectIds(选中项目的id数组)
|
||||||
* */
|
* */
|
||||||
const projectWithDepartment = (selectProjectIds) => {
|
const projectWithDepartment = (selectProjectIds, type) => {
|
||||||
//1.获取选中的项目 2.判断项目的执行科室是否相同 3.判断执行科室是否配置 4.将项目的执行科室复值到执行科室下拉选位置
|
//1.获取选中的项目 2.判断项目的执行科室是否相同 3.判断执行科室是否配置 4.将项目的执行科室复值到执行科室下拉选位置
|
||||||
let isRelease = true;
|
let isRelease = true;
|
||||||
// 选中项目的数组
|
// 选中项目的数组
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ const submit = () => {
|
|||||||
encounterId: patientInfo.value.encounterId,
|
encounterId: patientInfo.value.encounterId,
|
||||||
organizationId: patientInfo.value.inHospitalOrgId,
|
organizationId: patientInfo.value.inHospitalOrgId,
|
||||||
requestFormId: '',
|
requestFormId: '',
|
||||||
name: '检查申请单',
|
name: applicationListAllFilter.map(item => item.adviceName).join('、'),
|
||||||
descJson: JSON.stringify(submitForm),
|
descJson: JSON.stringify(submitForm),
|
||||||
categoryEnum: '2',
|
categoryEnum: '2',
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
|||||||
@@ -801,8 +801,8 @@ function clickRowDb(row, column, event) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
row.showPopover = false;
|
row.showPopover = false;
|
||||||
// “待签发(已保存 requestId存在)”不允许再编辑;仅“待保存(无requestId)”允许编辑
|
// 仅”待签发(statusEnum==1)”允许编辑;”已签发(statusEnum==2)”及之后状态不允许编辑
|
||||||
if (row.statusEnum == 1 && !row.requestId) {
|
if (row.statusEnum == 1) {
|
||||||
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
||||||
row.therapyEnum = String(row.therapyEnum ?? '1');
|
row.therapyEnum = String(row.therapyEnum ?? '1');
|
||||||
row.isEdit = true;
|
row.isEdit = true;
|
||||||
|
|||||||
@@ -1416,9 +1416,12 @@ function closeChargeDialog() {
|
|||||||
if (prescriptionRef.value && prescriptionRef.value.closeAllPopovers) {
|
if (prescriptionRef.value && prescriptionRef.value.closeAllPopovers) {
|
||||||
prescriptionRef.value.closeAllPopovers()
|
prescriptionRef.value.closeAllPopovers()
|
||||||
}
|
}
|
||||||
|
// 等 Vue 完成 DOM 更新后再关闭弹窗,确保 popover 先消失
|
||||||
|
nextTick(() => {
|
||||||
showChargeDialog.value = false
|
showChargeDialog.value = false
|
||||||
chargePatientInfo.value = {}
|
chargePatientInfo.value = {}
|
||||||
chargeSurgeryInfo.value = {}
|
chargeSurgeryInfo.value = {}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔧 新增:标志位,用于区分是"打开"还是"刷新"
|
// 🔧 新增:标志位,用于区分是"打开"还是"刷新"
|
||||||
|
|||||||
Reference in New Issue
Block a user