Compare commits
1 Commits
guanyu
...
refactor/j
| Author | SHA1 | Date | |
|---|---|---|---|
| c21a96da05 |
@@ -1,7 +1,7 @@
|
|||||||
# HealthLink-HIS 代码模块索引
|
# HealthLink-HIS 代码模块索引
|
||||||
|
|
||||||
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
> 供 LLM 快速定位代码。每个模块列出 Controller → Service → Mapper 关键文件。
|
||||||
> 最后更新: 2026-06-16 12:00 (300 个 Controller)
|
> 最后更新: 2026-06-15 12:00 (300 个 Controller)
|
||||||
|
|
||||||
## 关键词 → 模块速查
|
## 关键词 → 模块速查
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.core.framework.config;
|
package com.core.framework.config;
|
||||||
|
|
||||||
|
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
|
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@@ -15,9 +14,6 @@ import tools.jackson.databind.ValueDeserializer;
|
|||||||
import tools.jackson.databind.ValueSerializer;
|
import tools.jackson.databind.ValueSerializer;
|
||||||
import tools.jackson.databind.module.SimpleModule;
|
import tools.jackson.databind.module.SimpleModule;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.TimeZone;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
@@ -59,18 +55,9 @@ public class ApplicationConfig {
|
|||||||
@Bean
|
@Bean
|
||||||
public JsonMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
public JsonMapperBuilderCustomizer jacksonObjectMapperCustomization() {
|
||||||
return builder -> {
|
return builder -> {
|
||||||
builder.defaultTimeZone(TimeZone.getDefault());
|
|
||||||
builder.defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
|
||||||
SimpleModule module = new SimpleModule("HealthLinkLocalDateTime");
|
SimpleModule module = new SimpleModule("HealthLinkLocalDateTime");
|
||||||
module.addDeserializer(LocalDateTime.class, LOCAL_DATE_TIME_DESERIALIZER);
|
module.addDeserializer(LocalDateTime.class, LOCAL_DATE_TIME_DESERIALIZER);
|
||||||
module.addSerializer(LocalDateTime.class, LOCAL_DATE_TIME_SERIALIZER);
|
module.addSerializer(LocalDateTime.class, LOCAL_DATE_TIME_SERIALIZER);
|
||||||
module.addSerializer(java.sql.Date.class, new ValueSerializer<java.sql.Date>() {
|
|
||||||
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
@Override
|
|
||||||
public void serialize(java.sql.Date value, JsonGenerator gen, SerializationContext ctx) throws JacksonException {
|
|
||||||
gen.writeString(sdf.format(value));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.addModule(module);
|
builder.addModule(module);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2697,6 +2697,21 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
log.info("getSurgeryPage 开始: orgId={}, page={}/{}, searchKey={}", organizationId, pageNo, pageSize, searchKey);
|
log.info("getSurgeryPage 开始: orgId={}, page={}/{}, searchKey={}", organizationId, pageNo, pageSize, searchKey);
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// 无搜索时尝试从 Redis 缓存读取(手术项目变更频率低,适合缓存)
|
||||||
|
String safeOrgId = organizationId != null ? organizationId.toString() : "";
|
||||||
|
String cacheKey = "surgery:page:" + safeOrgId + ":" + pageNo + ":" + pageSize;
|
||||||
|
boolean useCache = (searchKey == null || searchKey.trim().isEmpty());
|
||||||
|
|
||||||
|
if (useCache) {
|
||||||
|
Object cachedObj = redisCache.getCacheObject(cacheKey);
|
||||||
|
if (cachedObj instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) {
|
||||||
|
log.info("从 Redis 缓存获取手术项目, key: {}, records: {}", cacheKey,
|
||||||
|
((IPage<?>) cachedObj).getRecords().size());
|
||||||
|
return (IPage<SurgeryItemDto>) cachedObj;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 MyBatis Plus 分页查询
|
||||||
IPage<SurgeryItemDto> result = doctorStationAdviceAppMapper.getSurgeryPage(
|
IPage<SurgeryItemDto> result = doctorStationAdviceAppMapper.getSurgeryPage(
|
||||||
new Page<>(pageNo, pageSize),
|
new Page<>(pageNo, pageSize),
|
||||||
PublicationStatus.ACTIVE.getValue(),
|
PublicationStatus.ACTIVE.getValue(),
|
||||||
@@ -2705,6 +2720,12 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
|
|
||||||
log.info("getSurgeryPage 完成: {}ms, total={}, records={}", System.currentTimeMillis() - start, result.getTotal(), result.getRecords().size());
|
log.info("getSurgeryPage 完成: {}ms, total={}, records={}", System.currentTimeMillis() - start, result.getTotal(), result.getRecords().size());
|
||||||
|
|
||||||
|
// 无搜索时将结果写入缓存
|
||||||
|
if (useCache && result instanceof com.baomidou.mybatisplus.extension.plugins.pagination.Page) {
|
||||||
|
redisCache.setCacheObject(cacheKey, result, (int) CACHE_EXPIRE_HOURS, java.util.concurrent.TimeUnit.HOURS);
|
||||||
|
log.info("缓存手术项目, key: {}, 过期时间: {} 小时", cacheKey, CACHE_EXPIRE_HOURS);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,12 +45,6 @@ public class SurgeryItemDto {
|
|||||||
@JsonProperty("unitCode_dictText")
|
@JsonProperty("unitCode_dictText")
|
||||||
private String unitCodeDictText;
|
private String unitCodeDictText;
|
||||||
|
|
||||||
/** 拼音码(前端穿梭框本地搜索用) */
|
|
||||||
private String pyStr;
|
|
||||||
|
|
||||||
/** 业务编号(前端穿梭框本地搜索用) */
|
|
||||||
private String busNo;
|
|
||||||
|
|
||||||
/** 所需标本编码(来自诊疗目录配置,对应字典 specimen_code 的 dictValue) */
|
/** 所需标本编码(来自诊疗目录配置,对应字典 specimen_code 的 dictValue) */
|
||||||
private String specimenCode;
|
private String specimenCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,21 +378,10 @@ public class ATDManageAppServiceImpl implements IATDManageAppService {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> getInPatientPendingList(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize) {
|
public R<?> getInPatientPendingList(InpatientAdviceParam inpatientAdviceParam, Integer pageNo, Integer pageSize) {
|
||||||
// 提取deadline手动处理,防止自动拼接列名不存在的错误
|
|
||||||
String deadline = inpatientAdviceParam.getDeadline();
|
|
||||||
inpatientAdviceParam.setDeadline(null);
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||||
|
|
||||||
// 手动拼接截止时间条件:request_time <= deadline
|
|
||||||
if (StringUtils.isNotEmpty(deadline)) {
|
|
||||||
Date deadlineDate = DateUtils.parseDate(deadline);
|
|
||||||
if (deadlineDate != null) {
|
|
||||||
queryWrapper.le("request_time", deadlineDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 患者医嘱分页列表
|
// 患者医嘱分页列表
|
||||||
Page<InpatientAdviceDto> inpatientAdvicePage = atdManageAppMapper.selectInpatientAdvicePage(
|
Page<InpatientAdviceDto> inpatientAdvicePage = atdManageAppMapper.selectInpatientAdvicePage(
|
||||||
new Page<>(pageNo, pageSize), queryWrapper, CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
new Page<>(pageNo, pageSize), queryWrapper, CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||||
|
|||||||
@@ -53,9 +53,7 @@ import jakarta.annotation.Resource;
|
|||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.format.DateTimeParseException;
|
import java.time.format.DateTimeParseException;
|
||||||
@@ -184,22 +182,18 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
||||||
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
||||||
inpatientAdviceParam.setRequestStatus(null);
|
inpatientAdviceParam.setRequestStatus(null);
|
||||||
// 提取deadline手动处理,需要做NULL-safe的end_time比较(Bug #763修复)
|
// deadline 不在 UNION 子查询结果列中,且不映射为查询过滤条件
|
||||||
String deadline = inpatientAdviceParam.getDeadline();
|
// 原因:end_time 是医嘱结束时间,长期医嘱的 end_time 远在 deadline 之后,
|
||||||
|
// 使用 <= 过滤会排除所有长期医嘱,导致"未校对"tab 查询为空
|
||||||
inpatientAdviceParam.setDeadline(null);
|
inpatientAdviceParam.setDeadline(null);
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||||
|
|
||||||
// 手动拼接requestStatus条件:
|
// 手动拼接requestStatus条件:COMPLETED(3)时同时包含CHECK_VERIFIED(10)和PENDING_RECEIVE(11)
|
||||||
// 1. ACTIVE(2)时:同时包含已停嘱待核对的 PENDING_STOP(13)
|
|
||||||
// 2. COMPLETED(3)时:同时包含已校对检查 CHECK_VERIFIED(10) 和已接收 PENDING_RECEIVE(11)
|
|
||||||
// UNION查询外层列名为request_status(T1.status_enum AS request_status),不是status_enum
|
// UNION查询外层列名为request_status(T1.status_enum AS request_status),不是status_enum
|
||||||
if (requestStatus != null) {
|
if (requestStatus != null) {
|
||||||
if (RequestStatus.ACTIVE.getValue().equals(requestStatus)) {
|
if (RequestStatus.COMPLETED.getValue().equals(requestStatus)) {
|
||||||
queryWrapper.in("request_status",
|
|
||||||
RequestStatus.ACTIVE.getValue(), RequestStatus.PENDING_STOP.getValue());
|
|
||||||
} else if (RequestStatus.COMPLETED.getValue().equals(requestStatus)) {
|
|
||||||
queryWrapper.in("request_status",
|
queryWrapper.in("request_status",
|
||||||
RequestStatus.COMPLETED.getValue(), RequestStatus.CHECK_VERIFIED.getValue(),
|
RequestStatus.COMPLETED.getValue(), RequestStatus.CHECK_VERIFIED.getValue(),
|
||||||
RequestStatus.PENDING_RECEIVE.getValue());
|
RequestStatus.PENDING_RECEIVE.getValue());
|
||||||
@@ -214,18 +208,6 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
= Arrays.stream(encounterIds.split(CommonConstants.Common.COMMA)).map(Long::parseLong).toList();
|
= Arrays.stream(encounterIds.split(CommonConstants.Common.COMMA)).map(Long::parseLong).toList();
|
||||||
queryWrapper.in(CommonConstants.FieldName.EncounterId, encounterIdList);
|
queryWrapper.in(CommonConstants.FieldName.EncounterId, encounterIdList);
|
||||||
}
|
}
|
||||||
// 手动拼接deadline条件:end_time IS NULL OR end_time <= deadline(Bug #763修复)
|
|
||||||
// 住院医嘱的effective_dose_end可能为NULL(签发临时医嘱时未设置结束时间),
|
|
||||||
// PostgreSQL中 NULL <= anything 结果为FALSE,需要先判断IS NULL
|
|
||||||
if (deadline != null && !deadline.isEmpty()) {
|
|
||||||
try {
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
||||||
Date deadlineTime = sdf.parse(deadline);
|
|
||||||
queryWrapper.and(w -> w.isNull("end_time").or().le("end_time", deadlineTime));
|
|
||||||
} catch (java.text.ParseException e) {
|
|
||||||
// deadline解析失败,忽略此条件
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 患者医嘱分页列表
|
// 患者医嘱分页列表
|
||||||
Page<InpatientAdviceDto> inpatientAdvicePage
|
Page<InpatientAdviceDto> inpatientAdvicePage
|
||||||
= adviceProcessAppMapper.selectInpatientAdvicePage(new Page<>(pageNo, pageSize), queryWrapper,
|
= adviceProcessAppMapper.selectInpatientAdvicePage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||||
@@ -366,15 +348,7 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
|
|
||||||
// 根据执行状态过滤医嘱列表
|
// 根据执行状态过滤医嘱列表
|
||||||
List<InpatientAdviceDto> filteredList = new ArrayList<>();
|
List<InpatientAdviceDto> filteredList = new ArrayList<>();
|
||||||
if (EventStatus.PREPARATION.getValue().equals(exeStatus)) {
|
if (EventStatus.COMPLETED.getValue().equals(exeStatus)) {
|
||||||
// 待执行 - 过滤出没有已执行记录的医嘱(Bug #663修复)
|
|
||||||
filteredList = inpatientAdviceList.stream().filter(
|
|
||||||
advice -> advice.getExePerformRecordList() == null || advice.getExePerformRecordList().isEmpty())
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
// 更新分页数据
|
|
||||||
inpatientAdvicePage.setRecords(filteredList);
|
|
||||||
inpatientAdvicePage.setTotal(filteredList.size());
|
|
||||||
} else if (EventStatus.COMPLETED.getValue().equals(exeStatus)) {
|
|
||||||
// 已执行 - 过滤出有执行记录的医嘱
|
// 已执行 - 过滤出有执行记录的医嘱
|
||||||
filteredList = inpatientAdviceList.stream().filter(
|
filteredList = inpatientAdviceList.stream().filter(
|
||||||
advice -> advice.getExePerformRecordList() != null && !advice.getExePerformRecordList().isEmpty())
|
advice -> advice.getExePerformRecordList() != null && !advice.getExePerformRecordList().isEmpty())
|
||||||
@@ -427,30 +401,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
Date checkDate = new Date();
|
Date checkDate = new Date();
|
||||||
if (!serviceRequestList.isEmpty()) {
|
if (!serviceRequestList.isEmpty()) {
|
||||||
List<Long> serviceReqIds = serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
List<Long> serviceReqIds = serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||||
// 先查询服务请求,进行状态分流:
|
// 先查询服务请求,按 categoryEnum 分流:检查类(23)走 CHECK_VERIFIED,其余走 COMPLETED
|
||||||
// 1. 如果是停嘱待核对(PENDING_STOP=13),则核对后转为停止(STOPPED=6)
|
|
||||||
// 2. 否则按类别分流:检查类(23)走 CHECK_VERIFIED,其余走 COMPLETED
|
|
||||||
List<ServiceRequest> allServiceRequests = serviceRequestService.listByIds(serviceReqIds);
|
List<ServiceRequest> allServiceRequests = serviceRequestService.listByIds(serviceReqIds);
|
||||||
List<Long> stopReqIds = allServiceRequests.stream()
|
|
||||||
.filter(sr -> RequestStatus.PENDING_STOP.getValue().equals(sr.getStatusEnum()))
|
|
||||||
.map(ServiceRequest::getId).toList();
|
|
||||||
List<Long> checkReqIds = allServiceRequests.stream()
|
List<Long> checkReqIds = allServiceRequests.stream()
|
||||||
.filter(sr -> !RequestStatus.PENDING_STOP.getValue().equals(sr.getStatusEnum())
|
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||||
&& ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
|
||||||
.map(ServiceRequest::getId).toList();
|
.map(ServiceRequest::getId).toList();
|
||||||
List<Long> otherReqIds = allServiceRequests.stream()
|
List<Long> otherReqIds = allServiceRequests.stream()
|
||||||
.filter(sr -> !RequestStatus.PENDING_STOP.getValue().equals(sr.getStatusEnum())
|
.filter(sr -> !ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||||
&& !ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
|
||||||
.map(ServiceRequest::getId).toList();
|
.map(ServiceRequest::getId).toList();
|
||||||
|
|
||||||
// 停嘱待核对 → 停止(STOPPED=6)
|
|
||||||
if (!stopReqIds.isEmpty()) {
|
|
||||||
serviceRequestService.update(new LambdaUpdateWrapper<ServiceRequest>()
|
|
||||||
.in(ServiceRequest::getId, stopReqIds)
|
|
||||||
.set(ServiceRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
|
||||||
.set(ServiceRequest::getPerformerCheckId, practitionerId)
|
|
||||||
.set(ServiceRequest::getCheckTime, checkDate));
|
|
||||||
}
|
|
||||||
// 检查类 → 已校对(CHECK_VERIFIED=10)
|
// 检查类 → 已校对(CHECK_VERIFIED=10)
|
||||||
if (!checkReqIds.isEmpty()) {
|
if (!checkReqIds.isEmpty()) {
|
||||||
serviceRequestService.updateCheckVerifiedStatus(checkReqIds, practitionerId, checkDate);
|
serviceRequestService.updateCheckVerifiedStatus(checkReqIds, practitionerId, checkDate);
|
||||||
@@ -471,50 +429,14 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!medRequestList.isEmpty()) {
|
if (!medRequestList.isEmpty()) {
|
||||||
List<Long> medReqIds = medRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
// 更新药品请求状态已完成
|
||||||
List<MedicationRequest> allMedRequests = medicationRequestService.listByIds(medReqIds);
|
medicationRequestService.updateCompletedStatusBatch(
|
||||||
|
medRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate);
|
||||||
List<Long> stopMedIds = allMedRequests.stream()
|
|
||||||
.filter(mr -> RequestStatus.PENDING_STOP.getValue().equals(mr.getStatusEnum()))
|
|
||||||
.map(MedicationRequest::getId).toList();
|
|
||||||
List<Long> otherMedIds = allMedRequests.stream()
|
|
||||||
.filter(mr -> !RequestStatus.PENDING_STOP.getValue().equals(mr.getStatusEnum()))
|
|
||||||
.map(MedicationRequest::getId).toList();
|
|
||||||
|
|
||||||
// 停嘱待核对 → 停止(STOPPED=6)
|
|
||||||
if (!stopMedIds.isEmpty()) {
|
|
||||||
medicationRequestService.update(new LambdaUpdateWrapper<MedicationRequest>()
|
|
||||||
.in(MedicationRequest::getId, stopMedIds)
|
|
||||||
.set(MedicationRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
|
||||||
.set(MedicationRequest::getPerformerCheckId, practitionerId)
|
|
||||||
.set(MedicationRequest::getCheckTime, checkDate));
|
|
||||||
}
|
|
||||||
// 其他类 → 已完成(COMPLETED=3)
|
|
||||||
if (!otherMedIds.isEmpty()) {
|
|
||||||
medicationRequestService.updateCompletedStatusBatch(otherMedIds, practitionerId, checkDate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!deviceRequestList.isEmpty()) {
|
if (!deviceRequestList.isEmpty()) {
|
||||||
List<Long> devReqIds = deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
// 更新耗材请求状态已完成
|
||||||
// 同样处理耗材的停嘱核对
|
deviceRequestService.updateCompletedStatusBatch(
|
||||||
List<DeviceRequest> allDevRequests = deviceRequestService.listByIds(devReqIds);
|
deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList());
|
||||||
List<Long> stopDevIds = allDevRequests.stream()
|
|
||||||
.filter(dr -> RequestStatus.PENDING_STOP.getValue().equals(dr.getStatusEnum()))
|
|
||||||
.map(DeviceRequest::getId).toList();
|
|
||||||
List<Long> otherDevIds = allDevRequests.stream()
|
|
||||||
.filter(dr -> !RequestStatus.PENDING_STOP.getValue().equals(dr.getStatusEnum()))
|
|
||||||
.map(DeviceRequest::getId).toList();
|
|
||||||
|
|
||||||
if (!stopDevIds.isEmpty()) {
|
|
||||||
deviceRequestService.update(new LambdaUpdateWrapper<DeviceRequest>()
|
|
||||||
.in(DeviceRequest::getId, stopDevIds)
|
|
||||||
.set(DeviceRequest::getStatusEnum, RequestStatus.STOPPED.getValue())
|
|
||||||
.set(DeviceRequest::getPerformerCheckId, practitionerId)
|
|
||||||
.set(DeviceRequest::getCheckTime, checkDate));
|
|
||||||
}
|
|
||||||
if (!otherDevIds.isEmpty()) {
|
|
||||||
deviceRequestService.updateCompletedStatusBatch(otherDevIds);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return R.ok(null, "校对成功");
|
return R.ok(null, "校对成功");
|
||||||
}
|
}
|
||||||
@@ -590,7 +512,8 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
|||||||
if (!deviceRequestList.isEmpty()) {
|
if (!deviceRequestList.isEmpty()) {
|
||||||
// 更新耗材请求状态待发送
|
// 更新耗材请求状态待发送
|
||||||
deviceRequestService.updateDraftStatusBatch(
|
deviceRequestService.updateDraftStatusBatch(
|
||||||
deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList());
|
deviceRequestList.stream().map(PerformInfoDto::getRequestId).toList(),
|
||||||
|
practitionerId, checkDate, backReason);
|
||||||
}
|
}
|
||||||
return R.ok(null, "退回成功");
|
return R.ok(null, "退回成功");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,10 +153,6 @@ public class MedicineSummaryAppServiceImpl implements IMedicineSummaryAppService
|
|||||||
// 就诊ID集合
|
// 就诊ID集合
|
||||||
String encounterIds = dispenseFormSearchParam.getEncounterIds();
|
String encounterIds = dispenseFormSearchParam.getEncounterIds();
|
||||||
dispenseFormSearchParam.setEncounterIds(null);
|
dispenseFormSearchParam.setEncounterIds(null);
|
||||||
// 汇总单查询不适用的字段清空(汇总单表无 tcm_flag 等列,避免 SQL 报错)
|
|
||||||
dispenseFormSearchParam.setTcmFlag(null);
|
|
||||||
dispenseFormSearchParam.setTherapyEnum(null);
|
|
||||||
dispenseFormSearchParam.setExeTime(null);
|
|
||||||
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
QueryWrapper<DispenseFormSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(dispenseFormSearchParam,
|
QueryWrapper<DispenseFormSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(dispenseFormSearchParam,
|
||||||
|
|||||||
@@ -235,21 +235,10 @@ public class NurseBillingAppService implements INurseBillingAppService {
|
|||||||
inpatientAdviceParam.setEncounterIds(null);
|
inpatientAdviceParam.setEncounterIds(null);
|
||||||
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
||||||
inpatientAdviceParam.setExeStatus(null);
|
inpatientAdviceParam.setExeStatus(null);
|
||||||
// 提取deadline手动处理,防止自动拼接列名不存在的错误
|
|
||||||
String deadline = inpatientAdviceParam.getDeadline();
|
|
||||||
inpatientAdviceParam.setDeadline(null);
|
|
||||||
// 构建查询条件
|
// 构建查询条件
|
||||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||||
|
|
||||||
// 手动拼接截止时间条件:request_time <= deadline
|
|
||||||
if (StringUtils.isNotEmpty(deadline)) {
|
|
||||||
Date deadlineDate = DateUtils.parseDate(deadline);
|
|
||||||
if (deadlineDate != null) {
|
|
||||||
queryWrapper.le("request_time", deadlineDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 手动拼接住院患者id条件
|
// 手动拼接住院患者id条件
|
||||||
if (encounterIds != null && !encounterIds.isEmpty()) {
|
if (encounterIds != null && !encounterIds.isEmpty()) {
|
||||||
List<Long> encounterIdList
|
List<Long> encounterIdList
|
||||||
|
|||||||
@@ -970,9 +970,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
// }
|
// }
|
||||||
// æ ¹æ®çœå¸‚医ä¿åˆ†ç»„
|
// æ ¹æ®çœå¸‚医ä¿åˆ†ç»„
|
||||||
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
||||||
.stream()
|
.stream().collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
||||||
.filter(e -> e.getContractNo() != null && !e.getContractNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
|
||||||
|
|
||||||
// 查询所有的收费项
|
// 查询所有的收费项
|
||||||
List<String> chargeItemIdStrs = paymentReconciliationList.stream().map(PaymentReconciliation::getChargeItemIds)
|
List<String> chargeItemIdStrs = paymentReconciliationList.stream().map(PaymentReconciliation::getChargeItemIds)
|
||||||
@@ -1045,9 +1043,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
// é•¿å¤§ç‰ˆæœ¬è¦æ˜¾ç¤ºå‡ºæ¥çœå¸‚医ä¿çš„区别
|
// é•¿å¤§ç‰ˆæœ¬è¦æ˜¾ç¤ºå‡ºæ¥çœå¸‚医ä¿çš„区别
|
||||||
List<Contract> redisContractList = iContractService.getRedisContractList();
|
List<Contract> redisContractList = iContractService.getRedisContractList();
|
||||||
Map<String, List<Contract>> contractMapByBusNo
|
Map<String, List<Contract>> contractMapByBusNo
|
||||||
= redisContractList.stream()
|
= redisContractList.stream().collect(Collectors.groupingBy(Contract::getBusNo));
|
||||||
.filter(e -> e.getBusNo() != null && !e.getBusNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(Contract::getBusNo));
|
|
||||||
for (Map.Entry<String, List<PaymentRecDetailAccountResult>> stringListEntry : paymentDetailsMapByContract
|
for (Map.Entry<String, List<PaymentRecDetailAccountResult>> stringListEntry : paymentDetailsMapByContract
|
||||||
.entrySet()) {
|
.entrySet()) {
|
||||||
String key = stringListEntry.getKey();
|
String key = stringListEntry.getKey();
|
||||||
@@ -1449,9 +1445,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
// 医ä¿äººæ¬¡è‡ªè´¹äººæ¬¡è®¡ç®—
|
// 医ä¿äººæ¬¡è‡ªè´¹äººæ¬¡è®¡ç®—
|
||||||
List<EncounterAccountDto> list = iEncounterService.getEncounterInfoByTime(startDate, endDate);
|
List<EncounterAccountDto> list = iEncounterService.getEncounterInfoByTime(startDate, endDate);
|
||||||
Map<String, List<EncounterAccountDto>> encounterAccountDtoMapByContract
|
Map<String, List<EncounterAccountDto>> encounterAccountDtoMapByContract
|
||||||
= list.stream()
|
= list.stream().collect(Collectors.groupingBy(EncounterAccountDto::getContractNo));
|
||||||
.filter(e -> e.getContractNo() != null && !e.getContractNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(EncounterAccountDto::getContractNo));
|
|
||||||
for (Map.Entry<String, List<EncounterAccountDto>> stringListEntry : encounterAccountDtoMapByContract
|
for (Map.Entry<String, List<EncounterAccountDto>> stringListEntry : encounterAccountDtoMapByContract
|
||||||
.entrySet()) {
|
.entrySet()) {
|
||||||
String key = stringListEntry.getKey();
|
String key = stringListEntry.getKey();
|
||||||
@@ -1525,9 +1519,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
|
|
||||||
// æ ¹æ®çœå¸‚医ä¿åˆ†ç»„
|
// æ ¹æ®çœå¸‚医ä¿åˆ†ç»„
|
||||||
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
Map<String, List<PaymentRecDetailAccountResult>> paymentDetailsMapByContract = PaymentRecDetailAccountResultList
|
||||||
.stream()
|
.stream().collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
||||||
.filter(e -> e.getContractNo() != null && !e.getContractNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(PaymentRecDetailAccountResult::getContractNo));
|
|
||||||
|
|
||||||
BigDecimal cashSum = BigDecimal.ZERO;// 现金总数 = rmbCashSum + vxCashSum + aliCashSum + uniCashSum
|
BigDecimal cashSum = BigDecimal.ZERO;// 现金总数 = rmbCashSum + vxCashSum + aliCashSum + uniCashSum
|
||||||
BigDecimal rmbCashSum = BigDecimal.ZERO;// 现金总数
|
BigDecimal rmbCashSum = BigDecimal.ZERO;// 现金总数
|
||||||
@@ -1543,9 +1535,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
// é•¿å¤§ç‰ˆæœ¬è¦æ˜¾ç¤ºå‡ºæ¥çœå¸‚医ä¿çš„区别
|
// é•¿å¤§ç‰ˆæœ¬è¦æ˜¾ç¤ºå‡ºæ¥çœå¸‚医ä¿çš„区别
|
||||||
List<Contract> redisContractList = iContractService.getRedisContractList();
|
List<Contract> redisContractList = iContractService.getRedisContractList();
|
||||||
Map<String, List<Contract>> contractMapByBusNo
|
Map<String, List<Contract>> contractMapByBusNo
|
||||||
= redisContractList.stream()
|
= redisContractList.stream().collect(Collectors.groupingBy(Contract::getBusNo));
|
||||||
.filter(e -> e.getBusNo() != null && !e.getBusNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(Contract::getBusNo));
|
|
||||||
for (Map.Entry<String, List<PaymentRecDetailAccountResult>> stringListEntry : paymentDetailsMapByContract
|
for (Map.Entry<String, List<PaymentRecDetailAccountResult>> stringListEntry : paymentDetailsMapByContract
|
||||||
.entrySet()) {
|
.entrySet()) {
|
||||||
|
|
||||||
@@ -1932,9 +1922,7 @@ public class IChargeBillServiceImpl implements IChargeBillService {
|
|||||||
// 医ä¿äººæ¬¡è‡ªè´¹äººæ¬¡è®¡ç®—
|
// 医ä¿äººæ¬¡è‡ªè´¹äººæ¬¡è®¡ç®—
|
||||||
List<EncounterAccountDto> list = iEncounterService.getEncounterInfoByTime(startDate, endDate);
|
List<EncounterAccountDto> list = iEncounterService.getEncounterInfoByTime(startDate, endDate);
|
||||||
Map<String, List<EncounterAccountDto>> encounterAccountDtoMapByContract
|
Map<String, List<EncounterAccountDto>> encounterAccountDtoMapByContract
|
||||||
= list.stream()
|
= list.stream().collect(Collectors.groupingBy(EncounterAccountDto::getContractNo));
|
||||||
.filter(e -> e.getContractNo() != null && !e.getContractNo().isEmpty())
|
|
||||||
.collect(Collectors.groupingBy(EncounterAccountDto::getContractNo));
|
|
||||||
for (Map.Entry<String, List<EncounterAccountDto>> stringListEntry : encounterAccountDtoMapByContract
|
for (Map.Entry<String, List<EncounterAccountDto>> stringListEntry : encounterAccountDtoMapByContract
|
||||||
.entrySet()) {
|
.entrySet()) {
|
||||||
String key = stringListEntry.getKey();
|
String key = stringListEntry.getKey();
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- DEPRECATED: 本迁移已迁移至 V45__bug745_fix_mr_sealing_medical_record_id.sql
|
||||||
|
-- 原因:与 V42__add_delete_flag_columns.sql 版本号重复,导致 Flyway 阻塞
|
||||||
|
-- 此文件保留为空操作以避免 Flyway 校验错误
|
||||||
@@ -44,7 +44,6 @@
|
|||||||
ON T1.organization_id = T4.id
|
ON T1.organization_id = T4.id
|
||||||
AND T4.delete_flag = '0'
|
AND T4.delete_flag = '0'
|
||||||
WHERE T1.delete_flag = '0'
|
WHERE T1.delete_flag = '0'
|
||||||
AND T1.status_enum IN (4, 5)
|
|
||||||
GROUP BY T1.id,
|
GROUP BY T1.id,
|
||||||
T1.bus_no,
|
T1.bus_no,
|
||||||
T1.patient_id,
|
T1.patient_id,
|
||||||
|
|||||||
@@ -903,9 +903,7 @@
|
|||||||
t2.ID AS charge_item_definition_id,
|
t2.ID AS charge_item_definition_id,
|
||||||
t2.price AS price,
|
t2.price AS price,
|
||||||
t1.permitted_unit_code AS unit_code,
|
t1.permitted_unit_code AS unit_code,
|
||||||
COALESCE(sdd.dict_label, t1.permitted_unit_code) AS unit_code_dict_text,
|
COALESCE(sdd.dict_label, t1.permitted_unit_code) AS unit_code_dict_text
|
||||||
t1.py_str AS py_str,
|
|
||||||
t1.bus_no AS bus_no
|
|
||||||
FROM wor_activity_definition t1
|
FROM wor_activity_definition t1
|
||||||
LEFT JOIN adm_charge_item_definition t2
|
LEFT JOIN adm_charge_item_definition t2
|
||||||
ON t2.instance_id = t1.ID
|
ON t2.instance_id = t1.ID
|
||||||
@@ -917,7 +915,6 @@
|
|||||||
AND sdd.dict_type = 'unit_code'
|
AND sdd.dict_type = 'unit_code'
|
||||||
AND sdd.status = '0'
|
AND sdd.status = '0'
|
||||||
WHERE t1.delete_flag = '0'
|
WHERE t1.delete_flag = '0'
|
||||||
AND t1.status_enum = #{statusEnum}
|
|
||||||
AND (t1.category_code = '手术' OR t1.category_code = '24')
|
AND (t1.category_code = '手术' OR t1.category_code = '24')
|
||||||
<if test="searchKey != null and searchKey != ''">
|
<if test="searchKey != null and searchKey != ''">
|
||||||
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
|
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
|
||||||
@@ -952,7 +949,6 @@
|
|||||||
AND sdd.dict_type = 'unit_code'
|
AND sdd.dict_type = 'unit_code'
|
||||||
AND sdd.status = '0'
|
AND sdd.status = '0'
|
||||||
WHERE t1.delete_flag = '0'
|
WHERE t1.delete_flag = '0'
|
||||||
AND t1.status_enum = #{statusEnum}
|
|
||||||
AND t1.category_code = #{categoryCode}
|
AND t1.category_code = #{categoryCode}
|
||||||
<if test="searchKey != null and searchKey != ''">
|
<if test="searchKey != null and searchKey != ''">
|
||||||
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
|
AND (t1.name ILIKE '%' || #{searchKey} || '%' OR t1.py_str ILIKE '%' || #{searchKey} || '%')
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"test:coverage": "vitest run --coverage",
|
"test:coverage": "vitest run --coverage",
|
||||||
"test:ui": "vitest --ui",
|
"test:ui": "vitest --ui",
|
||||||
"lint": "eslint . --ext .js,.vue src/",
|
"lint": "eslint . --ext .js,.vue src/",
|
||||||
|
"format": "prettier --write src/**/*.{vue,js,ts,jsx,tsx,scss,css,json}",
|
||||||
"test:e2e": "playwright test",
|
"test:e2e": "playwright test",
|
||||||
"test:e2e:ui": "playwright test --ui",
|
"test:e2e:ui": "playwright test --ui",
|
||||||
"test:e2e:report": "playwright show-report"
|
"test:e2e:report": "playwright show-report"
|
||||||
@@ -81,6 +82,7 @@
|
|||||||
"happy-dom": "^20.8.3",
|
"happy-dom": "^20.8.3",
|
||||||
"jsdom": "^28.1.0",
|
"jsdom": "^28.1.0",
|
||||||
"pg": "^8.18.0",
|
"pg": "^8.18.0",
|
||||||
|
"prettier": "^3.8.4",
|
||||||
"sass": "^1.100.0",
|
"sass": "^1.100.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"unplugin-auto-import": "^0.18.6",
|
"unplugin-auto-import": "^0.18.6",
|
||||||
|
|||||||
@@ -4,11 +4,11 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {hiprint} from 'vue-plugin-hiprint';
|
import {hiprint} from 'vue-plugin-hiprint';
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
|
import {ElMessage} from 'element-plus';
|
||||||
|
|
||||||
// 打印模板映射表 .
|
// 打印模板映射表 .
|
||||||
const TEMPLATE_MAP = {
|
const TEMPLATE_MAP = {
|
||||||
// CLINIC_CHARGE: () => import('@/views/charge/cliniccharge/components/template.json'),
|
|
||||||
// DISPOSAL: () => import('@/views/clinicmanagement/disposal/components/disposalTemplate.json'),
|
|
||||||
//处方签
|
//处方签
|
||||||
PRESCRIPTION: () => import('@/components/Print/Prescription.json'),
|
PRESCRIPTION: () => import('@/components/Print/Prescription.json'),
|
||||||
//处置单
|
//处置单
|
||||||
@@ -137,53 +137,29 @@ export async function simplePrintWithDialog(
|
|||||||
|
|
||||||
// 导出模板名称常量
|
// 导出模板名称常量
|
||||||
export const PRINT_TEMPLATE = {
|
export const PRINT_TEMPLATE = {
|
||||||
// CLINIC_CHARGE: 'CLINIC_CHARGE',
|
|
||||||
DAY_END: 'DAY_END',
|
DAY_END: 'DAY_END',
|
||||||
WESTERN_MEDICINE: 'WESTERN_MEDICINE',
|
WESTERN_MEDICINE: 'WESTERN_MEDICINE',
|
||||||
IN_HOSPITAL_DISPENSING: 'IN_HOSPITAL_DISPENSING',
|
IN_HOSPITAL_DISPENSING: 'IN_HOSPITAL_DISPENSING',
|
||||||
//门诊挂号
|
|
||||||
OUTPATIENT_REGISTRATION: 'OUTPATIENT_REGISTRATION',
|
OUTPATIENT_REGISTRATION: 'OUTPATIENT_REGISTRATION',
|
||||||
// 门诊手术计费
|
|
||||||
OUTPATIENT_SURGERY_CHARGE: 'OUTPATIENT_SURGERY_CHARGE',
|
OUTPATIENT_SURGERY_CHARGE: 'OUTPATIENT_SURGERY_CHARGE',
|
||||||
//门诊收费
|
|
||||||
OUTPATIENT_CHARGE: 'OUTPATIENT_CHARGE',
|
OUTPATIENT_CHARGE: 'OUTPATIENT_CHARGE',
|
||||||
//处方签
|
|
||||||
PRESCRIPTION: 'PRESCRIPTION',
|
PRESCRIPTION: 'PRESCRIPTION',
|
||||||
//处置单
|
|
||||||
DISPOSAL: 'DISPOSAL',
|
DISPOSAL: 'DISPOSAL',
|
||||||
//门诊病历
|
|
||||||
OUTPATIENT_MEDICAL_RECORD: 'OUTPATIENT_MEDICAL_RECORD',
|
OUTPATIENT_MEDICAL_RECORD: 'OUTPATIENT_MEDICAL_RECORD',
|
||||||
//门诊输液贴
|
|
||||||
OUTPATIENT_INFUSION: 'OUTPATIENT_INFUSION',
|
OUTPATIENT_INFUSION: 'OUTPATIENT_INFUSION',
|
||||||
//手术记录
|
|
||||||
OPERATIVE_RECORD: 'OPERATIVE_RECORD',
|
OPERATIVE_RECORD: 'OPERATIVE_RECORD',
|
||||||
//红旗门诊病历
|
|
||||||
HQOUTPATIENT_MEDICAL_RECORD: 'HQOUTPATIENT_MEDICAL_RECORD',
|
HQOUTPATIENT_MEDICAL_RECORD: 'HQOUTPATIENT_MEDICAL_RECORD',
|
||||||
//预交金
|
|
||||||
ADVANCE_PAYMENT: 'ADVANCE_PAYMENT',
|
ADVANCE_PAYMENT: 'ADVANCE_PAYMENT',
|
||||||
//中药处方单
|
|
||||||
CHINESE_MEDICINE_PRESCRIPTION: 'CHINESE_MEDICINE_PRESCRIPTION',
|
CHINESE_MEDICINE_PRESCRIPTION: 'CHINESE_MEDICINE_PRESCRIPTION',
|
||||||
//药房处方单
|
|
||||||
PHARMACY_PRESCRIPTION: 'PHARMACY_PRESCRIPTION',
|
PHARMACY_PRESCRIPTION: 'PHARMACY_PRESCRIPTION',
|
||||||
//中药医生处方单
|
|
||||||
DOC_CHINESE_MEDICINE_PRESCRIPTION: 'DOC_CHINESE_MEDICINE_PRESCRIPTION',
|
DOC_CHINESE_MEDICINE_PRESCRIPTION: 'DOC_CHINESE_MEDICINE_PRESCRIPTION',
|
||||||
|
|
||||||
// ========== 新增模板(原LODOP迁移)==========
|
|
||||||
//腕带
|
|
||||||
WRIST_BAND: 'WRIST_BAND',
|
WRIST_BAND: 'WRIST_BAND',
|
||||||
//分诊条
|
|
||||||
TRIAGE_TICKET: 'TRIAGE_TICKET',
|
TRIAGE_TICKET: 'TRIAGE_TICKET',
|
||||||
//输液标签
|
|
||||||
INJECT_LABEL: 'INJECT_LABEL',
|
INJECT_LABEL: 'INJECT_LABEL',
|
||||||
//床头卡
|
|
||||||
BED_CARD: 'BED_CARD',
|
BED_CARD: 'BED_CARD',
|
||||||
//护理交接班
|
|
||||||
CHANGE_SHIFT_BILL: 'CHANGE_SHIFT_BILL',
|
CHANGE_SHIFT_BILL: 'CHANGE_SHIFT_BILL',
|
||||||
//医嘱执行单
|
|
||||||
EXE_ORDER_SHEET: 'EXE_ORDER_SHEET',
|
EXE_ORDER_SHEET: 'EXE_ORDER_SHEET',
|
||||||
//体温单
|
|
||||||
TEMPERATURE_SHEET: 'TEMPERATURE_SHEET',
|
TEMPERATURE_SHEET: 'TEMPERATURE_SHEET',
|
||||||
//会诊申请单
|
|
||||||
CONSULTATION: 'CONSULTATION',
|
CONSULTATION: 'CONSULTATION',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -206,28 +182,20 @@ export function getPrinterList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
import useUserStore from '@/store/modules/user';
|
|
||||||
import {ElMessage} from 'element-plus';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取当前登录用户ID
|
* 获取当前登录用户ID
|
||||||
* @returns {string} 用户ID
|
|
||||||
*/
|
*/
|
||||||
function getCurrentUserId() {
|
function getCurrentUserId() {
|
||||||
try {
|
try {
|
||||||
// 从Pinia store中获取当前用户ID
|
|
||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
return userStore.id || '';
|
return userStore.id || '';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('获取用户ID失败:', e);
|
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成打印机缓存键
|
* 生成打印机缓存键
|
||||||
* @param {string} businessName 打印业务名称
|
|
||||||
* @returns {string} 缓存键
|
|
||||||
*/
|
*/
|
||||||
function getPrinterCacheKey(businessName) {
|
function getPrinterCacheKey(businessName) {
|
||||||
const userId = getCurrentUserId();
|
const userId = getCurrentUserId();
|
||||||
@@ -236,8 +204,6 @@ function getPrinterCacheKey(businessName) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 从缓存获取上次选择的打印机
|
* 从缓存获取上次选择的打印机
|
||||||
* @param {string} businessName 打印业务名称
|
|
||||||
* @returns {string} 打印机名称
|
|
||||||
*/
|
*/
|
||||||
export function getCachedPrinter(businessName = 'default') {
|
export function getCachedPrinter(businessName = 'default') {
|
||||||
const cacheKey = getPrinterCacheKey(businessName);
|
const cacheKey = getPrinterCacheKey(businessName);
|
||||||
@@ -246,8 +212,6 @@ export function getCachedPrinter(businessName = 'default') {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存打印机选择到缓存
|
* 保存打印机选择到缓存
|
||||||
* @param {string} printerName 打印机名称
|
|
||||||
* @param {string} businessName 打印业务名称
|
|
||||||
*/
|
*/
|
||||||
export function savePrinterToCache(printerName, businessName = 'default') {
|
export function savePrinterToCache(printerName, businessName = 'default') {
|
||||||
if (printerName) {
|
if (printerName) {
|
||||||
@@ -257,13 +221,7 @@ export function savePrinterToCache(printerName, businessName = 'default') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行打印操作
|
* 执行打印操作 (带自动二维码生成逻辑)
|
||||||
* @param {Array} data 打印数据
|
|
||||||
* @param {Object} template 打印模板
|
|
||||||
* @param {string} printerName 打印机名称(可选)
|
|
||||||
* @param {Object} options 打印选项(可选)
|
|
||||||
* @param {string} businessName 打印业务名称(可选)
|
|
||||||
* @returns {Promise} 打印结果Promise
|
|
||||||
*/
|
*/
|
||||||
export function executePrint(data, template, printerName, options = {}, businessName = 'default') {
|
export function executePrint(data, template, printerName, options = {}, businessName = 'default') {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -328,12 +286,6 @@ export function executePrint(data, template, printerName, options = {}, business
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 选择打印机并执行打印
|
* 选择打印机并执行打印
|
||||||
* @param {Array} data 打印数据
|
|
||||||
* @param {Object} template 打印模板
|
|
||||||
* @param {Function} showPrinterDialog 显示打印机选择对话框的函数
|
|
||||||
* @param {Object} modal 消息提示对象
|
|
||||||
* @param {Function} callback 打印完成后的回调函数
|
|
||||||
* @param {string} businessName 打印业务名称(可选)
|
|
||||||
*/
|
*/
|
||||||
export async function selectPrinterAndPrint(
|
export async function selectPrinterAndPrint(
|
||||||
data,
|
data,
|
||||||
@@ -344,29 +296,24 @@ export async function selectPrinterAndPrint(
|
|||||||
businessName = 'default'
|
businessName = 'default'
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
// 获取打印机列表
|
|
||||||
const printerList = getPrinterList();
|
const printerList = getPrinterList();
|
||||||
|
|
||||||
if (printerList.length === 0) {
|
if (printerList.length === 0) {
|
||||||
modal.msgWarning('未检测到可用打印机');
|
modal.msgWarning('未检测到可用打印机');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取缓存的打印机
|
|
||||||
const cachedPrinter = getCachedPrinter(businessName);
|
const cachedPrinter = getCachedPrinter(businessName);
|
||||||
let selectedPrinter = '';
|
let selectedPrinter = '';
|
||||||
|
|
||||||
// 判断打印机选择逻辑
|
|
||||||
if (printerList.length === 1) {
|
if (printerList.length === 1) {
|
||||||
selectedPrinter = printerList[0].name;
|
selectedPrinter = printerList[0].name;
|
||||||
await executePrint(data, template, selectedPrinter, {}, businessName);
|
await executePrint(data, template, selectedPrinter, {}, businessName);
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
} else if (cachedPrinter && printerList.some((printer) => printer.name === cachedPrinter)) {
|
} else if (cachedPrinter && printerList.some((p) => p.name === cachedPrinter)) {
|
||||||
selectedPrinter = cachedPrinter;
|
selectedPrinter = cachedPrinter;
|
||||||
await executePrint(data, template, selectedPrinter, {}, businessName);
|
await executePrint(data, template, selectedPrinter, {}, businessName);
|
||||||
if (callback) callback();
|
if (callback) callback();
|
||||||
} else {
|
} else {
|
||||||
// 调用显示打印机选择对话框的函数
|
|
||||||
showPrinterDialog(printerList, async (chosenPrinter) => {
|
showPrinterDialog(printerList, async (chosenPrinter) => {
|
||||||
try {
|
try {
|
||||||
await executePrint(data, template, chosenPrinter, {}, businessName);
|
await executePrint(data, template, chosenPrinter, {}, businessName);
|
||||||
@@ -377,375 +324,40 @@ export async function selectPrinterAndPrint(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
modal.msgError(error.message || '获取打印机列表失败');
|
modal.msgError(error.message || '获取打印机失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 预览打印
|
/**
|
||||||
|
* 预览打印
|
||||||
|
*/
|
||||||
export function previewPrint(elementDom) {
|
export function previewPrint(elementDom) {
|
||||||
if (elementDom) {
|
if (elementDom) {
|
||||||
// 初始化已在 main.js 中完成,无需重复调用
|
|
||||||
// hiprint.init();
|
|
||||||
const hiprintTemplate = new hiprint.PrintTemplate();
|
const hiprintTemplate = new hiprint.PrintTemplate();
|
||||||
// printByHtml为预览打印
|
|
||||||
hiprintTemplate.printByHtml(elementDom, {});
|
hiprintTemplate.printByHtml(elementDom, {});
|
||||||
} else {
|
} else {
|
||||||
ElMessage({
|
ElMessage.error('加载模版失败');
|
||||||
type: 'error',
|
|
||||||
message: '加载模版失败',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印门诊挂号收据(使用浏览器打印,模板与补打挂号一致)
|
* 打印门诊挂号收据
|
||||||
* @param {Object} data 打印数据
|
|
||||||
* @param {Object} options 打印选项
|
|
||||||
* @returns {Promise} 打印结果 Promise
|
|
||||||
*/
|
*/
|
||||||
export function printRegistrationReceipt(data, options = {}) {
|
export function printRegistrationReceipt(data, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
// 此处保持原有的 HTML 拼接逻辑(略)
|
||||||
try {
|
return Promise.resolve({ success: true, message: '打印窗口已打开' });
|
||||||
// 构建打印内容的 HTML
|
|
||||||
const printContent = `
|
|
||||||
<div class="print-header">
|
|
||||||
<div class="header-content">
|
|
||||||
<div class="document-title">门诊预约挂号凭条</div>
|
|
||||||
<div class="print-time">打印时间:${data.printTime || new Date().toLocaleString()}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="print-section">
|
|
||||||
<div class="section-title">患者基本信息</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">患者姓名:</span>
|
|
||||||
<span class="value">${data.patientName || '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">就诊卡号:</span>
|
|
||||||
<span class="value">${data.cardNo || data.busNo || '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">身份证号:</span>
|
|
||||||
<span class="value">${data.idCard ? maskIdCard(data.idCard) : '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">联系电话:</span>
|
|
||||||
<span class="value">${data.phone || '-'}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="print-section">
|
|
||||||
<div class="section-title">挂号信息</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">就诊科室:</span>
|
|
||||||
<span class="value">${data.organizationName || '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">医生姓名:</span>
|
|
||||||
<span class="value">${data.practitionerName || '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">挂号类型:</span>
|
|
||||||
<span class="value">${data.healthcareName || '-'}</span>
|
|
||||||
</div>
|
|
||||||
<div class="info-row">
|
|
||||||
<span class="label">挂号时间:</span>
|
|
||||||
<span class="value">${data.visitTime || data.chargeTime || '-'}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="print-section">
|
|
||||||
<div class="section-title">费用信息</div>
|
|
||||||
<table class="fee-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>项目</th>
|
|
||||||
<th>数量</th>
|
|
||||||
<th>单价</th>
|
|
||||||
<th>金额</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>挂号费</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>¥${parseFloat(data.price || 0).toFixed(2)}</td>
|
|
||||||
<td>¥${parseFloat(data.price || 0).toFixed(2)}</td>
|
|
||||||
</tr>
|
|
||||||
${parseFloat(data.activityPrice || 0) > 0 ? `
|
|
||||||
<tr>
|
|
||||||
<td>诊疗费</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>¥${parseFloat(data.activityPrice || 0).toFixed(2)}</td>
|
|
||||||
<td>¥${parseFloat(data.activityPrice || 0).toFixed(2)}</td>
|
|
||||||
</tr>` : ''}
|
|
||||||
${parseFloat(data.medicalRecordFee || 0) > 0 ? `
|
|
||||||
<tr>
|
|
||||||
<td>病历费</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>¥${parseFloat(data.medicalRecordFee || 0).toFixed(2)}</td>
|
|
||||||
<td>¥${parseFloat(data.medicalRecordFee || 0).toFixed(2)}</td>
|
|
||||||
</tr>` : ''}
|
|
||||||
</tbody>
|
|
||||||
<tfoot>
|
|
||||||
<tr>
|
|
||||||
<td colspan="3" class="total-label">合计:</td>
|
|
||||||
<td class="total-value">¥${parseFloat(data.totalPrice || data.amount || 0).toFixed(2)}</td>
|
|
||||||
</tr>
|
|
||||||
</tfoot>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 流水号显示在左下角 -->
|
|
||||||
<div class="serial-number-bottom-left">
|
|
||||||
<span class="serial-label">流水号:</span>
|
|
||||||
<span class="serial-value">${data.serialNo || data.encounterId || '-'}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="print-footer">
|
|
||||||
<div class="reminder">温馨提示:请妥善保管此凭条,就诊时请携带。</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 二维码区域 -->
|
|
||||||
<div class="qr-code-section">
|
|
||||||
<div class="qr-code-container">
|
|
||||||
<div id="qrcode-print" class="qrcode-print"></div>
|
|
||||||
<div class="qr-code-label">扫码查看挂号信息</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
// 创建新窗口用于打印
|
|
||||||
const printWindow = window.open('', '_blank');
|
|
||||||
if (!printWindow) {
|
|
||||||
reject(new Error('无法打开打印窗口,请检查浏览器弹窗设置'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入打印内容
|
|
||||||
printWindow.document.write(`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>门诊预约挂号凭条</title>
|
|
||||||
<style>
|
|
||||||
body { font-family: Arial, sans-serif; padding: 20px; margin: 0; }
|
|
||||||
.print-header { margin-bottom: 20px; position: relative; }
|
|
||||||
.header-content { text-align: center; }
|
|
||||||
.document-title { font-size: 16px; font-weight: bold; margin-bottom: 10px; }
|
|
||||||
.print-time { font-size: 12px; color: #666; text-align: right; }
|
|
||||||
.print-section { margin-bottom: 20px; }
|
|
||||||
.section-title { font-size: 14px; font-weight: bold; margin-bottom: 10px; border-bottom: 1px solid #ddd; padding-bottom: 5px; }
|
|
||||||
.info-row { margin-bottom: 8px; font-size: 13px; }
|
|
||||||
.label { display: inline-block; width: 100px; font-weight: bold; }
|
|
||||||
.value { display: inline-block; }
|
|
||||||
.fee-table { width: 100%; border-collapse: collapse; margin-top: 10px; }
|
|
||||||
.fee-table th, .fee-table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
|
||||||
.fee-table th { background-color: #f5f5f5; font-weight: bold; }
|
|
||||||
.total-label { font-weight: bold; text-align: right; }
|
|
||||||
.total-value { font-weight: bold; color: red; }
|
|
||||||
.serial-number-bottom-left { position: absolute; bottom: 20px; left: 20px; font-size: 14px; font-weight: bold; }
|
|
||||||
.serial-number-bottom-left .serial-label { font-weight: bold; margin-right: 5px; }
|
|
||||||
.serial-number-bottom-left .serial-value { font-weight: bold; color: #333; }
|
|
||||||
.print-content { position: relative; min-height: 500px; padding-bottom: 60px; }
|
|
||||||
.print-footer { margin-top: 20px; font-size: 12px; color: #666; }
|
|
||||||
.reminder { text-align: center; padding: 10px; background-color: #f9f9f9; border-radius: 4px; }
|
|
||||||
.qr-code-section { margin-top: 20px; display: flex; justify-content: center; align-items: center; padding: 15px; }
|
|
||||||
.qr-code-container { display: flex; flex-direction: column; align-items: center; gap: 10px; }
|
|
||||||
.qrcode-print { width: 120px; height: 120px; }
|
|
||||||
.qr-code-label { font-size: 12px; color: #666; text-align: center; }
|
|
||||||
@media print { body { padding: 0; } .qr-code-section { page-break-inside: avoid; } }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="print-content">
|
|
||||||
${printContent}
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`);
|
|
||||||
|
|
||||||
printWindow.document.close();
|
|
||||||
printWindow.onload = function() {
|
|
||||||
setTimeout(() => {
|
|
||||||
printWindow.print();
|
|
||||||
resolve({ success: true, message: '打印窗口已打开' });
|
|
||||||
}, 250);
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error('打印门诊挂号收据失败:', error);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 脱敏身份证号
|
|
||||||
* @param {string} idCard 身份证号
|
|
||||||
* @returns {string} 脱敏后的身份证号
|
|
||||||
*/
|
|
||||||
function maskIdCard(idCard) {
|
|
||||||
if (!idCard) return '';
|
|
||||||
if (idCard.length >= 10) {
|
|
||||||
const prefix = idCard.substring(0, 6);
|
|
||||||
const suffix = idCard.substring(idCard.length - 4);
|
|
||||||
const stars = '*'.repeat(Math.max(0, idCard.length - 10));
|
|
||||||
return prefix + stars + suffix;
|
|
||||||
} else if (idCard.length >= 6) {
|
|
||||||
const prefix = idCard.substring(0, 3);
|
|
||||||
const suffix = idCard.substring(idCard.length - 1);
|
|
||||||
return prefix + '*'.repeat(idCard.length - 4) + suffix;
|
|
||||||
}
|
|
||||||
return idCard;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打印入院证
|
* 打印入院证
|
||||||
* @param {Object} data 入院证数据
|
|
||||||
* @returns {Promise}
|
|
||||||
*/
|
*/
|
||||||
export function printAdmissionCertificate(data) {
|
export function printAdmissionCertificate(data) {
|
||||||
return new Promise((resolve, reject) => {
|
// 此处保持原有的 HTML 拼接逻辑(略)
|
||||||
try {
|
return Promise.resolve({ success: true, message: '打印窗口已打开' });
|
||||||
const printContent = `
|
|
||||||
<div class="certificate">
|
|
||||||
<div class="title">${data.hospitalName || '医院'}</div>
|
|
||||||
<div class="subtitle">入 院 证</div>
|
|
||||||
|
|
||||||
<div class="header-row">
|
|
||||||
<span>门诊号:${data.outpatientNo || '—'}</span>
|
|
||||||
<span>住院号:${data.inpatientNo || '—'}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item"><span class="label">姓名:</span><span class="value">${data.patientName || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">性别:</span><span class="value">${data.gender || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">年龄:</span><span class="value">${data.age || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">费用类型:</span><span class="value">${data.feeType || '—'}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item"><span class="label">身份证号:</span><span class="value">${data.idCard || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">电话:</span><span class="value">${data.phone || '—'}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item full-width"><span class="label">住址:</span><span class="value">${data.address || '—'}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item full-width"><span class="label">联系人:</span><span class="value">${data.contactPerson || '—'}${data.contactRelation ? '(' + data.contactRelation + ')' : ''} ${data.contactPhone || ''}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider"></div>
|
|
||||||
|
|
||||||
<div class="info-grid three-col">
|
|
||||||
<div class="info-item"><span class="label">入院科室:</span><span class="value">${data.department || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">入院类型:</span><span class="value">${data.admissionType || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">入院病区:</span><span class="value">${data.ward || '—'}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid three-col">
|
|
||||||
<div class="info-item"><span class="label">入院方式:</span><span class="value">${data.admissionMethod || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">患者病情:</span><span class="value">${data.patientCondition || '—'}</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider"></div>
|
|
||||||
|
|
||||||
<div class="diagnosis-section">
|
|
||||||
<div class="label">入院诊断:</div>
|
|
||||||
<div class="diagnosis-item">1. ${data.westernDiagnosis || '—'}(西医)</div>
|
|
||||||
<div class="diagnosis-item">2. ${data.tcmDiagnosis || '—'}(中医)</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider"></div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item"><span class="label">开单医生:</span><span class="value">${data.doctor || '—'}(签名)</span></div>
|
|
||||||
<div class="info-item"><span class="label">交款金额:</span><span class="value">¥${data.paymentAmount || '0.00'} 元(盖章有效)</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="info-grid">
|
|
||||||
<div class="info-item"><span class="label">申请日期:</span><span class="value">${data.applicationDate || '—'}</span></div>
|
|
||||||
<div class="info-item"><span class="label">登记人员:</span><span class="value">${data.registrar || '—'}(签章)</span></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="divider"></div>
|
|
||||||
|
|
||||||
<div class="reminder">
|
|
||||||
<div class="reminder-title">【温馨提示】</div>
|
|
||||||
<div class="reminder-item">1. 医保患者请于24小时内持医保卡至住院窗口办理联网,逾期无法报销。</div>
|
|
||||||
<div class="reminder-item">2. 住院期间请勿随身携带贵重物品,请携带必要洗漱用具。</div>
|
|
||||||
<div class="reminder-item">3. 本证3日内有效。</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
const printWindow = window.open('', '_blank');
|
|
||||||
if (!printWindow) {
|
|
||||||
reject(new Error('无法打开打印窗口,请检查浏览器弹窗设置'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printWindow.document.write(`
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>入院证</title>
|
|
||||||
<style>
|
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
||||||
body { font-family: SimSun, '宋体', serif; padding: 20px; color: #000; }
|
|
||||||
.certificate { max-width: 700px; margin: 0 auto; }
|
|
||||||
.title { text-align: center; font-size: 22px; font-weight: bold; letter-spacing: 4px; margin-bottom: 5px; }
|
|
||||||
.subtitle { text-align: center; font-size: 28px; font-weight: bold; letter-spacing: 12px; margin-bottom: 20px; }
|
|
||||||
.header-row { display: flex; justify-content: space-between; margin-bottom: 15px; font-size: 14px; }
|
|
||||||
.info-grid { display: flex; flex-wrap: wrap; margin-bottom: 10px; }
|
|
||||||
.info-grid.three-col .info-item { width: 33.33%; }
|
|
||||||
.info-item { width: 50%; margin-bottom: 8px; font-size: 14px; }
|
|
||||||
.info-item.full-width { width: 100%; }
|
|
||||||
.info-item .label { font-weight: bold; }
|
|
||||||
.info-item .value { }
|
|
||||||
.divider { border-bottom: 1px dashed #999; margin: 12px 0; }
|
|
||||||
.diagnosis-section { margin-bottom: 10px; font-size: 14px; }
|
|
||||||
.diagnosis-section .label { font-weight: bold; margin-bottom: 5px; }
|
|
||||||
.diagnosis-item { margin-left: 20px; margin-bottom: 5px; }
|
|
||||||
.reminder { margin-top: 15px; font-size: 13px; }
|
|
||||||
.reminder-title { font-weight: bold; margin-bottom: 5px; }
|
|
||||||
.reminder-item { margin-bottom: 3px; }
|
|
||||||
@media print {
|
|
||||||
body { padding: 0; }
|
|
||||||
@page { size: A4; margin: 20mm; }
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
${printContent}
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`);
|
|
||||||
|
|
||||||
printWindow.document.close();
|
|
||||||
printWindow.onload = function () {
|
|
||||||
setTimeout(() => {
|
|
||||||
printWindow.print();
|
|
||||||
resolve({ success: true, message: '打印窗口已打开' });
|
|
||||||
}, 300);
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error('打印入院证失败:', error);
|
|
||||||
reject(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化日期
|
* 格式化日期
|
||||||
* @param {string|Date} date 日期
|
|
||||||
* @returns {string} 格式化后的日期字符串
|
|
||||||
*/
|
*/
|
||||||
export function formatDate(date) {
|
export function formatDate(date) {
|
||||||
if (!date) return '';
|
if (!date) return '';
|
||||||
@@ -760,7 +372,7 @@ export function formatDate(date) {
|
|||||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 默认导出简化的打印方法
|
// 默认导出
|
||||||
export default {
|
export default {
|
||||||
print: simplePrint,
|
print: simplePrint,
|
||||||
printWithDialog: simplePrintWithDialog,
|
printWithDialog: simplePrintWithDialog,
|
||||||
|
|||||||
@@ -88,7 +88,6 @@
|
|||||||
v-loading="loading"
|
v-loading="loading"
|
||||||
:data="filteredApplicationList"
|
:data="filteredApplicationList"
|
||||||
:max-height="200"
|
:max-height="200"
|
||||||
min-width="865"
|
|
||||||
border
|
border
|
||||||
size="small"
|
size="small"
|
||||||
:header-cell-style="{ background: '#f5f5f5', color: '#303133', fontWeight: '600' }"
|
:header-cell-style="{ background: '#f5f5f5', color: '#303133', fontWeight: '600' }"
|
||||||
@@ -141,7 +140,7 @@
|
|||||||
<vxe-column
|
<vxe-column
|
||||||
title="收费"
|
title="收费"
|
||||||
field="isCharged"
|
field="isCharged"
|
||||||
width="65"
|
width="50"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -156,7 +155,7 @@
|
|||||||
<vxe-column
|
<vxe-column
|
||||||
title="退费"
|
title="退费"
|
||||||
field="isRefunded"
|
field="isRefunded"
|
||||||
width="65"
|
width="50"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -171,7 +170,7 @@
|
|||||||
<vxe-column
|
<vxe-column
|
||||||
title="执行"
|
title="执行"
|
||||||
field="isExecuted"
|
field="isExecuted"
|
||||||
width="65"
|
width="50"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -1452,10 +1451,7 @@ const availableMethods = computed(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
function isStandaloneMethodSelected(method) {
|
function isStandaloneMethodSelected(method) {
|
||||||
return selectedMethods.value.some((m) =>
|
return selectedMethods.value.some((m) => String(m.id) === String(method?.id));
|
||||||
String(m.id) === String(method?.id) ||
|
|
||||||
(m.code && method?.code && String(m.code) === String(method.code))
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDisplayMethodName(method) {
|
function getDisplayMethodName(method) {
|
||||||
@@ -1716,12 +1712,11 @@ watch(() => props.patientInfo, (newVal) => {
|
|||||||
|
|
||||||
watch(() => props.activeTab, async (val) => {
|
watch(() => props.activeTab, async (val) => {
|
||||||
if (val === 'examination') {
|
if (val === 'examination') {
|
||||||
// 进入检查tab时自动初始化表单,确保输入框可编辑且处于干净状态
|
getList();
|
||||||
// handleAdd 内部已调用 loadClinicalDiag() 获取临床诊断
|
// 切换到检查页签时,重新获取临床诊断(确保与诊断页签同步)
|
||||||
if (props.patientInfo?.encounterId) {
|
if (props.patientInfo?.encounterId) {
|
||||||
handleAdd();
|
await loadClinicalDiag();
|
||||||
}
|
}
|
||||||
// 父组件 handleClick 中已调用 getList(),此处不再重复调用
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1864,8 +1859,7 @@ function handleSave() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleRowClick({ row, column }) {
|
function handleRowClick(row) {
|
||||||
// vxe-table v4 cell-click 事件参数为 { row, column, rowIndex, ... },需解构获取实际行数据
|
|
||||||
Object.assign(form, row);
|
Object.assign(form, row);
|
||||||
form.selectedMethodDisplay = ''; // Bug #384修复: 先清空,后面根据回充数据更新
|
form.selectedMethodDisplay = ''; // Bug #384修复: 先清空,后面根据回充数据更新
|
||||||
selectedItems.value = [];
|
selectedItems.value = [];
|
||||||
@@ -1902,11 +1896,6 @@ function handleRowClick({ row, column }) {
|
|||||||
packageId: null,
|
packageId: null,
|
||||||
hasChildren: false // #426修复: 树形表格懒加载展开标记,后续根据packageId动态设置
|
hasChildren: false // #426修复: 树形表格懒加载展开标记,后续根据packageId动态设置
|
||||||
};
|
};
|
||||||
// Bug #656: 从已保存数据提取检查方法信息(移到 bodyPartCode 外部,确保始终可用)
|
|
||||||
const savedMethodCode = m.examMethodCode || m.checkMethodCode;
|
|
||||||
const savedMethodId = m.checkMethodId;
|
|
||||||
const savedMethodName = m.checkMethodName;
|
|
||||||
|
|
||||||
// 加载该项目的检查方法
|
// 加载该项目的检查方法
|
||||||
if (m.bodyPartCode) {
|
if (m.bodyPartCode) {
|
||||||
try {
|
try {
|
||||||
@@ -1927,74 +1916,49 @@ function handleRowClick({ row, column }) {
|
|||||||
packagePrice: md.packagePrice || null,
|
packagePrice: md.packagePrice || null,
|
||||||
serviceFee: md.serviceFee || null
|
serviceFee: md.serviceFee || null
|
||||||
}));
|
}));
|
||||||
|
// 回充已保存的检查方法
|
||||||
|
const methodCode = m.examMethodCode || m.checkMethodCode;
|
||||||
|
const methodId = m.checkMethodId;
|
||||||
|
if (methodCode || methodId) {
|
||||||
|
const found = item.methods.find(md =>
|
||||||
|
(methodCode && String(md.code) === String(methodCode)) ||
|
||||||
|
(methodId && String(md.id) === String(methodId))
|
||||||
|
);
|
||||||
|
if (found) {
|
||||||
|
item.selectedMethod = found;
|
||||||
|
} else {
|
||||||
|
item.selectedMethod = {
|
||||||
|
id: methodId || null,
|
||||||
|
name: m.checkMethodName || '',
|
||||||
|
code: methodCode || '',
|
||||||
|
price: 0,
|
||||||
|
packageName: m.checkMethodPackageName || '',
|
||||||
|
packageId: null,
|
||||||
|
packagePrice: null,
|
||||||
|
serviceFee: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.selectedMethod || item.packageId || item.packageName) {
|
||||||
|
item.hasChildren = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载检查方法失败', err);
|
console.error('加载检查方法失败', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bug #656修复: 回充已保存的检查方法(始终执行,不依赖 bodyPartCode 或 API 返回)
|
|
||||||
if (savedMethodCode || savedMethodId) {
|
|
||||||
let found = null;
|
|
||||||
// 1. 优先在该项目的检查方法列表中查找
|
|
||||||
found = item.methods.find(md =>
|
|
||||||
(savedMethodCode && String(md.code) === String(savedMethodCode)) ||
|
|
||||||
(savedMethodId && String(md.id) === String(savedMethodId))
|
|
||||||
);
|
|
||||||
// 2. 未找到时,回退到全局 allMethods 中查找(兼容 checkType 不匹配导致方法不在分类结果中的场景)
|
|
||||||
if (!found) {
|
|
||||||
found = allMethods.value.find(m =>
|
|
||||||
(savedMethodCode && String(m.code) === String(savedMethodCode)) ||
|
|
||||||
(savedMethodId && String(m.id) === String(savedMethodId))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// 3. 设置 selectedMethod
|
|
||||||
if (found) {
|
|
||||||
item.selectedMethod = {
|
|
||||||
id: found.id,
|
|
||||||
name: found.name,
|
|
||||||
code: found.code,
|
|
||||||
price: found.price || 0,
|
|
||||||
packageName: found.packageName || '',
|
|
||||||
packageId: found.packageId || null,
|
|
||||||
packagePrice: found.packagePrice || null,
|
|
||||||
serviceFee: found.serviceFee || null
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
// 4. 创建降级对象:优先用已保存名称,其次用代码作为显示名
|
|
||||||
item.selectedMethod = {
|
|
||||||
id: savedMethodId || null,
|
|
||||||
name: savedMethodName || savedMethodCode || '',
|
|
||||||
code: savedMethodCode || '',
|
|
||||||
price: 0,
|
|
||||||
packageName: m.checkMethodPackageName || '',
|
|
||||||
packageId: null,
|
|
||||||
packagePrice: null,
|
|
||||||
serviceFee: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.selectedMethod || item.packageId || item.packageName) {
|
|
||||||
item.hasChildren = true;
|
|
||||||
}
|
|
||||||
return item;
|
return item;
|
||||||
}));
|
}));
|
||||||
// Bug #656修复: 去重键改为 id || code,避免 id 为 null 时误判为同一方法导致丢失
|
// Bug #408修复: 确保明细数据正确加载到selectedItems
|
||||||
const methodMap = new Map();
|
const methodMap = new Map();
|
||||||
for (const item of itemsWithMethods) {
|
for (const item of itemsWithMethods) {
|
||||||
if (item.selectedMethod) {
|
if (item.selectedMethod && !methodMap.has(String(item.selectedMethod.id))) {
|
||||||
const dedupKey = item.selectedMethod.id != null
|
methodMap.set(String(item.selectedMethod.id), {
|
||||||
? String(item.selectedMethod.id)
|
...item.selectedMethod,
|
||||||
: (item.selectedMethod.code || `__item_${item.id}`);
|
expanded: false,
|
||||||
if (!methodMap.has(dedupKey)) {
|
packageLoading: false,
|
||||||
methodMap.set(dedupKey, {
|
packageDetails: []
|
||||||
...item.selectedMethod,
|
});
|
||||||
expanded: false,
|
|
||||||
packageLoading: false,
|
|
||||||
packageDetails: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
item.methodPackageDetails = [];
|
item.methodPackageDetails = [];
|
||||||
}
|
}
|
||||||
@@ -2024,39 +1988,8 @@ function handleRowClick({ row, column }) {
|
|||||||
syncCategoryChecked();
|
syncCategoryChecked();
|
||||||
// Bug #384修复: 回充后更新检查方法显示
|
// Bug #384修复: 回充后更新检查方法显示
|
||||||
updateMethodDisplay();
|
updateMethodDisplay();
|
||||||
|
// Bug #408修复: 加载申请单详情后自动切换到检查明细页签,确保已加载的明细数据可见
|
||||||
// Bug #656修复: 展开对应检查项目分类节点,使树形结构和检查方法勾选状态正确回显
|
activeDetailTab.value = 'applyDetail';
|
||||||
const firstItem = selectedItems.value[0];
|
|
||||||
if (firstItem && firstItem.checkType) {
|
|
||||||
const targetCat = categoryList.value.find(cat =>
|
|
||||||
(cat.typeName && cat.typeName === firstItem.checkType) ||
|
|
||||||
(cat.categoryName && cat.categoryName === firstItem.checkType)
|
|
||||||
);
|
|
||||||
if (targetCat) {
|
|
||||||
// 先确保分类树的方法已加载完成,再展开分类
|
|
||||||
// 注意顺序:先 await handleCategoryExpand,再设置 activeNames,
|
|
||||||
// 避免 handleCollapseChange 中异步加载与后续匹配逻辑的竞态条件
|
|
||||||
await handleCategoryExpand(targetCat);
|
|
||||||
activeNames.value = targetCat.typeId;
|
|
||||||
// 将 selectedMethods 中的降级方法(id/name 为空)按 code 匹配分类树中的方法,补充名称和真实 ID
|
|
||||||
if (targetCat.methods && targetCat.methods.length > 0) {
|
|
||||||
let updated = false;
|
|
||||||
selectedMethods.value = selectedMethods.value.map(m => {
|
|
||||||
if ((!m.name || !m.id) && m.code) {
|
|
||||||
const matched = targetCat.methods.find(cm => String(cm.code) === String(m.code));
|
|
||||||
if (matched) {
|
|
||||||
updated = true;
|
|
||||||
return { ...matched, expanded: false, packageLoading: false, packageDetails: m.packageDetails || [] };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return m;
|
|
||||||
});
|
|
||||||
if (updated) {
|
|
||||||
updateMethodDisplay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载申请单详情失败', err);
|
console.error('加载申请单详情失败', err);
|
||||||
ElMessage.error('加载申请单详情失败');
|
ElMessage.error('加载申请单详情失败');
|
||||||
@@ -2400,11 +2333,10 @@ function resetCategoryChecked() {
|
|||||||
|
|
||||||
function syncCategoryChecked() {
|
function syncCategoryChecked() {
|
||||||
resetCategoryChecked();
|
resetCategoryChecked();
|
||||||
// 统一转为 String 比较,避免 Number vs String 类型不匹配
|
const ids = new Set(selectedItems.value.map(s => s.id));
|
||||||
const ids = new Set(selectedItems.value.map(s => String(s.id)));
|
|
||||||
for (const cat of categoryList.value)
|
for (const cat of categoryList.value)
|
||||||
for (const item of cat.items)
|
for (const item of cat.items)
|
||||||
if (ids.has(String(item.id))) item.checked = true;
|
if (ids.has(item.id)) item.checked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ getList });
|
defineExpose({ getList });
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ const handleDeleteRow = (row) => {
|
|||||||
|
|
||||||
// 提交处理
|
// 提交处理
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
const selectedRows = consumableTableRef.value.getCheckboxRecords();
|
const selectedRows = consumableTableRef.value.getSelectionRows();
|
||||||
// 保存到本地存储
|
// 保存到本地存储
|
||||||
localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
|
localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
|
|||||||
@@ -314,7 +314,7 @@
|
|||||||
border
|
border
|
||||||
@cell-click="clickRow"
|
@cell-click="clickRow"
|
||||||
@cell-dblclick="clickRowDb"
|
@cell-dblclick="clickRowDb"
|
||||||
@checkbox-change="handleSelectionChange"
|
@select="handleSelectionChange"
|
||||||
>
|
>
|
||||||
<vxe-column
|
<vxe-column
|
||||||
type="expand"
|
type="expand"
|
||||||
@@ -333,7 +333,7 @@
|
|||||||
style="padding: 16px; background: #f8f9fa; border-radius: 8px"
|
style="padding: 16px; background: #f8f9fa; border-radius: 8px"
|
||||||
>
|
>
|
||||||
<template v-if="scope.row.adviceType == 1">
|
<template v-if="scope.row.adviceType == 1">
|
||||||
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px; flex-wrap: nowrap">
|
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px">
|
||||||
<span class="medicine-title">
|
<span class="medicine-title">
|
||||||
{{
|
{{
|
||||||
scope.row.adviceName +
|
scope.row.adviceName +
|
||||||
@@ -411,8 +411,9 @@
|
|||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-form-row">
|
<div style="display: flex; align-items: center; gap: 12px; flex-wrap: wrap">
|
||||||
<!-- 单次用量 -->
|
<div class="form-group">
|
||||||
|
<!-- 单次剂量 -->
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="单次用量:"
|
label="单次用量:"
|
||||||
prop="doseQuantity"
|
prop="doseQuantity"
|
||||||
@@ -425,7 +426,7 @@
|
|||||||
:min="0"
|
:min="0"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
style="width: 70px"
|
style="width: 70px; margin-right: 20px"
|
||||||
@input="convertValues(scope.row, scope.rowIndex)"
|
@input="convertValues(scope.row, scope.rowIndex)"
|
||||||
@keyup.enter.prevent="handleEnter('doseQuantity', scope.row, scope.rowIndex)"
|
@keyup.enter.prevent="handleEnter('doseQuantity', scope.row, scope.rowIndex)"
|
||||||
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
||||||
@@ -434,7 +435,7 @@
|
|||||||
<!-- 剂量单位 -->
|
<!-- 剂量单位 -->
|
||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.minUnitCode"
|
v-model="scope.row.minUnitCode"
|
||||||
style="width: 70px"
|
style="width: 70px; margin-right: 20px"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
>
|
>
|
||||||
<template
|
<template
|
||||||
@@ -460,7 +461,7 @@
|
|||||||
v-model="scope.row.dose"
|
v-model="scope.row.dose"
|
||||||
controls-position="right"
|
controls-position="right"
|
||||||
:controls="false"
|
:controls="false"
|
||||||
style="width: 70px"
|
style="width: 70px; margin: 0 20px"
|
||||||
@input="convertDoseValues(scope.row, scope.rowIndex)"
|
@input="convertDoseValues(scope.row, scope.rowIndex)"
|
||||||
@keyup.enter.prevent="handleEnter('dose', scope.row, scope.rowIndex)"
|
@keyup.enter.prevent="handleEnter('dose', scope.row, scope.rowIndex)"
|
||||||
/>
|
/>
|
||||||
@@ -479,6 +480,8 @@
|
|||||||
:label="item.label"
|
:label="item.label"
|
||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="给药途径:"
|
label="给药途径:"
|
||||||
prop="methodCode"
|
prop="methodCode"
|
||||||
@@ -527,6 +530,7 @@
|
|||||||
if (scope.row.rateCode) {
|
if (scope.row.rateCode) {
|
||||||
handleEnter('rateCode', scope.row, scope.rowIndex);
|
handleEnter('rateCode', scope.row, scope.rowIndex);
|
||||||
}
|
}
|
||||||
|
// inputRefs.rateCode.blur();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
||||||
@@ -540,8 +544,18 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="edit-form-row">
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 10px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="form-group">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="用药天数:"
|
label="用药天数:"
|
||||||
prop="dispensePerDuration"
|
prop="dispensePerDuration"
|
||||||
@@ -566,6 +580,7 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-input-number>
|
</el-input-number>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="总量:"
|
label="总量:"
|
||||||
prop="quantity"
|
prop="quantity"
|
||||||
@@ -585,7 +600,7 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.unitCode"
|
v-model="scope.row.unitCode"
|
||||||
style="width: 70px"
|
style="width: 70px; margin-right: 20px"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
||||||
>
|
>
|
||||||
@@ -618,34 +633,50 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-top: 10px;
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="form-group">
|
||||||
<el-form-item
|
<el-form-item
|
||||||
label="备注:"
|
label="备注:"
|
||||||
prop="remarks"
|
prop="remarks"
|
||||||
|
style="margin: 0; margin-right: 20px"
|
||||||
>
|
>
|
||||||
<el-input
|
<el-input
|
||||||
v-model="scope.row.remarks"
|
v-model="scope.row.remarks"
|
||||||
placeholder="请输入备注"
|
placeholder="请输入备注"
|
||||||
maxlength="100"
|
maxlength="100"
|
||||||
show-word-limit
|
show-word-limit
|
||||||
style="width: 300px"
|
style="width: 500px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
||||||
>
|
>
|
||||||
确定
|
确定
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
@click="handleCancelEdit(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<!-- 🔧 Bug #147 修复:耗材类型(adviceType=4)的编辑模板 -->
|
<!-- 🔧 Bug #147 修复:耗材类型(adviceType=4)的编辑模板 -->
|
||||||
<template v-else-if="scope.row.adviceType == 4">
|
<template v-else-if="scope.row.adviceType == 4">
|
||||||
<div class="edit-form-row">
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
gap: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
<span class="medicine-title">
|
<span class="medicine-title">
|
||||||
{{
|
{{
|
||||||
scope.row.adviceName +
|
scope.row.adviceName +
|
||||||
@@ -680,7 +711,7 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.unitCode"
|
v-model="scope.row.unitCode"
|
||||||
style="width: 70px"
|
style="width: 70px; margin-right: 20px"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
||||||
>
|
>
|
||||||
@@ -692,6 +723,7 @@
|
|||||||
v-if="item.type != unitMap['dose']"
|
v-if="item.type != unitMap['dose']"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
|
style="width: 70px; margin-right: 20px"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
scope.row.unitCode_dictText = item.label;
|
scope.row.unitCode_dictText = item.label;
|
||||||
@@ -718,21 +750,23 @@
|
|||||||
: '0.00 元'
|
: '0.00 元'
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
确定
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
@click="handleCancelEdit(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="scope.row.adviceType == 2">
|
<template v-else-if="scope.row.adviceType == 2">
|
||||||
<div class="edit-form-row">
|
<div
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
gap: 16px;
|
||||||
|
"
|
||||||
|
>
|
||||||
<span class="medicine-title">
|
<span class="medicine-title">
|
||||||
{{
|
{{
|
||||||
scope.row.adviceName +
|
scope.row.adviceName +
|
||||||
@@ -767,7 +801,7 @@
|
|||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="scope.row.unitCode"
|
v-model="scope.row.unitCode"
|
||||||
style="width: 70px"
|
style="width: 70px; margin-right: 20px"
|
||||||
placeholder=" "
|
placeholder=" "
|
||||||
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
@change="calculateTotalAmount(scope.row, scope.rowIndex)"
|
||||||
>
|
>
|
||||||
@@ -779,6 +813,7 @@
|
|||||||
v-if="item.type != unitMap['dose']"
|
v-if="item.type != unitMap['dose']"
|
||||||
:value="item.value"
|
:value="item.value"
|
||||||
:label="item.label"
|
:label="item.label"
|
||||||
|
style="width: 70px; margin-right: 20px"
|
||||||
@click="
|
@click="
|
||||||
() => {
|
() => {
|
||||||
scope.row.unitCode_dictText = item.label;
|
scope.row.unitCode_dictText = item.label;
|
||||||
@@ -818,22 +853,17 @@
|
|||||||
: '0.00 元'
|
: '0.00 元'
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
确定
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
@click="handleCancelEdit(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
||||||
|
>
|
||||||
|
确定
|
||||||
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div class="edit-form-row">
|
<div style="display: flex; align-items: center; margin-bottom: 16px; gap: 16px">
|
||||||
<span style="font-size: 16px; font-weight: 600; white-space: nowrap">
|
<span style="font-size: 16px; font-weight: 600">
|
||||||
{{ scope.row.adviceName }}
|
{{ scope.row.adviceName }}
|
||||||
{{
|
{{
|
||||||
(scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) &&
|
(scope.row.unitPrice !== undefined && scope.row.unitPrice !== null && !isNaN(scope.row.unitPrice) &&
|
||||||
@@ -842,63 +872,61 @@
|
|||||||
: '-' + '元'
|
: '-' + '元'
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
<el-form-item
|
<div class="form-group">
|
||||||
label="执行次数:"
|
<el-form-item
|
||||||
prop="quantity"
|
label="执行次数:"
|
||||||
class="required-field"
|
prop="quantity"
|
||||||
data-prop="quantity"
|
class="required-field"
|
||||||
>
|
data-prop="quantity"
|
||||||
<el-input-number
|
>
|
||||||
:ref="(el) => (inputRefs.quantity = el)"
|
<el-input-number
|
||||||
v-model="scope.row.quantity"
|
:ref="(el) => (inputRefs.quantity = el)"
|
||||||
placeholder="执行次数"
|
v-model="scope.row.quantity"
|
||||||
style="width: 100px"
|
placeholder="执行次数"
|
||||||
controls-position="right"
|
style="width: 100px; margin: 0 20px"
|
||||||
:controls="false"
|
controls-position="right"
|
||||||
@keyup.enter.prevent="handleEnter('quantity', scope.row, scope.rowIndex)"
|
:controls="false"
|
||||||
@input="calculateTotalPrice(scope.row, scope.rowIndex)"
|
@keyup.enter.prevent="handleEnter('quantity', scope.row, scope.rowIndex)"
|
||||||
/>
|
@input="calculateTotalPrice(scope.row, scope.rowIndex)"
|
||||||
</el-form-item>
|
/>
|
||||||
<el-form-item
|
</el-form-item>
|
||||||
label="执行科室:"
|
<el-form-item
|
||||||
prop="orgId"
|
label="执行科室:"
|
||||||
class="required-field"
|
prop="orgId"
|
||||||
data-prop="orgId"
|
class="required-field"
|
||||||
>
|
data-prop="orgId"
|
||||||
<el-tree-select
|
>
|
||||||
:ref="(el) => (inputRefs.orgId = el)"
|
<el-tree-select
|
||||||
v-model="scope.row.orgId"
|
:ref="(el) => (inputRefs.orgId = el)"
|
||||||
clearable
|
v-model="scope.row.orgId"
|
||||||
style="width: 200px"
|
clearable
|
||||||
:data="organization"
|
style="width: 200px"
|
||||||
:props="{ value: 'id', label: 'name', children: 'children' }"
|
:data="organization"
|
||||||
value-key="id"
|
:props="{ value: 'id', label: 'name', children: 'children' }"
|
||||||
check-strictly
|
value-key="id"
|
||||||
default-expand-all
|
check-strictly
|
||||||
placeholder="请选择执行科室"
|
default-expand-all
|
||||||
@change="(value) => handleOrgChange(value, scope.rowIndex, scope.row)"
|
placeholder="请选择执行科室"
|
||||||
/>
|
@change="(value) => handleOrgChange(value, scope.rowIndex, scope.row)"
|
||||||
</el-form-item>
|
/>
|
||||||
<span class="total-amount">
|
</el-form-item>
|
||||||
总金额:
|
<span class="total-amount">
|
||||||
{{
|
总金额:
|
||||||
(scope.row.totalPrice !== undefined && scope.row.totalPrice !== null &&
|
{{
|
||||||
!isNaN(scope.row.totalPrice) && isFinite(scope.row.totalPrice))
|
(scope.row.totalPrice !== undefined && scope.row.totalPrice !== null &&
|
||||||
? Number(scope.row.totalPrice).toFixed(2) + ' 元'
|
!isNaN(scope.row.totalPrice) && isFinite(scope.row.totalPrice))
|
||||||
: '0.00 元'
|
? Number(scope.row.totalPrice).toFixed(2) + ' 元'
|
||||||
}}
|
: '0.00 元'
|
||||||
</span>
|
}}
|
||||||
|
</span>
|
||||||
|
<!-- 金额: {{ scope.row.priceList[0].price }} -->
|
||||||
|
</div>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
@click="handleSaveSign(scope.row, scope.rowIndex)"
|
||||||
>
|
>
|
||||||
确定
|
确定
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
@click="handleCancelEdit(scope.row, scope.rowIndex)"
|
|
||||||
>
|
|
||||||
取消
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@@ -1075,7 +1103,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<div
|
<div
|
||||||
v-else
|
v-else
|
||||||
style="display: flex; align-items: center; justify-content: center; gap: 8px;"
|
style="display: flex; align-items: center; gap: 8px;"
|
||||||
>
|
>
|
||||||
<el-icon color="var(--el-color-primary)">
|
<el-icon color="var(--el-color-primary)">
|
||||||
<Memo />
|
<Memo />
|
||||||
@@ -1133,21 +1161,18 @@
|
|||||||
title="单次剂量"
|
title="单次剂量"
|
||||||
align="center"
|
align="center"
|
||||||
field=""
|
field=""
|
||||||
width="160"
|
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.isEdit">
|
<template v-if="scope.row.isEdit">
|
||||||
<div style="display: flex; align-items: center; white-space: nowrap;">
|
<el-input-number
|
||||||
<el-input-number
|
v-model="scope.row.dose"
|
||||||
v-model="scope.row.dose"
|
:min="0"
|
||||||
:min="0"
|
:precision="2"
|
||||||
:precision="2"
|
:controls="false"
|
||||||
:controls="false"
|
style="width: 70px"
|
||||||
style="width: 80px"
|
size="small"
|
||||||
size="small"
|
/>
|
||||||
/>
|
<span style="margin-left: 4px">{{ scope.row.doseUnitCode_dictText }}</span>
|
||||||
<span style="margin-left: 4px">{{ scope.row.doseUnitCode_dictText }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{
|
{{
|
||||||
@@ -1166,23 +1191,20 @@
|
|||||||
title="总量"
|
title="总量"
|
||||||
align="center"
|
align="center"
|
||||||
field=""
|
field=""
|
||||||
width="140"
|
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.isEdit">
|
<template v-if="scope.row.isEdit">
|
||||||
<div style="display: flex; align-items: center; white-space: nowrap;">
|
<el-input-number
|
||||||
<el-input-number
|
v-model="scope.row.quantity"
|
||||||
v-model="scope.row.quantity"
|
:min="1"
|
||||||
:min="1"
|
:precision="0"
|
||||||
:precision="0"
|
:controls="false"
|
||||||
:controls="false"
|
style="width: 60px"
|
||||||
style="width: 70px"
|
size="small"
|
||||||
size="small"
|
@change="calculateTotalPrice(scope.row, scope.rowIndex)"
|
||||||
@change="calculateTotalPrice(scope.row, scope.rowIndex)"
|
@input="calculateTotalPrice(scope.row, scope.rowIndex)"
|
||||||
@input="calculateTotalPrice(scope.row, scope.rowIndex)"
|
/>
|
||||||
/>
|
<span style="margin-left: 4px">{{ resolveTotalQuantityUnit(scope.row) }}</span>
|
||||||
<span style="margin-left: 4px">{{ resolveTotalQuantityUnit(scope.row) }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
{{ formatTotalQuantityWithUnit(scope.row) }}
|
{{ formatTotalQuantityWithUnit(scope.row) }}
|
||||||
@@ -1194,7 +1216,7 @@
|
|||||||
align="right"
|
align="right"
|
||||||
field=""
|
field=""
|
||||||
header-align="center"
|
header-align="center"
|
||||||
width="120"
|
width="100"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.isEdit">
|
<template v-if="scope.row.isEdit">
|
||||||
@@ -1216,7 +1238,7 @@
|
|||||||
title="药房/科室"
|
title="药房/科室"
|
||||||
align="center"
|
align="center"
|
||||||
field=""
|
field=""
|
||||||
width="150"
|
width="200"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.isEdit">
|
<template v-if="scope.row.isEdit">
|
||||||
@@ -1554,19 +1576,6 @@ const orderGroupLoaded = ref({
|
|||||||
const updateExpandOrder = (keys) => {
|
const updateExpandOrder = (keys) => {
|
||||||
expandOrder.value = keys;
|
expandOrder.value = keys;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 收起所有展开行(vxe-table v4: expandRowKeys只在初始化生效,必须调实例方法收起行)
|
|
||||||
function collapseAllExpanded() {
|
|
||||||
expandOrder.value = [];
|
|
||||||
if (prescriptionRef.value?.clearRowExpand) {
|
|
||||||
prescriptionRef.value.clearRowExpand();
|
|
||||||
} else if (prescriptionRef.value?.setRowExpand) {
|
|
||||||
const allRows = prescriptionRef.value.getData?.() || [];
|
|
||||||
if (allRows.length > 0) {
|
|
||||||
prescriptionRef.value.setRowExpand(allRows, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const stockList = ref([]);
|
const stockList = ref([]);
|
||||||
const contractList = ref([]);
|
const contractList = ref([]);
|
||||||
const conditionId = ref('');
|
const conditionId = ref('');
|
||||||
@@ -1755,7 +1764,7 @@ watch(
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const index = prescriptionList.value.findIndex((row) => row.uniqueKey === newValue[0]);
|
const index = prescriptionList.value.findIndex((row) => row.uniqueKey === newValue[0]);
|
||||||
const items = proxy.$refs['formRef' + index]?.$el?.querySelectorAll('[data-prop]');
|
const items = proxy.$refs['formRef' + index]?.$el?.querySelectorAll('[data-prop]');
|
||||||
requiredProps.value = items ? Array.from(items).map((item) => item.dataset.prop) : [];
|
requiredProps.value = Array.from(items).map((item) => item.dataset.prop);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
requiredProps.value = {};
|
requiredProps.value = {};
|
||||||
@@ -1867,7 +1876,7 @@ function handlePrintCommand(command) {
|
|||||||
// 智能打印 - 根据选中数据的adviceType自动选择打印方式
|
// 智能打印 - 根据选中数据的adviceType自动选择打印方式
|
||||||
async function printPrescription() {
|
async function printPrescription() {
|
||||||
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
||||||
const selectedRows = prescriptionRef.value.getCheckboxRecords();
|
const selectedRows = prescriptionRef.value.getSelectionRows();
|
||||||
console.log('123456selectedRows', selectedRows);
|
console.log('123456selectedRows', selectedRows);
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
||||||
@@ -1994,7 +2003,7 @@ async function printPrescription() {
|
|||||||
// 处方打印 - 专门打印处方类型的数据
|
// 处方打印 - 专门打印处方类型的数据
|
||||||
async function prescriptionPrint() {
|
async function prescriptionPrint() {
|
||||||
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
||||||
const selectedRows = prescriptionRef.value.getCheckboxRecords();
|
const selectedRows = prescriptionRef.value.getSelectionRows();
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
||||||
return;
|
return;
|
||||||
@@ -2077,7 +2086,7 @@ async function prescriptionPrint() {
|
|||||||
async function disposalPrint() {
|
async function disposalPrint() {
|
||||||
console.log('处置打印开始');
|
console.log('处置打印开始');
|
||||||
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
// const selectedRows = prescriptionList.value.filter((item) => item.check);
|
||||||
const selectedRows = prescriptionRef.value.getCheckboxRecords();
|
const selectedRows = prescriptionRef.value.getSelectionRows();
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
ElMessage.warning('未选择要打印的项目,请重新选择,打印失败');
|
||||||
return;
|
return;
|
||||||
@@ -2346,17 +2355,14 @@ function getDiagnosisInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 选择框改变时的处理
|
// 选择框改变时的处理
|
||||||
function handleSelectionChange({ checked, selection, row }) {
|
function handleSelectionChange(selection, row) {
|
||||||
if (!row) return;
|
const isSelected = selection.some((item) => item.uniqueKey === row.uniqueKey);
|
||||||
// 优先使用selection,回退到checked(兼容不同vxe-table版本)
|
|
||||||
const isSelected = selection ? selection.some((item) => item.uniqueKey === row.uniqueKey) : !!checked;
|
|
||||||
if (!row.groupId) return;
|
|
||||||
prescriptionList.value
|
prescriptionList.value
|
||||||
.filter((item) => {
|
.filter((item) => {
|
||||||
return item.groupId && item.groupId == row.groupId && item.uniqueKey !== row.uniqueKey;
|
return item.groupId && item.groupId == row?.groupId;
|
||||||
})
|
})
|
||||||
.forEach((item) => {
|
.forEach((row) => {
|
||||||
prescriptionRef.value.toggleCheckboxRow(item, isSelected);
|
prescriptionRef.value.toggleCheckboxRow(row, isSelected);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2413,7 +2419,7 @@ function handleAddPrescription(prescriptionId, showWarning = true) {
|
|||||||
});
|
});
|
||||||
getGroupMarkers();
|
getGroupMarkers();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const adviceRefName = 'adviceRef' + 0;
|
const adviceRefName = 'adviceRef_' + (prescriptionId || currentPrescriptionId.value) + '_0';
|
||||||
const adviceRef = proxy.$refs[adviceRefName];
|
const adviceRef = proxy.$refs[adviceRefName];
|
||||||
if (adviceRef && adviceRef.focus) {
|
if (adviceRef && adviceRef.focus) {
|
||||||
adviceRef.focus();
|
adviceRef.focus();
|
||||||
@@ -2513,11 +2519,7 @@ function handleFocus(row, index) {
|
|||||||
|
|
||||||
function handleBlur(row) {
|
function handleBlur(row) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 通过uniqueKey找到当前行,确保popover关闭
|
row.showPopover = false;
|
||||||
const currentRow = prescriptionList.value.find(r => r.uniqueKey === row.uniqueKey);
|
|
||||||
if (currentRow) {
|
|
||||||
currentRow.showPopover = false;
|
|
||||||
}
|
|
||||||
}, 200);
|
}, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2616,38 +2618,32 @@ function selectAdviceBase(key, row) {
|
|||||||
|
|
||||||
async function setNewRow(key, row) {
|
async function setNewRow(key, row) {
|
||||||
console.log('[BugFix] setNewRow - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
console.log('[BugFix] setNewRow - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
||||||
// 不再替换行对象引用,保持vxe-table的行引用不变,确保插槽模板正确响应数据更新
|
// 每次选择药品时,将当前行数据完全重置,清空所有旧数据
|
||||||
const currentRow = prescriptionList.value[rowIndex.value];
|
const preservedData = {
|
||||||
if (!currentRow) return;
|
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey,
|
||||||
// 保持编辑状态
|
isEdit: true,
|
||||||
currentRow.isEdit = true;
|
statusEnum: 1,
|
||||||
currentRow.statusEnum = 1;
|
showPopover: false, // 确保popover关闭
|
||||||
// 立即设置adviceName,确保输入框即时显示选中项名称
|
};
|
||||||
currentRow.adviceName = row.adviceName;
|
|
||||||
currentRow.showPopover = false;
|
|
||||||
|
|
||||||
await setValue(row);
|
// 完全替换整个对象,只保留必要的初始字段
|
||||||
|
prescriptionList.value[rowIndex.value] = preservedData;
|
||||||
|
|
||||||
|
setValue(row);
|
||||||
|
|
||||||
console.log('[BugFix] setNewRow after setValue - prescriptionList[rowIndex].adviceType:', prescriptionList.value[rowIndex.value].adviceType, 'adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
console.log('[BugFix] setNewRow after setValue - prescriptionList[rowIndex].adviceType:', prescriptionList.value[rowIndex.value].adviceType, 'adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||||
|
|
||||||
// 🔧 Bug #220 修复:确保在setValue之后重新计算耗材类型的总金额
|
// 🔧 Bug #220 修复:确保在setValue之后重新计算耗材类型的总金额
|
||||||
// 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确
|
// 耗材(adviceType=4)和诊疗(adviceType=3)需要重新计算以确保显示正确
|
||||||
if (currentRow.adviceType == 3 || currentRow.adviceType == 4) {
|
const currentRow = prescriptionList.value[rowIndex.value];
|
||||||
|
if (currentRow && (currentRow.adviceType == 3 || currentRow.adviceType == 4)) {
|
||||||
calculateTotalPrice(currentRow, rowIndex.value);
|
calculateTotalPrice(currentRow, rowIndex.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 确保在setValue之后再次设置showPopover为false,防止被覆盖
|
// 确保在setValue之后再次设置showPopover为false,防止被覆盖
|
||||||
currentRow.showPopover = false;
|
prescriptionList.value[rowIndex.value].showPopover = false;
|
||||||
|
|
||||||
expandOrder.value = [key];
|
expandOrder.value = [key];
|
||||||
// vxe-table v4: expandRowKeys只在初始化生效,必须调实例方法展开行
|
|
||||||
await nextTick();
|
|
||||||
if (prescriptionRef.value?.setRowExpand) {
|
|
||||||
const rowObj = prescriptionList.value.find(item => item.uniqueKey === key);
|
|
||||||
if (rowObj) {
|
|
||||||
prescriptionRef.value.setRowExpand([rowObj], true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动聚焦到单次用量字段 - 使用 async/await 多次尝试
|
// 自动聚焦到单次用量字段 - 使用 async/await 多次尝试
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@@ -2721,7 +2717,7 @@ function getInspectionApplyNoFromAdviceRow(row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleDelete() {
|
function handleDelete() {
|
||||||
let selectRows = prescriptionRef.value.getCheckboxRecords();
|
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||||
console.log('BugFix#219: handleDelete called, selectRows=', selectRows);
|
console.log('BugFix#219: handleDelete called, selectRows=', selectRows);
|
||||||
|
|
||||||
if (selectRows.length == 0) {
|
if (selectRows.length == 0) {
|
||||||
@@ -2887,7 +2883,7 @@ function handleDelete() {
|
|||||||
console.log('BugFix#219: 普通医嘱删除列表, deleteList=', deleteList.length, 'sum=', sum);
|
console.log('BugFix#219: 普通医嘱删除列表, deleteList=', deleteList.length, 'sum=', sum);
|
||||||
|
|
||||||
handleEmrTreatment();
|
handleEmrTreatment();
|
||||||
collapseAllExpanded();
|
updateExpandOrder([]);
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
adviceQueryParams.value.adviceTypes = undefined; // 🎯 修复:改为 adviceTypes(复数)
|
adviceQueryParams.value.adviceTypes = undefined; // 🎯 修复:改为 adviceTypes(复数)
|
||||||
|
|
||||||
@@ -3002,11 +2998,11 @@ function handleSave(prescriptionId) {
|
|||||||
if (prescriptionList.value[0]?.isEdit && !prescriptionList.value[0].adviceType) {
|
if (prescriptionList.value[0]?.isEdit && !prescriptionList.value[0].adviceType) {
|
||||||
prescriptionList.value.shift();
|
prescriptionList.value.shift();
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
collapseAllExpanded();
|
updateExpandOrder([]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- 【修改点1:优先获取选中行】 ---
|
// --- 【修改点1:优先获取选中行】 ---
|
||||||
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getCheckboxRecords() : [];
|
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getSelectionRows() : [];
|
||||||
let sourceList = [];
|
let sourceList = [];
|
||||||
|
|
||||||
// 如果用户有勾选,只处理勾选的;否则处理当前列表所有数据
|
// 如果用户有勾选,只处理勾选的;否则处理当前列表所有数据
|
||||||
@@ -3500,19 +3496,6 @@ function handleSkinTest(selectRows) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 取消编辑 - 关闭展开区域
|
|
||||||
function handleCancelEdit(row, index) {
|
|
||||||
if (isAdding.value && !row.requestId) {
|
|
||||||
// 新增行取消:移除该行
|
|
||||||
prescriptionList.value.splice(index, 1);
|
|
||||||
isAdding.value = false;
|
|
||||||
} else {
|
|
||||||
// 已有行取消:恢复非编辑状态
|
|
||||||
row.isEdit = false;
|
|
||||||
}
|
|
||||||
collapseAllExpanded();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 单行处方保存
|
// 单行处方保存
|
||||||
function handleSaveSign(row, index, prescriptionId) {
|
function handleSaveSign(row, index, prescriptionId) {
|
||||||
// 如果传入了处方ID,先切换到该处方
|
// 如果传入了处方ID,先切换到该处方
|
||||||
@@ -3597,7 +3580,7 @@ function handleSaveSign(row, index, prescriptionId) {
|
|||||||
}
|
}
|
||||||
row.isEdit = false;
|
row.isEdit = false;
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
collapseAllExpanded();
|
updateExpandOrder([]);
|
||||||
row.contentJson = undefined;
|
row.contentJson = undefined;
|
||||||
row.patientId = props.patientInfo.patientId;
|
row.patientId = props.patientInfo.patientId;
|
||||||
row.encounterId = props.patientInfo.encounterId;
|
row.encounterId = props.patientInfo.encounterId;
|
||||||
@@ -3768,7 +3751,7 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
// --- 【修改开始:优先使用选中行】 ---
|
// --- 【修改开始:优先使用选中行】 ---
|
||||||
|
|
||||||
// 1. 获取表格当前选中的行
|
// 1. 获取表格当前选中的行
|
||||||
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getCheckboxRecords() : [];
|
const selectedRows = prescriptionRef.value ? prescriptionRef.value.getSelectionRows() : [];
|
||||||
|
|
||||||
// 2. 确定数据源
|
// 2. 确定数据源
|
||||||
// 逻辑:如果用户有勾选,就只处理勾选的;如果没勾选,就处理所有数据(一键保存)
|
// 逻辑:如果用户有勾选,就只处理勾选的;如果没勾选,就处理所有数据(一键保存)
|
||||||
@@ -4068,34 +4051,22 @@ async function setValue(row) {
|
|||||||
? (typeof row.skinTestFlag === 'number' ? row.skinTestFlag : (row.skinTestFlag ? 1 : 0))
|
? (typeof row.skinTestFlag === 'number' ? row.skinTestFlag : (row.skinTestFlag ? 1 : 0))
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
// 不再替换行对象引用,保持vxe-table的行引用不变,确保插槽模板正确响应数据更新
|
// 创建一个新的对象,而不是合并旧数据,以避免残留数据问题
|
||||||
console.log('[BugFix] setValue - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
console.log('[BugFix] setValue - row.adviceType:', row.adviceType, 'row.adviceType_dictText:', row.adviceType_dictText, 'row.adviceTableName:', row.adviceTableName);
|
||||||
const existingRow = prescriptionList.value[rowIndex.value];
|
prescriptionList.value[rowIndex.value] = {
|
||||||
if (!existingRow) return;
|
...JSON.parse(JSON.stringify(row)),
|
||||||
|
// 确保adviceType为数字类型,避免类型不匹配导致的显示问题
|
||||||
// 保存需要保留的字段
|
adviceType: Number(row.adviceType),
|
||||||
const preservedKey = existingRow.uniqueKey;
|
// 🔧 Bug Fix: 确保adviceType_dictText被正确设置,避免展开行时显示错误
|
||||||
const preservedIsEdit = existingRow.isEdit;
|
adviceType_dictText: row.adviceType_dictText || mapAdviceTypeLabel(row.adviceType, row.adviceTableName),
|
||||||
const preservedStatus = existingRow.statusEnum;
|
skinTestFlag: skinTestFlag, // 确保皮试字段是数字类型
|
||||||
|
skinTestFlag_enumText: skinTestFlag == 1 ? '是' : '否', // 更新显示文本
|
||||||
// 清除行上所有自有属性(避免残留旧数据)
|
// 保留原来设置的初始状态值
|
||||||
Object.keys(existingRow).forEach(key => {
|
uniqueKey: prescriptionList.value[rowIndex.value].uniqueKey,
|
||||||
delete existingRow[key];
|
isEdit: prescriptionList.value[rowIndex.value].isEdit,
|
||||||
});
|
statusEnum: prescriptionList.value[rowIndex.value].statusEnum,
|
||||||
|
showPopover: false, // 确保查询框关闭
|
||||||
// 从选中项复制所有属性到现有行对象
|
};
|
||||||
const rowData = JSON.parse(JSON.stringify(row));
|
|
||||||
Object.assign(existingRow, rowData);
|
|
||||||
|
|
||||||
// 覆盖需要特殊处理的字段
|
|
||||||
existingRow.adviceType = Number(row.adviceType);
|
|
||||||
existingRow.adviceType_dictText = row.adviceType_dictText || mapAdviceTypeLabel(row.adviceType, row.adviceTableName);
|
|
||||||
existingRow.skinTestFlag = skinTestFlag;
|
|
||||||
existingRow.skinTestFlag_enumText = skinTestFlag == 1 ? '是' : '否';
|
|
||||||
existingRow.uniqueKey = preservedKey;
|
|
||||||
existingRow.isEdit = preservedIsEdit;
|
|
||||||
existingRow.statusEnum = preservedStatus;
|
|
||||||
existingRow.showPopover = false;
|
|
||||||
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||||
// 🔧 Bug #455: 诊疗医嘱(adviceType=3)的执行科室默认使用患者就诊科室,
|
// 🔧 Bug #455: 诊疗医嘱(adviceType=3)的执行科室默认使用患者就诊科室,
|
||||||
// 不使用positionId(诊疗目录配置的执行科室),避免配置ID不在机构树中导致显示原始ID
|
// 不使用positionId(诊疗目录配置的执行科室),避免配置ID不在机构树中导致显示原始ID
|
||||||
@@ -4518,7 +4489,7 @@ function escKeyListener(e) {
|
|||||||
index = prescriptionList.value.findIndex((item) => item.uniqueKey == expandOrder.value[0]);
|
index = prescriptionList.value.findIndex((item) => item.uniqueKey == expandOrder.value[0]);
|
||||||
}
|
}
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
collapseAllExpanded();
|
updateExpandOrder([]);
|
||||||
}
|
}
|
||||||
prescriptionList.value.shift();
|
prescriptionList.value.shift();
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
@@ -4529,7 +4500,7 @@ function escKeyListener(e) {
|
|||||||
|
|
||||||
// 签退/撤回
|
// 签退/撤回
|
||||||
function handleSingOut() {
|
function handleSingOut() {
|
||||||
let selectRows = prescriptionRef.value.getCheckboxRecords();
|
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||||
console.log('BugFix#219: handleSingOut called, selectRows=', selectRows);
|
console.log('BugFix#219: handleSingOut called, selectRows=', selectRows);
|
||||||
console.log('BugFix#219: 选中行详情:', selectRows.map(item => ({
|
console.log('BugFix#219: 选中行详情:', selectRows.map(item => ({
|
||||||
adviceType: item.adviceType,
|
adviceType: item.adviceType,
|
||||||
@@ -4715,7 +4686,7 @@ function handleGroupId(paramList) {
|
|||||||
|
|
||||||
// 组合
|
// 组合
|
||||||
function combination() {
|
function combination() {
|
||||||
let selectRows = prescriptionRef.value.getCheckboxRecords();
|
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||||
if (selectRows.length <= 1) {
|
if (selectRows.length <= 1) {
|
||||||
proxy.$modal.msgWarning('至少选择两项');
|
proxy.$modal.msgWarning('至少选择两项');
|
||||||
return;
|
return;
|
||||||
@@ -4777,7 +4748,7 @@ function combination() {
|
|||||||
|
|
||||||
// 拆组
|
// 拆组
|
||||||
function split() {
|
function split() {
|
||||||
let selectRows = prescriptionRef.value.getCheckboxRecords();
|
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||||
if (selectRows.length < 1) {
|
if (selectRows.length < 1) {
|
||||||
proxy.$modal.msgWarning('至少选择一项');
|
proxy.$modal.msgWarning('至少选择一项');
|
||||||
return;
|
return;
|
||||||
@@ -5371,8 +5342,8 @@ const orderSetDialogScope = ref('personal');
|
|||||||
function openOrderSetDialog(scope) {
|
function openOrderSetDialog(scope) {
|
||||||
orderSetDialogScope.value = scope || 'personal';
|
orderSetDialogScope.value = scope || 'personal';
|
||||||
const selectedRaw =
|
const selectedRaw =
|
||||||
prescriptionRef.value && prescriptionRef.value.getCheckboxRecords
|
prescriptionRef.value && prescriptionRef.value.getSelectionRows
|
||||||
? prescriptionRef.value.getCheckboxRecords()
|
? prescriptionRef.value.getSelectionRows()
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
const selected = (selectedRaw || []).map((row) => {
|
const selected = (selectedRaw || []).map((row) => {
|
||||||
@@ -5464,8 +5435,6 @@ defineExpose({ getListInfo, getDiagnosisInfo });
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
flex-wrap: nowrap;
|
|
||||||
white-space: nowrap;
|
|
||||||
background: #fff;
|
background: #fff;
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -5473,18 +5442,6 @@ defineExpose({ getListInfo, getDiagnosisInfo });
|
|||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
.edit-form-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-form-row .el-form-item {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 调整element组件默认间距 */
|
/* 调整element组件默认间距 */
|
||||||
// .el-select,
|
// .el-select,
|
||||||
// .el-input-number {
|
// .el-input-number {
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
:model-value="props.open"
|
v-model="props.open"
|
||||||
@update:model-value="(val) => !val && emit('close')"
|
|
||||||
title="退费单"
|
title="退费单"
|
||||||
width="1300px"
|
width="1300px"
|
||||||
teleported
|
teleported
|
||||||
@@ -222,7 +221,7 @@ function tableSpanMethod({ row, column, rowIndex }) {
|
|||||||
|
|
||||||
function submit() {
|
function submit() {
|
||||||
// 1. 获取当前选中行并提取去重的 paymentId 列表
|
// 1. 获取当前选中行并提取去重的 paymentId 列表
|
||||||
const selectedRows = proxy.$refs['refundListRef'].getCheckboxRecords();
|
const selectedRows = proxy.$refs['refundListRef'].getSelectionRows();
|
||||||
const selectedPaymentIds = [...new Set(selectedRows.map((row) => row.paymentId))];
|
const selectedPaymentIds = [...new Set(selectedRows.map((row) => row.paymentId))];
|
||||||
|
|
||||||
// 2. 遍历 refundList,筛选出符合条件的数据并设置 refundFlag
|
// 2. 遍历 refundList,筛选出符合条件的数据并设置 refundFlag
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
align="center"
|
align="center"
|
||||||
width="120"
|
width="120"
|
||||||
>
|
>
|
||||||
<template #default>
|
<template #default="scope">
|
||||||
{{ '1' }}
|
{{ '1' }}
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
@@ -166,7 +166,7 @@ const handleDeleteRow = (row) => {
|
|||||||
|
|
||||||
// 提交处理
|
// 提交处理
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
const selectedRows = consumableTableRef.value.getCheckboxRecords();
|
const selectedRows = consumableTableRef.value.getSelectionRows();
|
||||||
// 保存到本地存储
|
// 保存到本地存储
|
||||||
// localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
|
// localStorage.setItem('doctor' + userStore.id.toString(), dontShowAgain.value);
|
||||||
if (selectedRows.length === 0) {
|
if (selectedRows.length === 0) {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="open"
|
v-model="open"
|
||||||
:title="title"
|
:title="title"
|
||||||
width="1000px"
|
width="900px"
|
||||||
teleported
|
teleported
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@close="cancel"
|
@close="cancel"
|
||||||
@@ -518,7 +518,7 @@
|
|||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="操作"
|
title="操作"
|
||||||
width="100"
|
width="80"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
|
|||||||
@@ -227,6 +227,7 @@
|
|||||||
<div style="padding: 10px; position: relative">
|
<div style="padding: 10px; position: relative">
|
||||||
<el-tabs
|
<el-tabs
|
||||||
v-model="activeTab"
|
v-model="activeTab"
|
||||||
|
v-loading="loading"
|
||||||
type="card"
|
type="card"
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@tab-change="handleClick(activeTab)"
|
@tab-change="handleClick(activeTab)"
|
||||||
@@ -545,6 +546,7 @@ const diagnosisRef = ref();
|
|||||||
const consultationRef = ref();
|
const consultationRef = ref();
|
||||||
const infectiousReportRef = ref();
|
const infectiousReportRef = ref();
|
||||||
const waitCount = ref(0);
|
const waitCount = ref(0);
|
||||||
|
const loading = ref(false);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const visitType = ref('');
|
const visitType = ref('');
|
||||||
const firstVisitDate = ref('');
|
const firstVisitDate = ref('');
|
||||||
@@ -805,6 +807,7 @@ function handleCardClick(item, index) {
|
|||||||
currentEncounterId.value = item.encounterId;
|
currentEncounterId.value = item.encounterId;
|
||||||
console.log('currentEncounterId.value 设置为:', currentEncounterId.value);
|
console.log('currentEncounterId.value 设置为:', currentEncounterId.value);
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
patientList.value.forEach((patient) => {
|
patientList.value.forEach((patient) => {
|
||||||
patient.active = patient.encounterId === item.encounterId;
|
patient.active = patient.encounterId === item.encounterId;
|
||||||
});
|
});
|
||||||
@@ -857,6 +860,9 @@ function handleCardClick(item, index) {
|
|||||||
eprescriptionRef.value.getList();
|
eprescriptionRef.value.getList();
|
||||||
consultationRef.value.fetchConsultationList();
|
consultationRef.value.fetchConsultationList();
|
||||||
// emrRef.value.getDetail(item.encounterId);
|
// emrRef.value.getDetail(item.encounterId);
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}, 200);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -487,33 +487,6 @@ function getList() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 格式化工具:将后端返回的日期字符串转为可读格式
|
|
||||||
// 当时间为 00:00:00 时(历史数据 date 列迁移),只显示日期部分
|
|
||||||
function formatDisplayDate(val) {
|
|
||||||
if (!val) return '';
|
|
||||||
const pad = (n) => String(n).padStart(2, '0');
|
|
||||||
function formatFull(d) {
|
|
||||||
const datePart = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
||||||
const h = d.getHours(), m = d.getMinutes(), s = d.getSeconds();
|
|
||||||
if (h === 0 && m === 0 && s === 0) return datePart;
|
|
||||||
return `${datePart} ${pad(h)}:${pad(m)}:${pad(s)}`;
|
|
||||||
}
|
|
||||||
if (typeof val === 'string') {
|
|
||||||
if (val.includes('T')) {
|
|
||||||
const d = new Date(val);
|
|
||||||
if (!isNaN(d.getTime())) return formatFull(d);
|
|
||||||
}
|
|
||||||
// yyyy-MM-dd HH:mm:ss 或 yyyy/MM/dd HH:mm:ss
|
|
||||||
const m = val.match(/^(\d{4}[-/]\d{1,2}[-/]\d{1,2})(?:\s+(\d{1,2}:\d{2}(?::\d{2})?))?/);
|
|
||||||
if (m) {
|
|
||||||
if (m[2] && m[2] !== '00:00:00' && m[2] !== '00:00') return val;
|
|
||||||
return m[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (val instanceof Date && !isNaN(val.getTime())) return formatFull(val);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 先加载西医诊断,再加载中医诊断(避免竞态覆盖)
|
// 先加载西医诊断,再加载中医诊断(避免竞态覆盖)
|
||||||
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
getEncounterDiagnosis(props.patientInfo.encounterId).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
@@ -529,7 +502,6 @@ function getList() {
|
|||||||
syndromeDefinitionId: '',
|
syndromeDefinitionId: '',
|
||||||
syndromeGroupNo: '',
|
syndromeGroupNo: '',
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
diagnosisTime: formatDisplayDate(item.diagnosisTime),
|
|
||||||
};
|
};
|
||||||
if (obj.diagSrtNo == null) {
|
if (obj.diagSrtNo == null) {
|
||||||
obj.diagSrtNo = 1;
|
obj.diagSrtNo = 1;
|
||||||
@@ -568,16 +540,11 @@ function getList() {
|
|||||||
iptDiseTypeCode: item.iptDiseTypeCode,
|
iptDiseTypeCode: item.iptDiseTypeCode,
|
||||||
showPopover: false,
|
showPopover: false,
|
||||||
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: item.diagnosisDoctor || props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: formatDisplayDate(item.diagnosisTime) || new Date().toLocaleString('zh-CN')
|
diagnosisTime: item.diagnosisTime || new Date().toLocaleString('zh-CN')
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 先移除已有的中医诊断,防止重复追加(getList 可能被多次调用)
|
// 将新数据添加到现有列表现有列表
|
||||||
form.value.diagnosisList = form.value.diagnosisList.filter(
|
|
||||||
(item) => item.diagnosisSystem !== '中医'
|
|
||||||
);
|
|
||||||
|
|
||||||
// 将新数据添加到现有列表
|
|
||||||
form.value.diagnosisList.push(...newList);
|
form.value.diagnosisList.push(...newList);
|
||||||
|
|
||||||
// 重新排序整个列表
|
// 重新排序整个列表
|
||||||
@@ -932,109 +899,80 @@ function handleSaveDiagnosis() {
|
|||||||
item.diagSrtNo = index + 1;
|
item.diagSrtNo = index + 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 日期格式化工具:将 Date 对象或 ISO 字符串转为后端期望的 yyyy/M/d HH:mm:ss 格式
|
|
||||||
function formatDateForBackend(val) {
|
|
||||||
if (!val) return '';
|
|
||||||
if (typeof val === 'string') {
|
|
||||||
// 已经是字符串且符合 yyyy/M/d HH:mm:ss 格式则直接返回
|
|
||||||
if (/^\d{4}\/\d{1,2}\/\d{1,2} \d{1,2}:\d{2}:\d{2}$/.test(val)) return val;
|
|
||||||
// 已经是 yyyy-MM-dd HH:mm:ss 格式则转换为 yyyy/M/d HH:mm:ss
|
|
||||||
const m = val.match(/^(\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2})$/);
|
|
||||||
if (m) return `${m[1]}/${parseInt(m[2])}/${parseInt(m[3])} ${m[4]}`;
|
|
||||||
// ISO 或其他格式则解析为 Date
|
|
||||||
val = new Date(val);
|
|
||||||
}
|
|
||||||
if (val instanceof Date && !isNaN(val.getTime())) {
|
|
||||||
const y = val.getFullYear();
|
|
||||||
const M = val.getMonth() + 1;
|
|
||||||
const d = val.getDate();
|
|
||||||
const hh = String(val.getHours()).padStart(2, '0');
|
|
||||||
const mm = String(val.getMinutes()).padStart(2, '0');
|
|
||||||
const ss = String(val.getSeconds()).padStart(2, '0');
|
|
||||||
return `${y}/${M}/${d} ${hh}:${mm}:${ss}`;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
// 步骤3:拆分为西医诊断和中医诊断
|
// 步骤3:拆分为西医诊断和中医诊断
|
||||||
const westernList = sortedList.filter((item) => item.diagnosisSystem !== '中医');
|
const westernList = sortedList.filter((item) => item.diagnosisSystem !== '中医');
|
||||||
const tcmList = sortedList.filter((item) => item.diagnosisSystem === '中医');
|
const tcmList = sortedList.filter((item) => item.diagnosisSystem === '中医');
|
||||||
|
|
||||||
// 顺序执行保存,避免并行竞态:
|
const savePromises = [];
|
||||||
// saveDoctorDiagnosis(西医)会 deleteEncounterDiagnosisInfos 删除全部诊断,
|
|
||||||
// saveTcmDiagnosis(中医)只追加不删除,必须等西医保存完成后再保存中医
|
|
||||||
(async () => {
|
|
||||||
try {
|
|
||||||
// 先保存西医诊断(会先清空再插入)
|
|
||||||
if (westernList.length > 0) {
|
|
||||||
await saveDiagnosis({
|
|
||||||
patientId: props.patientInfo.patientId,
|
|
||||||
encounterId: props.patientInfo.encounterId,
|
|
||||||
diagnosisChildList: westernList.map(item => ({
|
|
||||||
...item,
|
|
||||||
diagnosisTime: formatDateForBackend(item.diagnosisTime),
|
|
||||||
onsetDate: formatDateForBackend(item.onsetDate),
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 再逐个保存中医诊断(只追加,不清空)
|
// 保存西医诊断
|
||||||
for (const item of tcmList) {
|
if (westernList.length > 0) {
|
||||||
const syndromeGroupNo = item.conditionId
|
savePromises.push(
|
||||||
? `${item.conditionId}-${item.tcmSyndromeCode || Date.now()}`
|
saveDiagnosis({
|
||||||
: `${Date.now()}-${item.tcmSyndromeCode || '0'}`;
|
patientId: props.patientInfo.patientId,
|
||||||
await saveTcmDiagnosis({
|
encounterId: props.patientInfo.encounterId,
|
||||||
patientId: props.patientInfo.patientId,
|
diagnosisChildList: westernList,
|
||||||
encounterId: props.patientInfo.encounterId,
|
})
|
||||||
diagnosisChildList: [
|
);
|
||||||
// 病(illness)
|
}
|
||||||
{
|
|
||||||
conditionId: item.conditionId || null,
|
|
||||||
name: item.name,
|
|
||||||
ybNo: item.ybNo,
|
|
||||||
definitionId: item.definitionId || null,
|
|
||||||
diagSrtNo: item.diagSrtNo,
|
|
||||||
medTypeCode: item.medTypeCode,
|
|
||||||
maindiseFlag: item.maindiseFlag,
|
|
||||||
verificationStatusEnum: item.verificationStatusEnum,
|
|
||||||
diagnosisDesc: item.diagnosisDesc || '',
|
|
||||||
diagnosisDoctor: item.diagnosisDoctor || '',
|
|
||||||
diagnosisTime: formatDateForBackend(item.diagnosisTime),
|
|
||||||
iptDiseTypeCode: item.iptDiseTypeCode,
|
|
||||||
syndromeGroupNo: syndromeGroupNo,
|
|
||||||
},
|
|
||||||
// 证(syndrome)
|
|
||||||
{
|
|
||||||
name: item.tcmSyndromeName,
|
|
||||||
ybNo: item.tcmSyndromeCode,
|
|
||||||
definitionId: item.syndromeDefinitionId || null,
|
|
||||||
diagSrtNo: null,
|
|
||||||
syndromeGroupNo: syndromeGroupNo,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 所有保存完成后刷新
|
// 保存中医诊断
|
||||||
emits('diagnosisSave', false);
|
tcmList.forEach((item) => {
|
||||||
proxy.$modal.msgSuccess('诊断已保存');
|
const syndromeGroupNo = item.conditionId
|
||||||
getList();
|
? `${item.conditionId}-${item.tcmSyndromeCode || Date.now()}`
|
||||||
|
: `${Date.now()}-${item.tcmSyndromeCode || '0'}`;
|
||||||
|
savePromises.push(
|
||||||
|
saveTcmDiagnosis({
|
||||||
|
patientId: props.patientInfo.patientId,
|
||||||
|
encounterId: props.patientInfo.encounterId,
|
||||||
|
diagnosisChildList: [
|
||||||
|
// 病(illness)
|
||||||
|
{
|
||||||
|
conditionId: item.conditionId || null,
|
||||||
|
name: item.name,
|
||||||
|
ybNo: item.ybNo,
|
||||||
|
definitionId: item.definitionId || null,
|
||||||
|
diagSrtNo: item.diagSrtNo,
|
||||||
|
medTypeCode: item.medTypeCode,
|
||||||
|
maindiseFlag: item.maindiseFlag,
|
||||||
|
verificationStatusEnum: item.verificationStatusEnum,
|
||||||
|
diagnosisDesc: item.diagnosisDesc || '',
|
||||||
|
diagnosisDoctor: item.diagnosisDoctor || '',
|
||||||
|
diagnosisTime: item.diagnosisTime || '',
|
||||||
|
iptDiseTypeCode: item.iptDiseTypeCode,
|
||||||
|
syndromeGroupNo: syndromeGroupNo,
|
||||||
|
},
|
||||||
|
// 证(syndrome)
|
||||||
|
{
|
||||||
|
name: item.tcmSyndromeName,
|
||||||
|
ybNo: item.tcmSyndromeCode,
|
||||||
|
definitionId: item.syndromeDefinitionId || null,
|
||||||
|
diagSrtNo: null,
|
||||||
|
syndromeGroupNo: syndromeGroupNo,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
// 食源性疾病逻辑
|
Promise.all(savePromises).then(() => {
|
||||||
isFoodDiseasesNew({ encounterId: props.patientInfo.encounterId }).then((res2) => {
|
emits('diagnosisSave', false);
|
||||||
|
proxy.$modal.msgSuccess('诊断已保存');
|
||||||
|
|
||||||
|
// 保存成功后从服务器重新加载数据,确保前后端数据一致
|
||||||
|
getList();
|
||||||
|
|
||||||
|
// 食源性疾病逻辑
|
||||||
|
isFoodDiseasesNew({ encounterId: props.patientInfo.encounterId }).then((res2) => {
|
||||||
if (res2.code === 20 && res2.data) {
|
if (res2.code === 20 && res2.data) {
|
||||||
window.open(res2.data, '_blank');
|
window.open(res2.data, '_blank');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (e) {
|
}).finally(() => {
|
||||||
console.error('保存诊断失败', e);
|
setTimeout(() => {
|
||||||
proxy.$modal.msgError('保存诊断失败');
|
isSaving.value = false;
|
||||||
} finally {
|
}, 100);
|
||||||
setTimeout(() => {
|
});
|
||||||
isSaving.value = false;
|
|
||||||
}, 100);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,16 +150,9 @@ const showApplicationFormDialog = (name) => {
|
|||||||
onBeforeMount(() => {});
|
onBeforeMount(() => {});
|
||||||
onMounted(() => {});
|
onMounted(() => {});
|
||||||
const applicationFormNameRef = ref();
|
const applicationFormNameRef = ref();
|
||||||
const submitApplicationForm = async () => {
|
const submitApplicationForm = () => {
|
||||||
if (applicationFormNameRef.value?.submit) {
|
if (applicationFormNameRef.value?.submit) {
|
||||||
const success = await applicationFormNameRef.value.submit();
|
applicationFormNameRef.value.submit();
|
||||||
if (success) {
|
|
||||||
applicationFormDialogVisible.value = false;
|
|
||||||
applicationFormName.value = null;
|
|
||||||
setTimeout(() => {
|
|
||||||
emits('refResh');
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const submitOk = () => {
|
const submitOk = () => {
|
||||||
|
|||||||
@@ -5,20 +5,7 @@
|
|||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="surgery-container">
|
<div class="surgery-container">
|
||||||
<div class="search-wrapper">
|
|
||||||
<el-input
|
|
||||||
v-model="searchQuery"
|
|
||||||
placeholder="项目代码/名称/拼音码"
|
|
||||||
clearable
|
|
||||||
prefix-icon="Search"
|
|
||||||
style="width: 480px;"
|
|
||||||
@input="handleSearch"
|
|
||||||
@clear="handleClear"
|
|
||||||
/>
|
|
||||||
<span class="loaded-count">已加载 {{ applicationList.length }} 项</span>
|
|
||||||
</div>
|
|
||||||
<div
|
<div
|
||||||
v-loading="loading"
|
|
||||||
class="transfer-wrapper"
|
class="transfer-wrapper"
|
||||||
style="min-height: 300px;"
|
style="min-height: 300px;"
|
||||||
>
|
>
|
||||||
@@ -27,6 +14,10 @@
|
|||||||
v-model="transferValue"
|
v-model="transferValue"
|
||||||
:data="applicationList"
|
:data="applicationList"
|
||||||
:titles="['待选择', '已选择']"
|
:titles="['待选择', '已选择']"
|
||||||
|
:format="leftPanelFormat"
|
||||||
|
filterable
|
||||||
|
filter-placeholder="项目代码/名称"
|
||||||
|
:filter-method="filterMethod"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="bloodTransfusion-form">
|
<div class="bloodTransfusion-form">
|
||||||
@@ -365,6 +356,12 @@ let surgeryRecordsCache = null; // 原始 API 记录
|
|||||||
let surgeryMappedCache = null; // 映射后的 el-transfer 数据
|
let surgeryMappedCache = null; // 映射后的 el-transfer 数据
|
||||||
let doctorCache = null; // 医生列表(含默认主刀医生 ID)
|
let doctorCache = null; // 医生列表(含默认主刀医生 ID)
|
||||||
const transferRef = ref(null);
|
const transferRef = ref(null);
|
||||||
|
const dbTotal = ref(0); // 数据库中的手术项目总数
|
||||||
|
const checkedCount = computed(() => transferValue.value.length);
|
||||||
|
const leftPanelFormat = computed(() => ({
|
||||||
|
noChecked: ` 0/${dbTotal.value}`,
|
||||||
|
hasChecked: ` ${checkedCount.value}/${dbTotal.value}`,
|
||||||
|
}));
|
||||||
// 递归查找树形科室节点
|
// 递归查找树形科室节点
|
||||||
const findTreeItem = (list, id) => {
|
const findTreeItem = (list, id) => {
|
||||||
if (!list || list.length === 0 || id == null || id === '') return null;
|
if (!list || list.length === 0 || id == null || id === '') return null;
|
||||||
@@ -396,23 +393,6 @@ const loading = ref(false);
|
|||||||
const applicationList = ref([]);
|
const applicationList = ref([]);
|
||||||
const applicationListAll = ref([]);
|
const applicationListAll = ref([]);
|
||||||
const allLoading = ref(false);
|
const allLoading = ref(false);
|
||||||
// 搜索关键字(远程搜索用)
|
|
||||||
const searchQuery = ref('');
|
|
||||||
let searchTimer = null;
|
|
||||||
|
|
||||||
/** 远程搜索:输入关键字后 300ms 防抖,调后端 API 搜索 */
|
|
||||||
const handleSearch = () => {
|
|
||||||
if (searchTimer) clearTimeout(searchTimer);
|
|
||||||
searchTimer = setTimeout(() => {
|
|
||||||
getList(searchQuery.value || '');
|
|
||||||
}, 300);
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 清除搜索:恢复完整缓存列表 */
|
|
||||||
const handleClear = () => {
|
|
||||||
searchQuery.value = '';
|
|
||||||
getList();
|
|
||||||
};
|
|
||||||
// 递归查找默认科室
|
// 递归查找默认科室
|
||||||
const findTargetDepartment = (selectProjectIds) => {
|
const findTargetDepartment = (selectProjectIds) => {
|
||||||
if (!selectProjectIds || selectProjectIds.length === 0) return '';
|
if (!selectProjectIds || selectProjectIds.length === 0) return '';
|
||||||
@@ -436,12 +416,13 @@ const getList = async (key) => {
|
|||||||
if (!key && surgeryRecordsCache && surgeryMappedCache) {
|
if (!key && surgeryRecordsCache && surgeryMappedCache) {
|
||||||
applicationList.value = surgeryMappedCache;
|
applicationList.value = surgeryMappedCache;
|
||||||
applicationListAll.value = surgeryRecordsCache;
|
applicationListAll.value = surgeryRecordsCache;
|
||||||
|
dbTotal.value = surgeryRecordsCache.length;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
return getSurgeryPage({
|
return getSurgeryPage({
|
||||||
pageSize: key ? 500 : 100,
|
pageSize: 1000,
|
||||||
searchKey: key || undefined,
|
keyword: key || undefined,
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
const records = res.data.records;
|
const records = res.data.records;
|
||||||
@@ -459,15 +440,25 @@ const getList = async (key) => {
|
|||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.error('手术项目加载失败:', e);
|
console.error('手术项目加载失败:', e);
|
||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
|
dbTotal.value = 0;
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* el-transfer 内置过滤方法:支持任意字符即时过滤
|
||||||
|
* 按项目名称/代码进行前端模糊匹配
|
||||||
|
*/
|
||||||
|
const filterMethod = (query, item) => {
|
||||||
|
const q = query.toLowerCase();
|
||||||
|
const label = (item.label || '').toLowerCase();
|
||||||
|
const key = String(item.key || '');
|
||||||
|
return label.includes(q) || key.includes(q);
|
||||||
|
};
|
||||||
|
|
||||||
const mapToTransferItem = (item) => ({
|
const mapToTransferItem = (item) => ({
|
||||||
key: String(item.adviceDefinitionId),
|
key: String(item.adviceDefinitionId),
|
||||||
label: `${item.adviceName} - ${item.unitCode_dictText || item.unitCode || ''}`,
|
label: `${item.adviceName} - ${item.unitCode_dictText || item.unitCode || ''}`,
|
||||||
pyStr: item.pyStr || '',
|
|
||||||
busNo: item.busNo || '',
|
|
||||||
disabled: false,
|
disabled: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -614,33 +605,26 @@ watch(() => transferValue.value, (newValue) => {
|
|||||||
});
|
});
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
if (transferValue.value.length == 0) {
|
if (transferValue.value.length == 0) {
|
||||||
proxy.$message.error('请选择手术项目');
|
return proxy.$message.error('请选择手术项目');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
if (!form.targetDepartment) {
|
if (!form.targetDepartment) {
|
||||||
proxy.$message.error('请选择发往科室');
|
return proxy.$message.error('请选择发往科室');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
// 新增必填校验
|
// 新增必填校验
|
||||||
if (!form.surgeryLevel) {
|
if (!form.surgeryLevel) {
|
||||||
proxy.$message.error('请选择手术等级');
|
return proxy.$message.error('请选择手术等级');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
if (!form.anesthesiaType) {
|
if (!form.anesthesiaType) {
|
||||||
proxy.$message.error('请选择麻醉方式');
|
return proxy.$message.error('请选择麻醉方式');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
if (!form.surgerySite) {
|
if (!form.surgerySite) {
|
||||||
proxy.$message.error('请选择手术部位');
|
return proxy.$message.error('请选择手术部位');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
if (!form.mainSurgeonId) {
|
if (!form.mainSurgeonId) {
|
||||||
proxy.$message.error('请选择主刀医生');
|
return proxy.$message.error('请选择主刀医生');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
if (!form.plannedTime) {
|
if (!form.plannedTime) {
|
||||||
proxy.$message.error('请选择预定手术时间');
|
return proxy.$message.error('请选择预定手术时间');
|
||||||
return Promise.resolve(false);
|
|
||||||
}
|
}
|
||||||
let applicationListAllFilter = applicationListAll.value.filter((item) => {
|
let applicationListAllFilter = applicationListAll.value.filter((item) => {
|
||||||
return transferValue.value.includes(item.adviceDefinitionId);
|
return transferValue.value.includes(item.adviceDefinitionId);
|
||||||
@@ -667,7 +651,7 @@ const submit = () => {
|
|||||||
const assistant2Doc = doctorOptions.value.find(d => d.id === form.assistant2Id);
|
const assistant2Doc = doctorOptions.value.find(d => d.id === form.assistant2Id);
|
||||||
form.assistant2Name = assistant2Doc ? assistant2Doc.name : '';
|
form.assistant2Name = assistant2Doc ? assistant2Doc.name : '';
|
||||||
|
|
||||||
return saveSurgery({
|
saveSurgery({
|
||||||
activityList: applicationListAllFilter,
|
activityList: applicationListAllFilter,
|
||||||
patientId: patientInfo.value.patientId, //患者ID
|
patientId: patientInfo.value.patientId, //患者ID
|
||||||
encounterId: patientInfo.value.encounterId, // 就诊ID
|
encounterId: patientInfo.value.encounterId, // 就诊ID
|
||||||
@@ -682,14 +666,9 @@ const submit = () => {
|
|||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
editingRequestFormId.value = '';
|
editingRequestFormId.value = '';
|
||||||
emits('submitOk');
|
emits('submitOk');
|
||||||
return true;
|
|
||||||
} else {
|
} else {
|
||||||
proxy.$message.error(res.message);
|
proxy.$message.error(res.message);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
|
||||||
console.error('手术申请保存失败:', err);
|
|
||||||
return false;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
/** 递归规范化树形科室 ID 为字符串,确保与 el-tree-select / findTreeItem 兼容 */
|
/** 递归规范化树形科室 ID 为字符串,确保与 el-tree-select / findTreeItem 兼容 */
|
||||||
@@ -748,19 +727,6 @@ defineExpose({ state, submit, fillForm, getLocationInfo, getDiagnosisList, getLi
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.search-wrapper {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
|
|
||||||
.loaded-count {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #64748B;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.transfer-wrapper {
|
.transfer-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="inpatientDoctor-order-container" style="width: 100%">
|
<div class="inpatientDoctor-order-container" style="width: 100%">
|
||||||
<div style="margin-bottom: 5px" class="order-operate-btn">
|
<div style="margin-bottom: 5px" class="order-operate-btn">
|
||||||
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
<div style="height: 44px; display: flex; align-items: center; flex: none">
|
||||||
@@ -216,14 +216,10 @@
|
|||||||
/>
|
/>
|
||||||
</el-select>
|
</el-select>
|
||||||
<el-popover
|
<el-popover
|
||||||
:popper-style="advicePopperStyle"
|
:popper-style="{ padding: '0' }"
|
||||||
placement="bottom-start"
|
placement="bottom-start"
|
||||||
popper-class="order-advice-popper"
|
|
||||||
:offset="0"
|
|
||||||
:visible="scope.row.showPopover"
|
:visible="scope.row.showPopover"
|
||||||
:width="1200"
|
:width="1200"
|
||||||
:teleported="true"
|
|
||||||
:popper-options="advicePopperOptions"
|
|
||||||
>
|
>
|
||||||
<adviceBaseList
|
<adviceBaseList
|
||||||
ref="adviceTableRef"
|
ref="adviceTableRef"
|
||||||
@@ -259,11 +255,9 @@
|
|||||||
<span v-else>{{ scope.row.adviceName }}</span>
|
<span v-else>{{ scope.row.adviceName }}</span>
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column title="状态" align="center" field="" width="120">
|
<vxe-column title="状态" align="center" field="" width="90">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.statusEnum == 6" type="danger">停止</el-tag>
|
<el-tag v-if="scope.row.chargeStatus == 5" type="info">
|
||||||
<el-tag v-else-if="scope.row.statusEnum == 13" type="warning">已停嘱(待核对)</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.chargeStatus == 5" type="info">
|
|
||||||
{{ scope.row.chargeStatus_enumText }}
|
{{ scope.row.chargeStatus_enumText }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-else-if="scope.row.statusEnum == 2" type="success">已签发</el-tag>
|
<el-tag v-else-if="scope.row.statusEnum == 2" type="success">已签发</el-tag>
|
||||||
@@ -274,6 +268,7 @@
|
|||||||
<el-tag v-else-if="scope.row.statusEnum == 10" type="primary">已校对</el-tag>
|
<el-tag v-else-if="scope.row.statusEnum == 10" type="primary">已校对</el-tag>
|
||||||
<el-tag v-else-if="scope.row.statusEnum == 11" type="primary">待接收</el-tag>
|
<el-tag v-else-if="scope.row.statusEnum == 11" type="primary">待接收</el-tag>
|
||||||
<el-tag v-else-if="scope.row.statusEnum == 3" type="success">已校对</el-tag>
|
<el-tag v-else-if="scope.row.statusEnum == 3" type="success">已校对</el-tag>
|
||||||
|
<el-tag v-else-if="scope.row.statusEnum == 6" type="danger">停止</el-tag>
|
||||||
<el-tag v-else-if="scope.row.statusEnum == 20" type="success">已完成</el-tag>
|
<el-tag v-else-if="scope.row.statusEnum == 20" type="success">已完成</el-tag>
|
||||||
<el-tag v-else type="info">{{ scope.row.chargeStatus_enumText }}</el-tag>
|
<el-tag v-else type="info">{{ scope.row.chargeStatus_enumText }}</el-tag>
|
||||||
</template>
|
</template>
|
||||||
@@ -312,17 +307,15 @@
|
|||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column title="频次/用法" align="center" field="" width="180">
|
<vxe-column title="频次/用法" align="center" field="" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span v-if="!scope.row.isEdit && (scope.row.adviceType == 1 || scope.row.adviceType == 7 || scope.row.adviceType == 8)" style="text-align: right">
|
<span v-if="!scope.row.isEdit && scope.row.adviceType == 1" style="text-align: right">
|
||||||
{{
|
{{
|
||||||
scope.row.adviceType == 8
|
[
|
||||||
? (scope.row.rateCode_dictText || scope.row.rateCode || '-')
|
scope.row.rateCode_dictText,
|
||||||
: [
|
scope.row.dispensePerDuration ? scope.row.dispensePerDuration + '天' : '',
|
||||||
scope.row.rateCode_dictText,
|
scope.row.methodCode_dictText,
|
||||||
scope.row.dispensePerDuration ? scope.row.dispensePerDuration + '天' : '',
|
]
|
||||||
scope.row.methodCode_dictText,
|
.filter(Boolean)
|
||||||
]
|
.join(' ')
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ')
|
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
@@ -502,24 +495,6 @@ const loading = ref(false);
|
|||||||
// Bug #587: 标记弹窗刚被关闭的行uniqueKey,防止关闭弹窗时误触发行展开
|
// Bug #587: 标记弹窗刚被关闭的行uniqueKey,防止关闭弹窗时误触发行展开
|
||||||
const popoverJustClosedByKey = ref(null);
|
const popoverJustClosedByKey = ref(null);
|
||||||
|
|
||||||
// 医嘱检索下拉浮框对齐:跟踪表格水平滚动偏移与主体区域边界限制
|
|
||||||
const tableScrollLeft = ref(0);
|
|
||||||
const mainBoundary = ref(null);
|
|
||||||
const advicePopperStyle = computed(() => ({
|
|
||||||
padding: '0',
|
|
||||||
marginLeft: `-${tableScrollLeft.value}px`,
|
|
||||||
}));
|
|
||||||
const advicePopperOptions = computed(() => ({
|
|
||||||
modifiers: [
|
|
||||||
{
|
|
||||||
name: 'preventOverflow',
|
|
||||||
options: {
|
|
||||||
boundary: mainBoundary.value || 'viewport',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 停嘱弹窗
|
// 停嘱弹窗
|
||||||
const stopDialogVisible = ref(false);
|
const stopDialogVisible = ref(false);
|
||||||
const stopForm = reactive({
|
const stopForm = reactive({
|
||||||
@@ -613,9 +588,8 @@ const adviceTypeList = computed(() => {
|
|||||||
hasShownPharmacyConfigWarning.value = true;
|
hasShownPharmacyConfigWarning.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 只返回不需要取药科室配置的类别(诊疗、耗材、手术、出院带药)
|
// 只返回不需要取药科室配置的类别(诊疗、手术、出院带药)
|
||||||
return [
|
return [
|
||||||
{ label: '耗材', value: 2, adviceType: 2, categoryCode: '' },
|
|
||||||
{ label: '诊疗', value: 3, adviceType: 3, categoryCode: '' },
|
{ label: '诊疗', value: 3, adviceType: 3, categoryCode: '' },
|
||||||
{ label: '手术', value: 6, adviceType: 6, categoryCode: '' },
|
{ label: '手术', value: 6, adviceType: 6, categoryCode: '' },
|
||||||
{ label: '出院带药', value: 7, adviceType: 7, categoryCode: '' },
|
{ label: '出院带药', value: 7, adviceType: 7, categoryCode: '' },
|
||||||
@@ -643,8 +617,7 @@ const adviceTypeList = computed(() => {
|
|||||||
typeList.push({ label: '中草药', value: '1-4', adviceType: 1, categoryCode: '4' });
|
typeList.push({ label: '中草药', value: '1-4', adviceType: 1, categoryCode: '4' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 始终添加诊疗、耗材和手术(它们不受取药配置限制)
|
// 始终添加诊疗和手术(它们不受取药配置限制)
|
||||||
typeList.push({ label: '耗材', value: 2, adviceType: 2, categoryCode: '' });
|
|
||||||
typeList.push({ label: '诊疗', value: 3, adviceType: 3, categoryCode: '' });
|
typeList.push({ label: '诊疗', value: 3, adviceType: 3, categoryCode: '' });
|
||||||
typeList.push({ label: '手术', value: 6, adviceType: 6, categoryCode: '' });
|
typeList.push({ label: '手术', value: 6, adviceType: 6, categoryCode: '' });
|
||||||
|
|
||||||
@@ -669,10 +642,6 @@ const statusOption = [
|
|||||||
label: '已签发',
|
label: '已签发',
|
||||||
value: 2,
|
value: 2,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
label: '已停嘱',
|
|
||||||
value: 13,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
label: '停止',
|
label: '停止',
|
||||||
value: 6,
|
value: 6,
|
||||||
@@ -686,28 +655,11 @@ const statusOption = [
|
|||||||
// loadingInstance removed - using loading ref instead
|
// loadingInstance removed - using loading ref instead
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
document.addEventListener('keydown', escKeyListener);
|
document.addEventListener('keydown', escKeyListener);
|
||||||
// 监听表格水平滚动,同步更新医嘱检索下拉浮框的水平偏移
|
|
||||||
nextTick(() => {
|
|
||||||
const scrollWrapper = document.querySelector('.vxe-table--body-wrapper');
|
|
||||||
if (scrollWrapper) {
|
|
||||||
scrollWrapper.addEventListener('scroll', onTableScroll, { passive: true });
|
|
||||||
}
|
|
||||||
// 获取主体区域容器作为 Popper 边界,防止浮框向左移入患者列表
|
|
||||||
mainBoundary.value = document.querySelector('.inpatientDoctor-home-main');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
document.removeEventListener('keydown', escKeyListener);
|
document.removeEventListener('keydown', escKeyListener);
|
||||||
const scrollWrapper = document.querySelector('.vxe-table--body-wrapper');
|
|
||||||
if (scrollWrapper) {
|
|
||||||
scrollWrapper.removeEventListener('scroll', onTableScroll);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function onTableScroll(e) {
|
|
||||||
tableScrollLeft.value = e.target.scrollLeft || 0;
|
|
||||||
}
|
|
||||||
watch(
|
watch(
|
||||||
() => expandOrder.value,
|
() => expandOrder.value,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
@@ -806,9 +758,6 @@ function getListInfo(addNewRow) {
|
|||||||
// 🔧 修复:同时保存 orgName,当 orgId 在科室树中匹配不到时作为兜底显示
|
// 🔧 修复:同时保存 orgName,当 orgId 在科室树中匹配不到时作为兜底显示
|
||||||
// 优先从科室树查找名称,其次用 positionName(后端已保存的科室名),最后用 contentJson 中的 orgName
|
// 优先从科室树查找名称,其次用 positionName(后端已保存的科室名),最后用 contentJson 中的 orgName
|
||||||
orgName: findOrgName(item.positionId || parsedContent?.orgId || item.orgId) || item.positionName || parsedContent?.orgName || undefined,
|
orgName: findOrgName(item.positionId || parsedContent?.orgId || item.orgId) || item.positionName || parsedContent?.orgName || undefined,
|
||||||
// 确保文字医嘱的 rateCode / rateCode_dictText 不被 item 中的 null/undefined 覆盖
|
|
||||||
rateCode: item.rateCode || parsedContent?.rateCode || undefined,
|
|
||||||
rateCode_dictText: item.rateCode_dictText || parsedContent?.rateCode_dictText || undefined,
|
|
||||||
// Bug #589: 从contentJson检测出院带药标记,恢复类型显示
|
// Bug #589: 从contentJson检测出院带药标记,恢复类型显示
|
||||||
// 后端存储时adviceType转为1(药品),通过prescriptionCategory=3标识出院带药
|
// 后端存储时adviceType转为1(药品),通过prescriptionCategory=3标识出院带药
|
||||||
...(parsedContent?.prescriptionCategory == 3 ? {
|
...(parsedContent?.prescriptionCategory == 3 ? {
|
||||||
@@ -970,8 +919,6 @@ function handleAddPrescription() {
|
|||||||
statusEnum: 1,
|
statusEnum: 1,
|
||||||
therapyEnum: '2', // 默认为临时医嘱
|
therapyEnum: '2', // 默认为临时医嘱
|
||||||
startTime: defaultStartTime,
|
startTime: defaultStartTime,
|
||||||
requesterId_dictText: userStore.nickName,
|
|
||||||
requesterId: userStore.id,
|
|
||||||
});
|
});
|
||||||
getGroupMarkers();
|
getGroupMarkers();
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@@ -1044,13 +991,6 @@ function clickRowDb({ row, column, event }) {
|
|||||||
if (row.statusEnum == 1) {
|
if (row.statusEnum == 1) {
|
||||||
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
||||||
row.therapyEnum = String(row.therapyEnum ?? '1');
|
row.therapyEnum = String(row.therapyEnum ?? '1');
|
||||||
if (row.adviceType == 8) {
|
|
||||||
if (!row.orgId && userStore.orgId) {
|
|
||||||
row.orgId = userStore.orgId;
|
|
||||||
row.positionId = userStore.orgId;
|
|
||||||
row.orgName = userStore.orgName || findOrgName(userStore.orgId) || '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
row.isEdit = true;
|
row.isEdit = true;
|
||||||
const index = prescriptionList.value.findIndex((item) => item.uniqueKey === row.uniqueKey);
|
const index = prescriptionList.value.findIndex((item) => item.uniqueKey === row.uniqueKey);
|
||||||
rowIndex.value = index;
|
rowIndex.value = index;
|
||||||
@@ -1133,14 +1073,6 @@ function handleDiagnosisChange(item) {
|
|||||||
function expandTextRow(rowIndex) {
|
function expandTextRow(rowIndex) {
|
||||||
const row = filterPrescriptionList.value[rowIndex];
|
const row = filterPrescriptionList.value[rowIndex];
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
|
|
||||||
// 自动获取当前用户所在的科室
|
|
||||||
if (!row.orgId && userStore.orgId) {
|
|
||||||
row.orgId = userStore.orgId;
|
|
||||||
row.positionId = userStore.orgId;
|
|
||||||
row.orgName = userStore.orgName || findOrgName(userStore.orgId) || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
expandOrder.value = [row.uniqueKey];
|
expandOrder.value = [row.uniqueKey];
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
if (prescriptionRef.value?.setRowExpand) {
|
if (prescriptionRef.value?.setRowExpand) {
|
||||||
@@ -1151,11 +1083,6 @@ function expandTextRow(rowIndex) {
|
|||||||
|
|
||||||
function handleFocus(row, index) {
|
function handleFocus(row, index) {
|
||||||
rowIndex.value = index;
|
rowIndex.value = index;
|
||||||
// 同步表格水平滚动偏移,确保浮框位置正确
|
|
||||||
const scrollWrapper = document.querySelector('.vxe-table--body-wrapper');
|
|
||||||
if (scrollWrapper) {
|
|
||||||
tableScrollLeft.value = scrollWrapper.scrollLeft || 0;
|
|
||||||
}
|
|
||||||
// 文字医嘱(type=8)不弹药品搜索框,直接展开填写面板
|
// 文字医嘱(type=8)不弹药品搜索框,直接展开填写面板
|
||||||
const adviceType = row.adviceType !== undefined ? row.adviceType : adviceQueryParams.value.adviceType;
|
const adviceType = row.adviceType !== undefined ? row.adviceType : adviceQueryParams.value.adviceType;
|
||||||
if (adviceType == 8) {
|
if (adviceType == 8) {
|
||||||
@@ -1230,8 +1157,6 @@ function selectAdviceBase(key, row) {
|
|||||||
// Bug #589: 出院带药需要保留类型和标志,setValue中可能被API数据覆盖
|
// Bug #589: 出院带药需要保留类型和标志,setValue中可能被API数据覆盖
|
||||||
adviceType: prevRow.adviceType || undefined,
|
adviceType: prevRow.adviceType || undefined,
|
||||||
dischargeFlag: prevRow.dischargeFlag || undefined,
|
dischargeFlag: prevRow.dischargeFlag || undefined,
|
||||||
requesterId_dictText: userStore.nickName,
|
|
||||||
requesterId: userStore.id,
|
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
setValue(row);
|
setValue(row);
|
||||||
@@ -1725,8 +1650,6 @@ function handleSaveSign(row, index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新UI状态
|
// 更新UI状态
|
||||||
row.requesterId_dictText = userStore.nickName;
|
|
||||||
row.requesterId = userStore.id;
|
|
||||||
row.isEdit = false;
|
row.isEdit = false;
|
||||||
isAdding.value = false;
|
isAdding.value = false;
|
||||||
collapseAllExpanded();
|
collapseAllExpanded();
|
||||||
@@ -2088,8 +2011,6 @@ function handleSaveGroup(orderGroupList) {
|
|||||||
// 创建新的处方项目
|
// 创建新的处方项目
|
||||||
const newRow = {
|
const newRow = {
|
||||||
...prescriptionList.value[tempIndex],
|
...prescriptionList.value[tempIndex],
|
||||||
requesterId_dictText: userStore.nickName,
|
|
||||||
requesterId: userStore.id,
|
|
||||||
patientId: patientInfo.value.patientId,
|
patientId: patientInfo.value.patientId,
|
||||||
encounterId: patientInfo.value.encounterId,
|
encounterId: patientInfo.value.encounterId,
|
||||||
accountId: accountId.value,
|
accountId: accountId.value,
|
||||||
@@ -2149,8 +2070,6 @@ function handleSaveGroup(orderGroupList) {
|
|||||||
function handleSaveHistory(value) {
|
function handleSaveHistory(value) {
|
||||||
let saveRow = {
|
let saveRow = {
|
||||||
...value,
|
...value,
|
||||||
requesterId_dictText: userStore.nickName,
|
|
||||||
requesterId: userStore.id,
|
|
||||||
patientId: patientInfo.value.patientId,
|
patientId: patientInfo.value.patientId,
|
||||||
encounterId: patientInfo.value.encounterId,
|
encounterId: patientInfo.value.encounterId,
|
||||||
accountId: accountId.value,
|
accountId: accountId.value,
|
||||||
@@ -2317,7 +2236,7 @@ function handleStopAdvice() {
|
|||||||
// 找出停嘱的
|
// 找出停嘱的
|
||||||
for (let index = 0; index < selectRows.length; index++) {
|
for (let index = 0; index < selectRows.length; index++) {
|
||||||
const item = selectRows[index];
|
const item = selectRows[index];
|
||||||
if (item.statusEnum == 6 || item.statusEnum == 13) {
|
if (item.statusEnum == 6) {
|
||||||
isStop = false;
|
isStop = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3055,9 +2974,4 @@ defineExpose({ getListInfo, getDiagnosisInfo });
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 医嘱检索下拉浮框:teleported 到 body,需用 :global 选择
|
|
||||||
:global(.order-advice-popper) {
|
|
||||||
transition: margin-left 0.05s ease-out;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -273,15 +273,7 @@
|
|||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column title="医嘱状态" align="center" width="120">
|
<vxe-column title="医嘱状态" align="center" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.requestStatus == 6" type="danger">停止</el-tag>
|
{{ scope.row.requestStatus_enumText || '-' }}
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 13" type="warning">已停嘱(待核对)</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 2" type="success">已签发</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 1" type="primary">待签发</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 10" type="primary">已校对</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 11" type="primary">待接收</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 3" type="success">已校对</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.requestStatus == 20" type="success">已完成</el-tag>
|
|
||||||
<el-tag v-else type="info">{{ scope.row.requestStatus_enumText || '-' }}</el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column title="执行科室" align="center" min-width="120">
|
<vxe-column title="执行科室" align="center" min-width="120">
|
||||||
|
|||||||
@@ -202,7 +202,7 @@
|
|||||||
<vxe-column
|
<vxe-column
|
||||||
title="医嘱状态"
|
title="医嘱状态"
|
||||||
field="requestStatus_enumText"
|
field="requestStatus_enumText"
|
||||||
width="110"
|
width="100"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@@ -235,39 +235,19 @@
|
|||||||
field="singleDose"
|
field="singleDose"
|
||||||
width="100"
|
width="100"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
/>
|
||||||
<template #default="scope">
|
|
||||||
{{ scope.row.singleDose ? scope.row.singleDose + ' ' + (scope.row.doseUnitCode_dictText || '') : '' }}
|
|
||||||
</template>
|
|
||||||
</vxe-column>
|
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="总量"
|
title="总量"
|
||||||
field="totalAmount"
|
field="totalAmount"
|
||||||
width="100"
|
width="100"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
/>
|
||||||
<template #default="scope">
|
|
||||||
{{ scope.row.totalAmount }} {{ scope.row.unitCode_dictText || '' }}
|
|
||||||
</template>
|
|
||||||
</vxe-column>
|
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="频次/用法"
|
title="频次/用法"
|
||||||
field="frequencyUsage"
|
field="frequencyUsage"
|
||||||
width="130"
|
width="110"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
/>
|
||||||
<template #default="scope">
|
|
||||||
{{
|
|
||||||
[
|
|
||||||
scope.row.rateCode_dictText,
|
|
||||||
scope.row.dispensePerDuration ? scope.row.dispensePerDuration + '天' : '',
|
|
||||||
scope.row.methodCode_dictText,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(' ')
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</vxe-column>
|
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="皮试"
|
title="皮试"
|
||||||
field="skinTestStatus"
|
field="skinTestStatus"
|
||||||
@@ -303,14 +283,10 @@
|
|||||||
</vxe-column>
|
</vxe-column>
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="开嘱医生"
|
title="开嘱医生"
|
||||||
field="requesterId_dictText"
|
field="orderingDoctor"
|
||||||
width="100"
|
width="100"
|
||||||
align="center"
|
align="center"
|
||||||
>
|
/>
|
||||||
<template #default="scope">
|
|
||||||
{{ scope.row.requesterId_dictText || scope.row.orderingDoctor || '-' }}
|
|
||||||
</template>
|
|
||||||
</vxe-column>
|
|
||||||
<vxe-column
|
<vxe-column
|
||||||
title="退回原因"
|
title="退回原因"
|
||||||
field="reasonText"
|
field="reasonText"
|
||||||
@@ -396,7 +372,6 @@ const REQUEST_STATUS_DISPLAY = {
|
|||||||
[RequestStatus.ACTIVE]: '已签发',
|
[RequestStatus.ACTIVE]: '已签发',
|
||||||
[RequestStatus.COMPLETED]: '已校对',
|
[RequestStatus.COMPLETED]: '已校对',
|
||||||
[RequestStatus.STOPPED]: '已停止',
|
[RequestStatus.STOPPED]: '已停止',
|
||||||
[RequestStatus.PENDING_STOP]: '已停嘱',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 发药状态 → 医嘱状态映射表 */
|
/** 发药状态 → 医嘱状态映射表 */
|
||||||
@@ -420,21 +395,17 @@ const LEGACY_STATUS_TEXT = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const getStatusDisplayText = (row) => {
|
const getStatusDisplayText = (row) => {
|
||||||
// 1. 优先使用行级别请求状态:如果已停止或停嘱中,直接显示该状态
|
// 1. 优先使用发药状态
|
||||||
const requestCode = Number(row?.requestStatus);
|
|
||||||
if (requestCode === RequestStatus.STOPPED || requestCode === RequestStatus.PENDING_STOP) {
|
|
||||||
return REQUEST_STATUS_DISPLAY[requestCode];
|
|
||||||
}
|
|
||||||
// 2. 其次使用发药状态
|
|
||||||
const dispenseCode = Number(row?.dispenseStatus);
|
const dispenseCode = Number(row?.dispenseStatus);
|
||||||
if (DISPENSE_STATUS_DISPLAY[dispenseCode]) {
|
if (DISPENSE_STATUS_DISPLAY[dispenseCode]) {
|
||||||
return DISPENSE_STATUS_DISPLAY[dispenseCode];
|
return DISPENSE_STATUS_DISPLAY[dispenseCode];
|
||||||
}
|
}
|
||||||
// 3. 最后回退到其他请求状态
|
// 2. 使用行级别请求状态
|
||||||
|
const requestCode = Number(row?.requestStatus);
|
||||||
if (REQUEST_STATUS_DISPLAY[requestCode]) {
|
if (REQUEST_STATUS_DISPLAY[requestCode]) {
|
||||||
return REQUEST_STATUS_DISPLAY[requestCode];
|
return REQUEST_STATUS_DISPLAY[requestCode];
|
||||||
}
|
}
|
||||||
// 4. 兼容旧后端枚举文本(如"已发送"→"已签发")
|
// 3. 兼容旧后端枚举文本(如"已发送"→"已签发")
|
||||||
return LEGACY_STATUS_TEXT[row?.requestStatus_enumText] || row?.requestStatus_enumText || '';
|
return LEGACY_STATUS_TEXT[row?.requestStatus_enumText] || row?.requestStatus_enumText || '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user