fix bug434:门诊手术安排:编辑弹窗中“切口类型”字段未正确回显数据
bug426:门诊医生站-检查开立:已选择列表应支持树形展开,显示套餐明细 bug439:领用出库:选择领用药品后“总库存数量”列数据未显示 bug457:门诊收费:已签发的手术类医嘱在门诊收费列表中不显示项目名称
This commit is contained in:
@@ -7,7 +7,6 @@ import com.core.common.core.domain.R;
|
|||||||
import com.core.common.core.domain.model.LoginUser;
|
import com.core.common.core.domain.model.LoginUser;
|
||||||
import com.core.common.utils.SecurityUtils;
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.openhis.administration.domain.Patient;
|
import com.openhis.administration.domain.Patient;
|
||||||
import com.openhis.administration.service.IOrganizationService;
|
|
||||||
import com.openhis.administration.service.IPatientService;
|
import com.openhis.administration.service.IPatientService;
|
||||||
import com.openhis.clinical.domain.Surgery;
|
import com.openhis.clinical.domain.Surgery;
|
||||||
import com.openhis.clinical.service.ISurgeryService;
|
import com.openhis.clinical.service.ISurgeryService;
|
||||||
@@ -28,7 +27,6 @@ import java.io.IOException;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -204,6 +202,8 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
return R.fail("新增手术安排失败");
|
return R.fail("新增手术安排失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncSurgeryIncisionLevel(opSchedule.getOperCode(), opCreateScheduleDto.getIncisionLevel());
|
||||||
|
|
||||||
// Bug #247 修复:更新手术申请单状态为已排期 (1)
|
// Bug #247 修复:更新手术申请单状态为已排期 (1)
|
||||||
if (opCreateScheduleDto.getApplyId() != null) {
|
if (opCreateScheduleDto.getApplyId() != null) {
|
||||||
try {
|
try {
|
||||||
@@ -300,6 +300,8 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
return R.fail("修改手术安排失败");
|
return R.fail("修改手术安排失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
syncSurgeryIncisionLevel(opScheduleDto.getOperCode(), opScheduleDto.getIncisionLevel());
|
||||||
|
|
||||||
return R.ok("修改手术安排成功");
|
return R.ok("修改手术安排成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -433,6 +435,28 @@ public class SurgicalScheduleAppServiceImpl implements ISurgicalScheduleAppServi
|
|||||||
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
return scheduleDate.format(java.time.format.DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步手术申请表中的切口类型
|
||||||
|
*/
|
||||||
|
private void syncSurgeryIncisionLevel(String surgeryNo, Integer incisionLevel) {
|
||||||
|
if (surgeryNo == null || surgeryNo.isEmpty() || incisionLevel == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaQueryWrapper<Surgery> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.eq(Surgery::getSurgeryNo, surgeryNo)
|
||||||
|
.eq(Surgery::getDeleteFlag, "0");
|
||||||
|
Surgery surgery = surgeryService.getOne(queryWrapper);
|
||||||
|
if (surgery == null) {
|
||||||
|
log.warn("未找到需要同步切口类型的手术申请记录 - surgeryNo: {}", surgeryNo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
surgery.setIncisionLevel(incisionLevel);
|
||||||
|
surgery.setUpdateTime(new Date());
|
||||||
|
surgeryService.updateById(surgery);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 填充手术申请中缺失的名称字段
|
* 填充手术申请中缺失的名称字段
|
||||||
* 在创建手术安排时调用,确保关联的cli_surgery表中的名称字段有值
|
* 在创建手术安排时调用,确保关联的cli_surgery表中的名称字段有值
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonFormat;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -85,6 +84,11 @@ public class OpCreateScheduleDto {
|
|||||||
*/
|
*/
|
||||||
private String surgerySite;
|
private String surgerySite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切口类型
|
||||||
|
*/
|
||||||
|
private Integer incisionLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入院时间
|
* 入院时间
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -93,6 +93,12 @@ public class OpScheduleDto extends OpSchedule {
|
|||||||
* 手术类型
|
* 手术类型
|
||||||
*/
|
*/
|
||||||
private String surgeryType;
|
private String surgeryType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切口类型
|
||||||
|
*/
|
||||||
|
private Integer incisionLevel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 申请科室
|
* 申请科室
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import com.openhis.medication.service.IMedicationDispenseService;
|
|||||||
import com.openhis.medication.service.IMedicationRequestService;
|
import com.openhis.medication.service.IMedicationRequestService;
|
||||||
import com.openhis.web.chargemanage.mapper.OutpatientRegistrationAppMapper;
|
import com.openhis.web.chargemanage.mapper.OutpatientRegistrationAppMapper;
|
||||||
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
|
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
|
||||||
|
import com.openhis.web.doctorstation.appservice.IDoctorStationInspectionLabApplyService;
|
||||||
import com.openhis.web.doctorstation.dto.*;
|
import com.openhis.web.doctorstation.dto.*;
|
||||||
import com.openhis.web.doctorstation.mapper.DoctorStationAdviceAppMapper;
|
import com.openhis.web.doctorstation.mapper.DoctorStationAdviceAppMapper;
|
||||||
import com.openhis.web.doctorstation.utils.AdviceUtils;
|
import com.openhis.web.doctorstation.utils.AdviceUtils;
|
||||||
@@ -47,12 +48,15 @@ import com.openhis.workflow.domain.InventoryItem;
|
|||||||
import com.openhis.workflow.domain.ServiceRequest;
|
import com.openhis.workflow.domain.ServiceRequest;
|
||||||
import com.openhis.workflow.service.*;
|
import com.openhis.workflow.service.*;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,6 +66,9 @@ import java.util.stream.Collectors;
|
|||||||
@Service
|
@Service
|
||||||
public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAppService {
|
public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAppService {
|
||||||
|
|
||||||
|
private static final Pattern INSPECTION_APPLY_NO_JSON =
|
||||||
|
Pattern.compile("\"applyNo\"\\s*:\\s*\"([^\"]+)\"");
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
AssignSeqUtil assignSeqUtil;
|
AssignSeqUtil assignSeqUtil;
|
||||||
|
|
||||||
@@ -118,6 +125,13 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
@Resource
|
@Resource
|
||||||
IInventoryItemService inventoryItemService;
|
IInventoryItemService inventoryItemService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与检验申请实现存在循环依赖,需延迟注入;删除诊疗医嘱时按 contentJson 级联作废检验申请单。
|
||||||
|
*/
|
||||||
|
@Resource
|
||||||
|
@Lazy
|
||||||
|
private IDoctorStationInspectionLabApplyService iDoctorStationInspectionLabApplyService;
|
||||||
|
|
||||||
// 缓存 key 前缀
|
// 缓存 key 前缀
|
||||||
private static final String ADVICE_BASE_INFO_CACHE_PREFIX = "advice:base:info:";
|
private static final String ADVICE_BASE_INFO_CACHE_PREFIX = "advice:base:info:";
|
||||||
// 缓存过期时间(小时)
|
// 缓存过期时间(小时)
|
||||||
@@ -1696,6 +1710,21 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从诊疗医嘱 contentJson 中解析检验申请单号(检验保存时写入形如 {"applyNo":"..."})。
|
||||||
|
*/
|
||||||
|
private String extractInspectionApplyNoFromContentJson(String contentJson) {
|
||||||
|
if (StringUtils.isBlank(contentJson) || !contentJson.contains("applyNo")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Matcher m = INSPECTION_APPLY_NO_JSON.matcher(contentJson);
|
||||||
|
if (!m.find()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String applyNo = m.group(1).trim();
|
||||||
|
return StringUtils.isBlank(applyNo) ? null : applyNo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理诊疗
|
* 处理诊疗
|
||||||
*/
|
*/
|
||||||
@@ -1744,6 +1773,8 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 检验申请单在医嘱 contentJson 中写入 applyNo;从医嘱删除时需先级联作废检验单,避免检验页签仍显示孤儿申请
|
||||||
|
Map<String, List<Long>> labApplyNoToRequestIds = new LinkedHashMap<>();
|
||||||
for (AdviceSaveDto adviceSaveDto : deleteList) {
|
for (AdviceSaveDto adviceSaveDto : deleteList) {
|
||||||
Long requestId = adviceSaveDto.getRequestId();
|
Long requestId = adviceSaveDto.getRequestId();
|
||||||
// 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的诊疗请求
|
// 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的诊疗请求
|
||||||
@@ -1752,6 +1783,35 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
iServiceRequestService.removeById(requestId);// 删除诊疗
|
iServiceRequestService.removeById(requestId);// 删除诊疗
|
||||||
|
ServiceRequest existing = iServiceRequestService.getById(adviceSaveDto.getRequestId());
|
||||||
|
if (existing == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String applyNo = extractInspectionApplyNoFromContentJson(existing.getContentJson());
|
||||||
|
if (StringUtils.isNotBlank(applyNo)) {
|
||||||
|
labApplyNoToRequestIds.computeIfAbsent(applyNo, k -> new ArrayList<>())
|
||||||
|
.add(adviceSaveDto.getRequestId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Set<Long> labCascadeSkippedRequestIds = new HashSet<>();
|
||||||
|
for (Map.Entry<String, List<Long>> e : labApplyNoToRequestIds.entrySet()) {
|
||||||
|
R<?> delLab = iDoctorStationInspectionLabApplyService.deleteInspectionLabApply(e.getKey());
|
||||||
|
if (delLab != null && R.isSuccess(delLab)) {
|
||||||
|
labCascadeSkippedRequestIds.addAll(e.getValue());
|
||||||
|
log.info("handService - 级联作废检验申请单 applyNo={},已跳过重复删除的医嘱 requestIds={}",
|
||||||
|
e.getKey(), e.getValue());
|
||||||
|
} else {
|
||||||
|
String msg = delLab != null && StringUtils.isNotEmpty(delLab.getMsg()) ? delLab.getMsg() : "删除检验申请单失败";
|
||||||
|
log.warn("handService - 级联作废检验申请单未成功 applyNo={} msg={},将回退为仅删除当前医嘱记录",
|
||||||
|
e.getKey(), msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (AdviceSaveDto adviceSaveDto : deleteList) {
|
||||||
|
if (labCascadeSkippedRequestIds.contains(adviceSaveDto.getRequestId())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Long requestId = adviceSaveDto.getRequestId();
|
||||||
|
iServiceRequestService.removeById(requestId);// 删除诊疗
|
||||||
iServiceRequestService.remove(
|
iServiceRequestService.remove(
|
||||||
new LambdaQueryWrapper<ServiceRequest>().eq(ServiceRequest::getParentId,
|
new LambdaQueryWrapper<ServiceRequest>().eq(ServiceRequest::getParentId,
|
||||||
requestId));// 删除诊疗套餐对应的子项
|
requestId));// 删除诊疗套餐对应的子项
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public class NursingRecordController {
|
|||||||
* 获取住院患者信息 分页显示
|
* 获取住院患者信息 分页显示
|
||||||
*
|
*
|
||||||
* @param nursingSearchParam 查询参数
|
* @param nursingSearchParam 查询参数
|
||||||
|
*
|
||||||
* @param searchKey 模糊查询
|
* @param searchKey 模糊查询
|
||||||
* @param pageNo 当前页码
|
* @param pageNo 当前页码
|
||||||
* @param pageSize 查询条数
|
* @param pageSize 查询条数
|
||||||
|
|||||||
@@ -97,6 +97,10 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN COALESCE(
|
||||||
|
wsr.content_json::json->>'surgeryName',
|
||||||
|
wsr.content_json::json->>'adviceName',
|
||||||
|
T9sr.surgery_name)
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
@@ -108,6 +112,7 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN NULL
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN NULL
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN NULL
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN NULL
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
WHEN T1.context_enum = 6 THEN T2.yb_no
|
WHEN T1.context_enum = 6 THEN T2.yb_no
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
@@ -118,6 +123,7 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.id
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.id
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.id
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.id
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN COALESCE(T9sr.id, wsr.activity_id)
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
||||||
WHEN T1.context_enum = 6 THEN T2.id
|
WHEN T1.context_enum = 6 THEN T2.id
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
||||||
@@ -159,6 +165,11 @@
|
|||||||
LEFT JOIN med_medication_request AS mmr ON mmr.id = T1.service_id AND mmr.delete_flag = '0'
|
LEFT JOIN med_medication_request AS mmr ON mmr.id = T1.service_id AND mmr.delete_flag = '0'
|
||||||
LEFT JOIN wor_device_request AS wdr ON wdr.id = T1.service_id AND wdr.delete_flag = '0'
|
LEFT JOIN wor_device_request AS wdr ON wdr.id = T1.service_id AND wdr.delete_flag = '0'
|
||||||
LEFT JOIN wor_service_request AS wsr ON wsr.id = T1.service_id AND wsr.delete_flag = '0'
|
LEFT JOIN wor_service_request AS wsr ON wsr.id = T1.service_id AND wsr.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_surgery AS T9sr ON T1.context_enum = 6
|
||||||
|
AND T1.service_table = 'wor_service_request'
|
||||||
|
AND wsr.activity_id IS NOT NULL
|
||||||
|
AND wsr.activity_id = T9sr.id
|
||||||
|
AND T9sr.delete_flag = '0'
|
||||||
LEFT JOIN wor_service_request AS wsrp ON wsrp.id = wsr.parent_id AND wsrp.delete_flag = '0'
|
LEFT JOIN wor_service_request AS wsrp ON wsrp.id = wsr.parent_id AND wsrp.delete_flag = '0'
|
||||||
WHERE T1.encounter_id = #{encounterId}
|
WHERE T1.encounter_id = #{encounterId}
|
||||||
AND T1.status_enum IN (0
|
AND T1.status_enum IN (0
|
||||||
@@ -223,6 +234,10 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.surgery_name
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN COALESCE(
|
||||||
|
wsr.content_json::json->>'surgeryName',
|
||||||
|
wsr.content_json::json->>'adviceName',
|
||||||
|
T9sr.surgery_name)
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
@@ -234,6 +249,7 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN NULL
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN NULL
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN NULL
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN NULL
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
WHEN T1.context_enum = 6 THEN T2.yb_no
|
WHEN T1.context_enum = 6 THEN T2.yb_no
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN NULL
|
||||||
@@ -244,6 +260,7 @@
|
|||||||
CASE
|
CASE
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.id
|
WHEN T1.context_enum = #{activity} AND T1.product_table = 'cli_surgery' THEN T9.id
|
||||||
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.id
|
WHEN T1.context_enum = 6 AND T1.product_table = 'cli_surgery' THEN T9.id
|
||||||
|
WHEN T1.context_enum = 6 AND T1.service_table = 'wor_service_request' THEN COALESCE(T9sr.id, wsr.activity_id)
|
||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
||||||
WHEN T1.context_enum = 6 THEN T2.id
|
WHEN T1.context_enum = 6 THEN T2.id
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN 0
|
||||||
@@ -286,6 +303,11 @@
|
|||||||
LEFT JOIN med_medication_request AS mmr ON mmr.id = T1.service_id AND mmr.delete_flag = '0'
|
LEFT JOIN med_medication_request AS mmr ON mmr.id = T1.service_id AND mmr.delete_flag = '0'
|
||||||
LEFT JOIN wor_device_request AS wdr ON wdr.id = T1.service_id AND wdr.delete_flag = '0'
|
LEFT JOIN wor_device_request AS wdr ON wdr.id = T1.service_id AND wdr.delete_flag = '0'
|
||||||
LEFT JOIN wor_service_request AS wsr ON wsr.id = T1.service_id AND wsr.delete_flag = '0'
|
LEFT JOIN wor_service_request AS wsr ON wsr.id = T1.service_id AND wsr.delete_flag = '0'
|
||||||
|
LEFT JOIN cli_surgery AS T9sr ON T1.context_enum = 6
|
||||||
|
AND T1.service_table = 'wor_service_request'
|
||||||
|
AND wsr.activity_id IS NOT NULL
|
||||||
|
AND wsr.activity_id = T9sr.id
|
||||||
|
AND T9sr.delete_flag = '0'
|
||||||
WHERE T1.encounter_id = #{encounterId}
|
WHERE T1.encounter_id = #{encounterId}
|
||||||
AND T1.status_enum IN (0
|
AND T1.status_enum IN (0
|
||||||
, #{planned}
|
, #{planned}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@
|
|||||||
</if>
|
</if>
|
||||||
AND os.delete_flag = '0'
|
AND os.delete_flag = '0'
|
||||||
</where>
|
</where>
|
||||||
ORDER BY os.create_time DESC
|
ORDER BY os.create_time DESC, os.schedule_id DESC
|
||||||
</select>
|
</select>
|
||||||
<!-- 根据ID查询手术安排详情-->
|
<!-- 根据ID查询手术安排详情-->
|
||||||
<select id="getSurgeryScheduleDetail" resultType="com.openhis.web.clinicalmanage.dto.OpScheduleDto">
|
<select id="getSurgeryScheduleDetail" resultType="com.openhis.web.clinicalmanage.dto.OpScheduleDto">
|
||||||
@@ -89,6 +89,8 @@
|
|||||||
cs.apply_doctor_name AS apply_doctor_name,
|
cs.apply_doctor_name AS apply_doctor_name,
|
||||||
drf.create_time AS apply_time,
|
drf.create_time AS apply_time,
|
||||||
os.surgery_nature AS surgeryType,
|
os.surgery_nature AS surgeryType,
|
||||||
|
cs.incision_level AS incisionLevel,
|
||||||
|
fc.contract_name AS feeType,
|
||||||
os.fee_type AS feeType,
|
os.fee_type AS feeType,
|
||||||
COALESCE(pi.identifier_no, ap.bus_no, '') AS identifierNo
|
COALESCE(pi.identifier_no, ap.bus_no, '') AS identifierNo
|
||||||
FROM op_schedule os
|
FROM op_schedule os
|
||||||
@@ -183,7 +185,7 @@
|
|||||||
<if test="dto.applyDeptId != null and dto.applyDeptId != ''"> AND cs.apply_dept_id = #{dto.applyDeptId}</if>
|
<if test="dto.applyDeptId != null and dto.applyDeptId != ''"> AND cs.apply_dept_id = #{dto.applyDeptId}</if>
|
||||||
<if test="dto.patientName != null and dto.patientName != ''"> AND ap.name LIKE CONCAT('%', #{dto.patientName}, '%')</if>
|
<if test="dto.patientName != null and dto.patientName != ''"> AND ap.name LIKE CONCAT('%', #{dto.patientName}, '%')</if>
|
||||||
</where>
|
</where>
|
||||||
ORDER BY os.create_time DESC
|
ORDER BY os.create_time DESC, os.schedule_id DESC
|
||||||
</select>
|
</select>
|
||||||
<!-- 查询时间段内该手术室是否被占用-->
|
<!-- 查询时间段内该手术室是否被占用-->
|
||||||
<select id="isScheduleConflict" resultType="java.lang.Boolean">
|
<select id="isScheduleConflict" resultType="java.lang.Boolean">
|
||||||
|
|||||||
@@ -278,16 +278,33 @@
|
|||||||
<el-input v-model="scope.row.applyPart" size="small" />
|
<el-input v-model="scope.row.applyPart" size="small" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="检查方法" min-width="120">
|
<el-table-column label="检查方法" min-width="160">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<!-- Bug #384修复: 显示检查方法名称,不显示套餐名称 -->
|
<el-select
|
||||||
<span v-if="scope.row.selectedMethod">
|
v-if="scope.row.methods && scope.row.methods.length > 1"
|
||||||
{{ scope.row.selectedMethod.name }}
|
:model-value="scope.row.selectedMethod"
|
||||||
</span>
|
value-key="id"
|
||||||
<span v-else-if="scope.row.methods && scope.row.methods.length > 0" style="color: #909399;">
|
size="small"
|
||||||
未选择
|
style="width: 100%"
|
||||||
</span>
|
placeholder="选择方法"
|
||||||
<span v-else style="color: #c0c4cc;">-</span>
|
@update:model-value="(val) => onDetailMethodChange(scope.row, val)"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="meth in scope.row.methods"
|
||||||
|
:key="meth.id"
|
||||||
|
:label="`${meth.name}${meth.packagePrice != null ? ' ¥' + formatDetailAmount(meth.packagePrice) : ''}`"
|
||||||
|
:value="meth"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
<template v-else>
|
||||||
|
<span v-if="scope.row.selectedMethod">
|
||||||
|
{{ scope.row.selectedMethod.name }}
|
||||||
|
</span>
|
||||||
|
<span v-else-if="scope.row.methods && scope.row.methods.length > 0" style="color: #909399;">
|
||||||
|
未选择
|
||||||
|
</span>
|
||||||
|
<span v-else style="color: #c0c4cc;">-</span>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="单位" prop="unit" width="55" align="center" />
|
<el-table-column label="单位" prop="unit" width="55" align="center" />
|
||||||
@@ -412,58 +429,48 @@
|
|||||||
v-for="(item, idx) in selectedItems"
|
v-for="(item, idx) in selectedItems"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
class="selected-item-card"
|
class="selected-item-card"
|
||||||
|
:class="{ 'is-expanded': item.expanded }"
|
||||||
>
|
>
|
||||||
<!-- Bug #384修复 + #426修复: 项目卡片头部,可展开/收起 -->
|
<!-- Bug #384修复 + #426修复: 项目卡片头部,可展开/收起 -->
|
||||||
<div class="card-header" @click="toggleItemExpand(item)">
|
<div class="card-header" @click="toggleItemExpand(item)">
|
||||||
<el-tag v-if="item.isPackage || item.packageName" size="small" type="warning" style="margin-right: 4px; flex-shrink: 0;">套餐</el-tag>
|
<el-tag v-if="item.isPackage || item.packageName" size="small" type="warning" style="margin-right: 4px; flex-shrink: 0;">套餐</el-tag>
|
||||||
<span class="card-name">{{ item.name }}</span>
|
<el-tooltip :content="item.name" placement="top" :show-after="400">
|
||||||
<span class="card-price">¥{{ item.price }}</span>
|
<span class="card-name">{{ item.name }}</span>
|
||||||
<!-- 展开/收起图标 -->
|
</el-tooltip>
|
||||||
<el-icon class="expand-icon" :class="{ expanded: item.expanded }">
|
<span class="card-price">¥{{ formatDetailAmount(item.price) }}</span>
|
||||||
<ArrowRight />
|
<el-icon :class="['expand-icon', { expanded: item.expanded }]">
|
||||||
|
<ArrowDown v-if="!item.expanded" />
|
||||||
|
<ArrowUp v-if="item.expanded" />
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<!-- 删除按钮 -->
|
<!-- 删除按钮 -->
|
||||||
<el-button link type="danger" size="small" @click.stop="handleRemoveItem(idx, item)">
|
<el-button link type="danger" size="small" @click.stop="handleRemoveItem(idx, item)">
|
||||||
<el-icon><Close /></el-icon>
|
<el-icon><Close /></el-icon>
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
<!-- Bug #428修复 + #426修复: 展开后显示套餐明细或检查方法 -->
|
<!-- Bug #428: 有套餐 ID 时默认展开;加载中/空/明细均在本区域展示 -->
|
||||||
<div v-show="item.expanded" class="expanded-content">
|
<div v-if="item.expanded && shouldShowPackageBody(item)" class="selected-card-body">
|
||||||
<!-- 显示套餐明细 -->
|
<div v-if="item.packageDetailsLoading" class="package-details-loading">加载中...</div>
|
||||||
<div v-if="(item.isPackage || item.packageName) && item.packageDetails && item.packageDetails.length > 0" class="package-details-list">
|
<template v-else>
|
||||||
<div class="detail-row" v-for="detail in item.packageDetails" :key="detail.id">
|
<div v-if="getPackageDetailsList(item).length === 0" class="package-details-empty">
|
||||||
<span class="detail-name">{{ detail.name }}</span>
|
暂无套餐明细
|
||||||
<span class="detail-info">数量: {{ detail.quantity }} 单价: ¥{{ detail.price }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div v-else class="package-details-list">
|
||||||
<!-- 套餐明细加载中 -->
|
<div class="package-details-head">套餐明细</div>
|
||||||
<div v-else-if="(item.isPackage || item.packageName) && item.packageDetailsLoading" class="package-loading-hint">
|
<div
|
||||||
加载中...
|
v-for="(detail, dIdx) in getPackageDetailsList(item)"
|
||||||
</div>
|
:key="detail.id ?? detail.itemCode ?? `d-${dIdx}`"
|
||||||
<!-- 显示检查方法 -->
|
class="detail-row"
|
||||||
<div v-else-if="item.methods && item.methods.length > 0" class="method-list">
|
>
|
||||||
<div v-for="method in item.methods" :key="method.id" class="method-option">
|
<el-tooltip :content="detail.name" placement="top" :show-after="500">
|
||||||
<el-checkbox :model-value="item.selectedMethod?.id === method.id" @change="(val) => selectMethodCheckbox(val, item, method)">
|
<span class="detail-name">{{ detail.name }}</span>
|
||||||
<span class="method-name">{{ method.name }}</span>
|
</el-tooltip>
|
||||||
<span class="method-price">¥{{ method.packagePrice || item.price }}</span>
|
<div class="detail-meta">
|
||||||
</el-checkbox>
|
<span class="detail-qty">×{{ detail.quantity || 1 }}</span>
|
||||||
</div>
|
<span class="detail-price">¥{{ formatDetailAmount(detail.price) }}</span>
|
||||||
<!-- 选中方法后,显示对应的套餐明细 -->
|
</div>
|
||||||
<div v-if="item.selectedMethod && item.methodPackageDetails && item.methodPackageDetails.length > 0" class="method-package-details">
|
|
||||||
<div class="method-package-header">
|
|
||||||
<span class="method-package-title">套餐明细 - {{ item.selectedMethod.name }}</span>
|
|
||||||
</div>
|
|
||||||
<div v-for="detail in item.methodPackageDetails" :key="detail.id" class="method-option">
|
|
||||||
<el-checkbox v-model="detail.checked">
|
|
||||||
<span class="method-name">{{ detail.name }}</span>
|
|
||||||
<span class="method-price">数量: {{ detail.quantity }} ¥{{ detail.price }}</span>
|
|
||||||
</el-checkbox>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="item.selectedMethod && item.methodPackageLoading" class="method-package-loading">
|
</template>
|
||||||
加载套餐明细中...
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -477,7 +484,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue';
|
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { Printer, Delete, ArrowDown, ArrowUp, Close, ArrowRight } from '@element-plus/icons-vue';
|
import { Printer, Delete, ArrowDown, ArrowUp, Close } from '@element-plus/icons-vue';
|
||||||
import useUserStore from '@/store/modules/user';
|
import useUserStore from '@/store/modules/user';
|
||||||
import request from '@/utils/request';
|
import request from '@/utils/request';
|
||||||
import { listCheckMethod, searchCheckMethod, listCheckPackage } from '@/api/system/checkType';
|
import { listCheckMethod, searchCheckMethod, listCheckPackage } from '@/api/system/checkType';
|
||||||
@@ -568,21 +575,22 @@ handleResetSearch();
|
|||||||
|
|
||||||
// 🔧 BugFix#426: 懒加载套餐明细
|
// 🔧 BugFix#426: 懒加载套餐明细
|
||||||
async function loadPackageDetails(row, treeNode, resolve) {
|
async function loadPackageDetails(row, treeNode, resolve) {
|
||||||
if (!row.isPackage || !row.packageId) {
|
if (!row.packageId) {
|
||||||
resolve([]);
|
resolve([]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await request({
|
const res = await request({
|
||||||
url: `/system/package/${row.packageId}/details`,
|
url: `/system/check-type/package/${row.packageId}/details`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200) {
|
||||||
const children = res.data.map(item => ({
|
const list = parsePackageDetailsPayload(res);
|
||||||
...item,
|
const children = list.map((child) => ({
|
||||||
name: item.name || item.itemName,
|
...child,
|
||||||
unit: item.unit || '次',
|
name: child.name || child.itemName,
|
||||||
price: item.price || item.itemPrice || 0,
|
unit: child.unit || '次',
|
||||||
|
price: child.price ?? child.unitPrice ?? child.itemPrice ?? 0,
|
||||||
quantity: row.quantity || 1,
|
quantity: row.quantity || 1,
|
||||||
isPackageDetail: true
|
isPackageDetail: true
|
||||||
}));
|
}));
|
||||||
@@ -597,16 +605,68 @@ async function loadPackageDetails(row, treeNode, resolve) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #428修复 + #426修复: 为已选择项目加载套餐明细(通过packageId或packageName查询)
|
// #428修复 + #426修复: 为已选择项目加载套餐明细(通过packageId或packageName查询)
|
||||||
|
/** 套餐明细挂在「部位」或已选的「检查方法」上(方法可带 packageId) */
|
||||||
|
function getPackageCarrier(item) {
|
||||||
|
return item?.selectedMethod?.packageId ? item.selectedMethod : item;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPackageDetailsList(item) {
|
||||||
|
// 明细挂在行对象上,避免仅写入 methods 内嵌对象时首帧不触发视图更新(体感需点两次才展开)
|
||||||
|
if (Array.isArray(item?.packageDetailsDisplay)) {
|
||||||
|
return item.packageDetailsDisplay;
|
||||||
|
}
|
||||||
|
const carrier = getPackageCarrier(item);
|
||||||
|
return Array.isArray(carrier?.packageDetails) ? carrier.packageDetails : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 有套餐 ID 的已选行才展示右侧套餐区(加载中 / 空 / 明细列表) */
|
||||||
|
function shouldShowPackageBody(item) {
|
||||||
|
return !!getPackageCarrier(item)?.packageId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 金额展示:统一两位小数 */
|
||||||
|
function formatDetailAmount(value) {
|
||||||
|
const n = Number(value ?? 0);
|
||||||
|
return Number.isFinite(n) ? n.toFixed(2) : '0.00';
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 默认检查方法:优先与部位 packageId 一致的方法,否则取首个带套餐的方法,否则取第一个 */
|
||||||
|
function pickDefaultMethod(methods, partItem) {
|
||||||
|
if (!methods?.length) return null;
|
||||||
|
if (methods.length === 1) return methods[0];
|
||||||
|
const pid = partItem?.packageId ?? null;
|
||||||
|
if (pid != null && pid !== '') {
|
||||||
|
const matched = methods.find(
|
||||||
|
(x) => x.packageId != null && String(x.packageId) === String(pid)
|
||||||
|
);
|
||||||
|
if (matched) return matched;
|
||||||
|
}
|
||||||
|
const withPkg = methods.find((x) => x.packageId != null);
|
||||||
|
if (withPkg) return withPkg;
|
||||||
|
return methods[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function parsePackageDetailsPayload(res) {
|
||||||
|
const raw =
|
||||||
|
res?.data?.data ??
|
||||||
|
res?.data?.records ??
|
||||||
|
res?.data ??
|
||||||
|
res?.rows ??
|
||||||
|
res;
|
||||||
|
if (!Array.isArray(raw)) return [];
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #428: 为已选择项目加载套餐明细(后端:CheckTypeController /system/check-type/package/{id}/details)
|
||||||
async function loadPackageDetailsForItem(item) {
|
async function loadPackageDetailsForItem(item) {
|
||||||
// 只要有 packageName 就认为是套餐,不强制要求 isPackage 或 packageId
|
const carrier = getPackageCarrier(item);
|
||||||
if (!item.packageName && !item.packageId) {
|
let packageId = item.packageId || carrier?.packageId;
|
||||||
|
if (!packageId && !item.packageName) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
item.packageDetailsLoading = true;
|
item.packageDetailsLoading = true;
|
||||||
try {
|
try {
|
||||||
let packageId = item.packageId;
|
|
||||||
if (!packageId && item.packageName) {
|
if (!packageId && item.packageName) {
|
||||||
// CheckPart 没有 packageId 字段,需要通过 packageName 查询获取
|
|
||||||
const pkgRes = await listCheckPackage({ packageName: item.packageName });
|
const pkgRes = await listCheckPackage({ packageName: item.packageName });
|
||||||
let packages = pkgRes?.data || [];
|
let packages = pkgRes?.data || [];
|
||||||
if (!Array.isArray(packages)) {
|
if (!Array.isArray(packages)) {
|
||||||
@@ -614,31 +674,48 @@ async function loadPackageDetailsForItem(item) {
|
|||||||
}
|
}
|
||||||
if (packages.length === 0) {
|
if (packages.length === 0) {
|
||||||
item.packageDetails = [];
|
item.packageDetails = [];
|
||||||
|
item.packageDetailsDisplay = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
packageId = packages[0].id;
|
packageId = packages[0].id;
|
||||||
|
item.packageId = packageId;
|
||||||
}
|
}
|
||||||
if (!packageId) {
|
if (!packageId) {
|
||||||
item.packageDetails = [];
|
item.packageDetails = [];
|
||||||
|
item.packageDetailsDisplay = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await request({
|
const res = await request({
|
||||||
url: `/system/package/${packageId}/details`,
|
url: `/system/check-type/package/${packageId}/details`,
|
||||||
method: 'get'
|
method: 'get'
|
||||||
});
|
});
|
||||||
|
const list = parsePackageDetailsPayload(res);
|
||||||
|
const mapped = list.map((detail) => ({
|
||||||
|
...detail,
|
||||||
|
name: detail.name || detail.itemName,
|
||||||
|
unit: detail.unit || '次',
|
||||||
|
price: detail.price ?? detail.unitPrice ?? detail.itemPrice ?? 0,
|
||||||
|
quantity: detail.quantity || 1
|
||||||
|
}));
|
||||||
|
item.packageDetailsDisplay = mapped;
|
||||||
|
carrier.packageDetails = mapped;
|
||||||
if (res.code === 200 && res.data) {
|
if (res.code === 200 && res.data) {
|
||||||
item.packageDetails = res.data.map(detail => ({
|
item.packageDetails = Array.isArray(res.data)
|
||||||
...detail,
|
? res.data.map((detail) => ({
|
||||||
name: detail.name || detail.itemName,
|
...detail,
|
||||||
unit: detail.unit || '次',
|
name: detail.name || detail.itemName,
|
||||||
price: detail.price || detail.unitPrice || 0,
|
unit: detail.unit || '次',
|
||||||
quantity: detail.quantity || 1
|
price: detail.price || detail.unitPrice || 0,
|
||||||
}));
|
quantity: detail.quantity || 1
|
||||||
|
}))
|
||||||
|
: mapped;
|
||||||
} else {
|
} else {
|
||||||
item.packageDetails = [];
|
item.packageDetails = mapped;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载套餐明细失败:', err);
|
console.error('加载套餐明细失败:', err);
|
||||||
|
item.packageDetailsDisplay = [];
|
||||||
|
carrier.packageDetails = [];
|
||||||
item.packageDetails = [];
|
item.packageDetails = [];
|
||||||
} finally {
|
} finally {
|
||||||
item.packageDetailsLoading = false;
|
item.packageDetailsLoading = false;
|
||||||
@@ -1174,7 +1251,10 @@ function handleRowClick(row) {
|
|||||||
nationalCode: '', checked: true,
|
nationalCode: '', checked: true,
|
||||||
methods: [],
|
methods: [],
|
||||||
selectedMethod: null,
|
selectedMethod: null,
|
||||||
expanded: false // Bug #384修复: 添加展开状态
|
expanded: false,
|
||||||
|
packageDetailsLoading: false,
|
||||||
|
isPackage: false,
|
||||||
|
packageId: null
|
||||||
};
|
};
|
||||||
// 加载该项目的检查方法
|
// 加载该项目的检查方法
|
||||||
if (m.bodyPartCode) {
|
if (m.bodyPartCode) {
|
||||||
@@ -1205,6 +1285,13 @@ function handleRowClick(row) {
|
|||||||
item.packageId = item.selectedMethod.packageId;
|
item.packageId = item.selectedMethod.packageId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!item.selectedMethod && item.methods.length) {
|
||||||
|
item.selectedMethod = pickDefaultMethod(item.methods, { packageId: item.packageId });
|
||||||
|
}
|
||||||
|
if (item.selectedMethod?.packageId) {
|
||||||
|
item.packageId = item.selectedMethod.packageId;
|
||||||
|
item.isPackage = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('加载检查方法失败', err);
|
console.error('加载检查方法失败', err);
|
||||||
@@ -1214,6 +1301,12 @@ function handleRowClick(row) {
|
|||||||
return item;
|
return item;
|
||||||
}));
|
}));
|
||||||
selectedItems.value = itemsWithMethods;
|
selectedItems.value = itemsWithMethods;
|
||||||
|
for (const it of selectedItems.value) {
|
||||||
|
if (getPackageCarrier(it)?.packageId) {
|
||||||
|
await loadPackageDetailsForItem(it);
|
||||||
|
}
|
||||||
|
it.expanded = !!getPackageCarrier(it)?.packageId;
|
||||||
|
}
|
||||||
syncCategoryChecked();
|
syncCategoryChecked();
|
||||||
// Bug #384修复: 回充后更新检查方法显示
|
// Bug #384修复: 回充后更新检查方法显示
|
||||||
updateMethodDisplay();
|
updateMethodDisplay();
|
||||||
@@ -1375,7 +1468,7 @@ async function handleItemSelect(checked, item, cat) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedItems.value.push({
|
const newRow = {
|
||||||
id: item.id, name: item.name,
|
id: item.id, name: item.name,
|
||||||
price: item.price, quantity: 1,
|
price: item.price, quantity: 1,
|
||||||
serviceFee: item.serviceFee || 0,
|
serviceFee: item.serviceFee || 0,
|
||||||
@@ -1386,11 +1479,27 @@ async function handleItemSelect(checked, item, cat) {
|
|||||||
checked: true,
|
checked: true,
|
||||||
methods: methods,
|
methods: methods,
|
||||||
selectedMethod: null,
|
selectedMethod: null,
|
||||||
expanded: false, // Bug #384修复: 新增展开状态,默认不展开
|
expanded: false,
|
||||||
isPackage: !!item.packageName, // Bug #428修复: 标记是否为套餐
|
isPackage: !!(item.packageId || item.packageName),
|
||||||
packageName: item.packageName || null, // Bug #426修复: 套餐名称,用于查找packageId
|
packageName: item.packageName || null,
|
||||||
packageId: item.packageId || null // Bug #428修复: 套餐ID
|
packageDetailsLoading: false,
|
||||||
});
|
packageId: item.packageId || null
|
||||||
|
};
|
||||||
|
selectedItems.value.push(newRow);
|
||||||
|
// 必须用数组里的响应式行,不能继续改局部 newRow:push 后列表内是 proxy,改 raw 对象不会触发右侧卡片更新(会一直卡在「加载中」)
|
||||||
|
const row = selectedItems.value[selectedItems.value.length - 1];
|
||||||
|
|
||||||
|
// 右侧不再展示「检查方法」列表:自动选默认方法(保存、计价仍依赖 selectedMethod)
|
||||||
|
if (methods.length >= 1) {
|
||||||
|
row.selectedMethod = pickDefaultMethod(methods, item);
|
||||||
|
}
|
||||||
|
updateMethodDisplay();
|
||||||
|
|
||||||
|
// 有套餐 ID 时默认展开(先显示加载区,明细写入行对象 packageDetailsDisplay)
|
||||||
|
row.expanded = !!getPackageCarrier(row)?.packageId;
|
||||||
|
if (getPackageCarrier(row)?.packageId) {
|
||||||
|
await loadPackageDetailsForItem(row);
|
||||||
|
}
|
||||||
|
|
||||||
// 自动回填执行科室:按检查项目类型 → 检查类型管理里配置的执行科室
|
// 自动回填执行科室:按检查项目类型 → 检查类型管理里配置的执行科室
|
||||||
if (selectedItems.value.length === 1 && cat?.performDeptName) {
|
if (selectedItems.value.length === 1 && cat?.performDeptName) {
|
||||||
@@ -1414,16 +1523,23 @@ async function handleItemSelect(checked, item, cat) {
|
|||||||
// Bug #384修复 + #426修复: 展开/收起项目卡片
|
// Bug #384修复 + #426修复: 展开/收起项目卡片
|
||||||
async function toggleItemExpand(item) {
|
async function toggleItemExpand(item) {
|
||||||
item.expanded = !item.expanded;
|
item.expanded = !item.expanded;
|
||||||
// 如果是展开且该项目是套餐(通过 isPackage 或 packageName 判断),加载套餐明细
|
|
||||||
if (item.expanded && (item.isPackage || item.packageName) && (!item.packageDetails || item.packageDetails.length === 0) && !item.packageDetailsLoading) {
|
if (item.expanded && (item.isPackage || item.packageName) && (!item.packageDetails || item.packageDetails.length === 0) && !item.packageDetailsLoading) {
|
||||||
await loadPackageDetailsForItem(item);
|
await loadPackageDetailsForItem(item);
|
||||||
}
|
}
|
||||||
|
if (item.expanded && shouldShowPackageBody(item)) {
|
||||||
|
if (getPackageDetailsList(item).length === 0 && !item.packageDetailsLoading) {
|
||||||
|
await loadPackageDetailsForItem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bug #384修复: 勾选框选择检查方法(单选逻辑)
|
// Bug #384修复: 勾选框选择检查方法(单选逻辑)
|
||||||
async function selectMethodCheckbox(checked, item, method) {
|
async function selectMethodCheckbox(checked, item, method) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
item.selectedMethod = method;
|
item.selectedMethod = method;
|
||||||
|
if (item.expanded && method.packageId) {
|
||||||
|
loadPackageDetailsForItem(item);
|
||||||
|
}
|
||||||
// 动态加载该方法对应的套餐明细
|
// 动态加载该方法对应的套餐明细
|
||||||
await loadMethodPackageDetails(item, method);
|
await loadMethodPackageDetails(item, method);
|
||||||
} else {
|
} else {
|
||||||
@@ -1483,6 +1599,28 @@ async function loadMethodPackageDetails(item, method) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 检查明细表格中切换检查方法 */
|
||||||
|
async function onDetailMethodChange(row, val) {
|
||||||
|
row.selectedMethod = val || null;
|
||||||
|
if (val?.packageId) {
|
||||||
|
row.packageId = val.packageId;
|
||||||
|
row.isPackage = true;
|
||||||
|
}
|
||||||
|
row.packageDetailsDisplay = undefined;
|
||||||
|
const carrier = getPackageCarrier(row);
|
||||||
|
if (carrier) {
|
||||||
|
carrier.packageDetails = undefined;
|
||||||
|
}
|
||||||
|
updateMethodDisplay();
|
||||||
|
row.expanded = !!getPackageCarrier(row)?.packageId;
|
||||||
|
if (getPackageCarrier(row)?.packageId) {
|
||||||
|
await loadPackageDetailsForItem(row);
|
||||||
|
}
|
||||||
|
nextTick(() => {
|
||||||
|
form.totalAmount = totalAmountCalc.value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Bug #384修复: 更新检查方法显示字段(联动)
|
// Bug #384修复: 更新检查方法显示字段(联动)
|
||||||
function updateMethodDisplay() {
|
function updateMethodDisplay() {
|
||||||
// 找到第一个有选中检查方法的项目
|
// 找到第一个有选中检查方法的项目
|
||||||
@@ -1627,7 +1765,7 @@ defineExpose({ getList });
|
|||||||
|
|
||||||
/* 右:分类面板 */
|
/* 右:分类面板 */
|
||||||
.category-panel {
|
.category-panel {
|
||||||
width: 380px;
|
width: 420px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@@ -1763,8 +1901,11 @@ defineExpose({ getList });
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 已选择 tags */
|
/* 已选择 tags */
|
||||||
|
/* 已选择:加宽,避免套餐明细挤成一团 */
|
||||||
.selected-panel {
|
.selected-panel {
|
||||||
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
width: 220px;
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 280px;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -1772,9 +1913,11 @@ defineExpose({ getList });
|
|||||||
.selected-tags {
|
.selected-tags {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 6px;
|
gap: 8px;
|
||||||
|
padding-right: 2px;
|
||||||
}
|
}
|
||||||
.selected-tag {
|
.selected-tag {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
@@ -1787,30 +1930,40 @@ defineExpose({ getList });
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #384修复: 已选择项目卡片(可展开) */
|
/* 已选择项目卡片 */
|
||||||
.selected-item-card {
|
.selected-item-card {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: #F5F5F5;
|
background: #fff;
|
||||||
border-radius: 4px;
|
border-radius: 6px;
|
||||||
border: 1px solid #e4e7ed;
|
border: 1px solid #e4e7ed;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected-item-card .card-header {
|
.selected-item-card .card-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 8px 10px;
|
padding: 10px 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
gap: 4px;
|
gap: 8px;
|
||||||
|
background: linear-gradient(180deg, #f8fafc 0%, #f0f4f8 100%);
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.selected-item-card .card-header:hover {
|
.selected-item-card .card-header:hover {
|
||||||
background: #E6F7FF;
|
background: linear-gradient(180deg, #ecf5ff 0%, #e3eef8 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-item-card.is-expanded .card-header {
|
||||||
|
border-bottom-color: #ebeef5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-name {
|
.card-name {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 12px;
|
min-width: 0;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
color: #303133;
|
color: #303133;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
@@ -1818,14 +1971,17 @@ defineExpose({ getList });
|
|||||||
}
|
}
|
||||||
|
|
||||||
.card-price {
|
.card-price {
|
||||||
font-size: 12px;
|
font-size: 13px;
|
||||||
color: #1890FF;
|
color: #409eff;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.expand-icon {
|
.expand-icon {
|
||||||
font-size: 12px;
|
font-size: 14px;
|
||||||
color: #909399;
|
color: #909399;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
|
flex-shrink: 0;
|
||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
@@ -1834,19 +1990,6 @@ defineExpose({ getList });
|
|||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #426修复: 展开内容容器 */
|
|
||||||
.expanded-content {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bug #426修复: 套餐明细加载提示 */
|
|
||||||
.package-loading-hint {
|
|
||||||
padding: 8px 10px;
|
|
||||||
font-size: 11px;
|
|
||||||
color: #c0c4cc;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bug #428修复: 套餐明细列表样式 */
|
/* Bug #428修复: 套餐明细列表样式 */
|
||||||
.package-details-list {
|
.package-details-list {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
@@ -1882,61 +2025,83 @@ defineExpose({ getList });
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #384修复: 检查方法勾选框列表 */
|
/* 展开区域 */
|
||||||
.method-list {
|
.selected-card-body {
|
||||||
padding: 6px 10px;
|
background: #fafbfc;
|
||||||
background: #fff;
|
}
|
||||||
border-top: 1px solid #e4e7ed;
|
|
||||||
|
.package-details-loading,
|
||||||
|
.package-details-empty {
|
||||||
|
padding: 12px 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-details-empty {
|
||||||
|
color: #c0c4cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-details-list {
|
||||||
|
padding: 10px 10px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-details-head {
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #909399;
|
||||||
|
letter-spacing: 0.02em;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
border-bottom: 1px dashed #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) auto;
|
||||||
|
gap: 8px 12px;
|
||||||
|
align-items: start;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-row:last-of-type {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-name {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #303133;
|
||||||
|
line-height: 1.5;
|
||||||
|
word-break: break-word;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-meta {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: flex-end;
|
||||||
gap: 4px;
|
gap: 4px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-option {
|
.detail-qty {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-option :deep(.el-checkbox__label) {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-option .method-name {
|
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-option .method-price {
|
|
||||||
font-size: 11px;
|
|
||||||
color: #e6a23c;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 选中方法后显示的套餐明细 */
|
|
||||||
.method-package-details {
|
|
||||||
margin-top: 4px;
|
|
||||||
padding: 4px 0;
|
|
||||||
border-top: 1px dashed #dcdfe6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-package-header {
|
|
||||||
padding: 2px 0 4px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-package-title {
|
|
||||||
font-size: 10px;
|
|
||||||
color: #909399;
|
color: #909399;
|
||||||
font-weight: 500;
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-package-loading {
|
.detail-price {
|
||||||
padding: 4px 0 4px 24px;
|
font-size: 12px;
|
||||||
font-size: 10px;
|
font-weight: 600;
|
||||||
color: #c0c4cc;
|
color: #e6a23c;
|
||||||
|
font-variant-numeric: tabular-nums;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 折叠组件细节 */
|
/* 折叠组件细节 */
|
||||||
|
|||||||
@@ -875,7 +875,7 @@ import { ArrowDown, Search, Memo, Minus, Plus, Edit, Delete } from '@element-plu
|
|||||||
import printUtils, { getPrinterList, PRINT_TEMPLATE, savePrinterToCache, } from '@/utils/printUtils';
|
import printUtils, { getPrinterList, PRINT_TEMPLATE, savePrinterToCache, } from '@/utils/printUtils';
|
||||||
import Template from "@/views/inpatientDoctor/home/emr/components/template.vue";
|
import Template from "@/views/inpatientDoctor/home/emr/components/template.vue";
|
||||||
|
|
||||||
const emit = defineEmits(['selectDiagnosis']);
|
const emit = defineEmits(['selectDiagnosis', 'inspectionListRefresh']);
|
||||||
const total = ref(0);
|
const total = ref(0);
|
||||||
const queryParams = ref({});
|
const queryParams = ref({});
|
||||||
const prescriptionList = ref([]);
|
const prescriptionList = ref([]);
|
||||||
@@ -2084,6 +2084,21 @@ function getOrgList() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 诊疗医嘱关联检验申请时 contentJson 含 applyNo */
|
||||||
|
function getInspectionApplyNoFromAdviceRow(row) {
|
||||||
|
if (!row || row.adviceType !== 3) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const raw = row.contentJson;
|
||||||
|
const j = raw ? (typeof raw === 'string' ? JSON.parse(raw) : raw) : {};
|
||||||
|
const no = j && j.applyNo != null ? String(j.applyNo).trim() : '';
|
||||||
|
return no || null;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleDelete() {
|
function handleDelete() {
|
||||||
let selectRows = prescriptionRef.value.getSelectionRows();
|
let selectRows = prescriptionRef.value.getSelectionRows();
|
||||||
console.log('BugFix#219: handleDelete called, selectRows=', selectRows);
|
console.log('BugFix#219: handleDelete called, selectRows=', selectRows);
|
||||||
@@ -2263,12 +2278,31 @@ function handleDelete() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (deleteList.length > 0) {
|
if (deleteList.length > 0) {
|
||||||
savePrescription({ adviceSaveList: deleteList }).then((res) => {
|
const hasLabLinked = deleteList.some((d) => {
|
||||||
if (res.code == 200) {
|
const row = normalRows.find((r) => r.requestId === d.requestId);
|
||||||
proxy.$modal.msgSuccess('删除成功');
|
return row && getInspectionApplyNoFromAdviceRow(row);
|
||||||
getListInfo(false);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
const runApiDelete = () => {
|
||||||
|
savePrescription({ adviceSaveList: deleteList }).then((res) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
proxy.$modal.msgSuccess('删除成功');
|
||||||
|
getListInfo(false);
|
||||||
|
emit('inspectionListRefresh');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
if (hasLabLinked) {
|
||||||
|
proxy.$modal
|
||||||
|
.confirm(
|
||||||
|
'删除此医嘱将同时作废关联的检验申请单(检验页签中的同单申请及同单下相关医嘱)。是否继续?',
|
||||||
|
'删除确认',
|
||||||
|
{ type: 'warning' }
|
||||||
|
)
|
||||||
|
.then(runApiDelete)
|
||||||
|
.catch(() => {});
|
||||||
|
} else {
|
||||||
|
runApiDelete();
|
||||||
|
}
|
||||||
} else if (consultationRows.length == 0) {
|
} else if (consultationRows.length == 0) {
|
||||||
proxy.$modal.msgWarning('所选医嘱不可删除,请先撤回后再删除');
|
proxy.$modal.msgWarning('所选医嘱不可删除,请先撤回后再删除');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -138,7 +138,8 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="医嘱" name="prescription">
|
<el-tab-pane label="医嘱" name="prescription">
|
||||||
<prescriptionlist :patientInfo="patientInfo" ref="prescriptionRef" :activeTab="activeTab"
|
<prescriptionlist :patientInfo="patientInfo" ref="prescriptionRef" :activeTab="activeTab"
|
||||||
:outpatientEmrSaved="outpatientEmrSaved" />
|
:outpatientEmrSaved="outpatientEmrSaved"
|
||||||
|
@inspectionListRefresh="refreshInspectionListFromAdvice" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="中医" name="tcm">
|
<el-tab-pane label="中医" name="tcm">
|
||||||
<tcmAdvice :patientInfo="patientInfo" ref="tcmRef" />
|
<tcmAdvice :patientInfo="patientInfo" ref="tcmRef" />
|
||||||
@@ -312,6 +313,9 @@ const patientDrawerRef = ref();
|
|||||||
const prescriptionRef = ref();
|
const prescriptionRef = ref();
|
||||||
const tcmRef = ref();
|
const tcmRef = ref();
|
||||||
const inspectionRef = ref();
|
const inspectionRef = ref();
|
||||||
|
function refreshInspectionListFromAdvice() {
|
||||||
|
inspectionRef.value?.getList?.();
|
||||||
|
}
|
||||||
const examinationRef = ref();
|
const examinationRef = ref();
|
||||||
const surgeryRef = ref();
|
const surgeryRef = ref();
|
||||||
const emrRef = ref();
|
const emrRef = ref();
|
||||||
|
|||||||
@@ -61,7 +61,11 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
/** 表头所选出库仓库:传入后药品列表只含该仓有库存的行,避免选到别仓批号导致 inventory-item-info 一直为 0 */
|
||||||
|
orgLocationId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const emit = defineEmits(['selectRow']);
|
const emit = defineEmits(['selectRow']);
|
||||||
const queryParams = ref({
|
const queryParams = ref({
|
||||||
@@ -89,11 +93,14 @@ watch(
|
|||||||
queryParams.value.searchKey = newValue.searchKey;
|
queryParams.value.searchKey = newValue.searchKey;
|
||||||
queryParams.value.itemType = newValue.itemType;
|
queryParams.value.itemType = newValue.itemType;
|
||||||
queryParams.value.purchaseFlag = 0;
|
queryParams.value.purchaseFlag = 0;
|
||||||
// queryParams.value.sourceLocationId = newValue.sourceLocationId;
|
if (newValue.orgLocationId != null && newValue.orgLocationId !== '') {
|
||||||
// queryParams.value.purposeLocationId = newValue.purposeLocationId;
|
queryParams.value.orgLocationId = newValue.orgLocationId;
|
||||||
|
} else {
|
||||||
|
delete queryParams.value.orgLocationId;
|
||||||
|
}
|
||||||
throttledGetList();
|
throttledGetList();
|
||||||
},
|
},
|
||||||
{ immdiate: true, deep: true }
|
{ immediate: true, deep: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
getList();
|
getList();
|
||||||
|
|||||||
@@ -133,6 +133,7 @@
|
|||||||
filterable
|
filterable
|
||||||
style="width: 200px"
|
style="width: 200px"
|
||||||
:disabled="data.isEdit"
|
:disabled="data.isEdit"
|
||||||
|
@change="onHeaderWarehouseChange"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in purposeTypeListOptions"
|
v-for="item in purposeTypeListOptions"
|
||||||
@@ -222,6 +223,7 @@
|
|||||||
@selectRow="(row) => selectRow(row, scope.$index)"
|
@selectRow="(row) => selectRow(row, scope.$index)"
|
||||||
:searchKey="medicineSearchKey"
|
:searchKey="medicineSearchKey"
|
||||||
:itemType="itemType"
|
:itemType="itemType"
|
||||||
|
:orgLocationId="receiptHeaderForm.headerLocationId"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</PopoverList>
|
</PopoverList>
|
||||||
@@ -483,6 +485,46 @@ import {useStore} from '@/store/store';
|
|||||||
import useTagsViewStore from '@/store/modules/tagsView';
|
import useTagsViewStore from '@/store/modules/tagsView';
|
||||||
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue'
|
import TraceNoDialog from '@/components/OpenHis/TraceNoDialog/index.vue'
|
||||||
|
|
||||||
|
/** 领用保存 IssueDto:后端 Jackson 只认 yyyy-MM-dd HH:mm:ss;库存接口可能回传 2025/4/2 00:00:00 等 */
|
||||||
|
function toIssueDateTimeStr(val) {
|
||||||
|
if (val == null || val === '') return undefined;
|
||||||
|
if (typeof val === 'string') {
|
||||||
|
const s = val.trim();
|
||||||
|
if (/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(s)) return s;
|
||||||
|
if (/^\d{4}-\d{2}-\d{2}$/.test(s)) return `${s} 00:00:00`;
|
||||||
|
}
|
||||||
|
const d = val instanceof Date ? val : new Date(val);
|
||||||
|
if (Number.isNaN(d.getTime())) return undefined;
|
||||||
|
return formatDate(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 总库存 totalQuantity 为最小单位;领用数量按当前计量单位折算成最小单位后再比较 */
|
||||||
|
function getRequisitionQtyInMinUnit(r) {
|
||||||
|
const q = Number(r.itemQuantity ?? 0);
|
||||||
|
if (!Number.isFinite(q) || q < 0) return NaN;
|
||||||
|
const minCode = r.unitList?.minUnitCode;
|
||||||
|
if (!minCode || r.unitCode === minCode) return q;
|
||||||
|
const part = Number(r.partPercent ?? 1);
|
||||||
|
return q * part;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateRequisitionQtyVsStock(r, lineNo) {
|
||||||
|
const cap = Number(r.totalQuantity ?? 0);
|
||||||
|
const reqMin = getRequisitionQtyInMinUnit(r);
|
||||||
|
if (!Number.isFinite(reqMin)) {
|
||||||
|
return `第${lineNo}行:领用数量请输入有效数字`;
|
||||||
|
}
|
||||||
|
if (cap > 0 && reqMin > cap + 1e-9) {
|
||||||
|
const name = r.name || `第${lineNo}行`;
|
||||||
|
return `${name}:领用数量(折合最小单位)不能超过当前仓库可领库存 ${cap},请修改后再保存。`;
|
||||||
|
}
|
||||||
|
if (cap <= 0 && reqMin > 0) {
|
||||||
|
const name = r.name || `第${lineNo}行`;
|
||||||
|
return `${name}:当前仓库可领库存为 0,不能填写正数领用数量。`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const tagsViewStore = useTagsViewStore();
|
const tagsViewStore = useTagsViewStore();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
@@ -568,6 +610,8 @@ const data = reactive({
|
|||||||
medicationType: [{ required: true, message: '请选择药品类型', trigger: 'change' }],
|
medicationType: [{ required: true, message: '请选择药品类型', trigger: 'change' }],
|
||||||
locationId: [{ required: true, message: '请选择领用部门', trigger: 'change' }],
|
locationId: [{ required: true, message: '请选择领用部门', trigger: 'change' }],
|
||||||
practitionerId: [{ required: true, message: '请选择部门经手人', trigger: 'change' }],
|
practitionerId: [{ required: true, message: '请选择部门经手人', trigger: 'change' }],
|
||||||
|
// 领用出库按「表头仓库」查 /app-common/inventory-item-info,未选仓库会查不到库存并误报「仓库数量为0」
|
||||||
|
headerLocationId: [{ required: true, message: '请先选择仓库(按仓库查询可领用库存)', trigger: 'change' }],
|
||||||
},
|
},
|
||||||
tableRules: {
|
tableRules: {
|
||||||
name: [{ required: true, message: '项目不能为空', trigger: 'change' }],
|
name: [{ required: true, message: '项目不能为空', trigger: 'change' }],
|
||||||
@@ -988,10 +1032,9 @@ function selectRow(rowValue, index) {
|
|||||||
form.purchaseinventoryList[index].unitList = rowValue.unitList[0];
|
form.purchaseinventoryList[index].unitList = rowValue.unitList[0];
|
||||||
form.purchaseinventoryList[index].lotNumber = rowValue.lotNumber;
|
form.purchaseinventoryList[index].lotNumber = rowValue.lotNumber;
|
||||||
form.purchaseinventoryList[index].ybNo = rowValue.ybNo;
|
form.purchaseinventoryList[index].ybNo = rowValue.ybNo;
|
||||||
// #439 fix: 不清空sourceLocationId,保留handleAddRow设置的仓库ID
|
// 出库仓库:优先表头当前所选仓库(避免先选药后选仓时行上一直为空)
|
||||||
if (!form.purchaseinventoryList[index].sourceLocationId) {
|
form.purchaseinventoryList[index].sourceLocationId =
|
||||||
form.purchaseinventoryList[index].sourceLocationId = receiptHeaderForm.headerLocationId || '';
|
receiptHeaderForm.headerLocationId || form.purchaseinventoryList[index].sourceLocationId || '';
|
||||||
}
|
|
||||||
getPharmacyCabinetList().then((res) => {
|
getPharmacyCabinetList().then((res) => {
|
||||||
purposeTypeListOptions.value = res.data;
|
purposeTypeListOptions.value = res.data;
|
||||||
handleLocationClick(1, rowValue, index)
|
handleLocationClick(1, rowValue, index)
|
||||||
@@ -1004,7 +1047,30 @@ function selectRow(rowValue, index) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择仓库
|
/** 多条库存记录时取可领数量最大的一条(避免仅取 res.data[0] 恰好为 0) */
|
||||||
|
function pickBestOrgQuantityRow(list) {
|
||||||
|
if (!Array.isArray(list) || list.length === 0) return null;
|
||||||
|
return list.reduce((best, cur) => {
|
||||||
|
const cq = Number(cur?.orgQuantity ?? 0);
|
||||||
|
const bq = Number(best?.orgQuantity ?? 0);
|
||||||
|
return cq > bq ? cur : best;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 表头「仓库」变化:同步每行 sourceLocationId 并重新拉库存(修复先选药品后选仓库行上仍无仓库 ID) */
|
||||||
|
function onHeaderWarehouseChange() {
|
||||||
|
const hid = receiptHeaderForm.headerLocationId;
|
||||||
|
form.purchaseinventoryList.forEach((r) => {
|
||||||
|
r.sourceLocationId = hid || '';
|
||||||
|
});
|
||||||
|
form.purchaseinventoryList.forEach((r, idx) => {
|
||||||
|
if (hid && r.itemId) {
|
||||||
|
handleLocationClick(1, {}, idx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选择仓库 / 选药品后拉取该仓库存
|
||||||
function handleLocationClick(item, row, index) {
|
function handleLocationClick(item, row, index) {
|
||||||
getCount({
|
getCount({
|
||||||
itemId: form.purchaseinventoryList[index].itemId,
|
itemId: form.purchaseinventoryList[index].itemId,
|
||||||
@@ -1013,67 +1079,100 @@ function handleLocationClick(item, row, index) {
|
|||||||
if (res.data && res.data.length > 0) {
|
if (res.data && res.data.length > 0) {
|
||||||
form.purchaseinventoryList[index].itemTable = res.data[0].itemTable || '';
|
form.purchaseinventoryList[index].itemTable = res.data[0].itemTable || '';
|
||||||
form.purchaseinventoryList[index].totalQuantity = res.data[0].orgQuantity || 0;
|
form.purchaseinventoryList[index].totalQuantity = res.data[0].orgQuantity || 0;
|
||||||
|
const r = form.purchaseinventoryList[index];
|
||||||
|
let orgLocationId = r.sourceLocationId || receiptHeaderForm.headerLocationId || '';
|
||||||
|
if (!orgLocationId) {
|
||||||
|
proxy.$message.warning('请先在表头选择「仓库」。库存按仓库维度查询,未选仓库无法匹配您看到的总库存。');
|
||||||
|
r.totalQuantity = 0;
|
||||||
|
r.price = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!r.sourceLocationId) {
|
||||||
|
r.sourceLocationId = orgLocationId;
|
||||||
|
}
|
||||||
|
|
||||||
if (res.data[0].price) {
|
const lotTrimmed =
|
||||||
form.purchaseinventoryList[index].price = res.data[0].price.toFixed(4);
|
r.lotNumber != null && String(r.lotNumber).trim() !== '' ? String(r.lotNumber).trim() : null;
|
||||||
} else {
|
|
||||||
form.purchaseinventoryList[index].price = 0;
|
const runGet = (withLot) => {
|
||||||
}
|
const params = { itemId: r.itemId, orgLocationId };
|
||||||
// 获取供应商id
|
if (withLot && lotTrimmed) {
|
||||||
form.purchaseinventoryList[index].supplierId = res.data[0].supplierId || '';
|
params.lotNumber = lotTrimmed;
|
||||||
// 生产日期
|
}
|
||||||
form.purchaseinventoryList[index].startTime = res.data[0].productionDate;
|
return getCount(params);
|
||||||
// 有效期
|
};
|
||||||
form.purchaseinventoryList[index].endTime = res.data[0].expirationDate;
|
|
||||||
form.purchaseinventoryList[index].unitCode =
|
const applyFromDto = (d, syncLotFromPick) => {
|
||||||
form.purchaseinventoryList[index].unitList.minUnitCode;
|
if (syncLotFromPick && d.lotNumber != null && d.lotNumber !== '') {
|
||||||
form.purchaseinventoryList[index].unitCode_dictText =
|
r.lotNumber = d.lotNumber;
|
||||||
form.purchaseinventoryList[index].unitList.minUnitCode_dictText;
|
}
|
||||||
// 单价 大单位单价
|
r.itemTable = d.itemTable || '';
|
||||||
console.log(
|
r.totalQuantity = d.orgQuantity || 0;
|
||||||
form.purchaseinventoryList[index].unitCode ==
|
if (d.price) {
|
||||||
form.purchaseinventoryList[index].unitList.minUnitCode,
|
r.price = d.price.toFixed(4);
|
||||||
1212121
|
} else {
|
||||||
);
|
r.price = 0;
|
||||||
if (
|
}
|
||||||
form.purchaseinventoryList[index].unitCode ==
|
r.supplierId = d.supplierId || '';
|
||||||
form.purchaseinventoryList[index].unitList.minUnitCode
|
r.startTime = toIssueDateTimeStr(d.productionDate) || '';
|
||||||
) {
|
r.endTime = toIssueDateTimeStr(d.expirationDate) || '';
|
||||||
form.purchaseinventoryList[index].price =
|
r.unitCode = r.unitList.minUnitCode;
|
||||||
res.data[0].price / form.purchaseinventoryList[index].partPercent || '';
|
r.unitCode_dictText = r.unitList.minUnitCode_dictText;
|
||||||
form.purchaseinventoryList[index].price =
|
if (r.unitCode == r.unitList.minUnitCode) {
|
||||||
form.purchaseinventoryList[index].price.toFixed(4);
|
r.price = d.price / r.partPercent || '';
|
||||||
// parseFloat(form.purchaseinventoryList[index].price.toFixed(4))
|
r.price = r.price.toFixed(4);
|
||||||
} else {
|
} else if (r.price > 1) {
|
||||||
console.log(
|
r.price = r.price.toFixed(4);
|
||||||
form.purchaseinventoryList[index].price > 1,
|
}
|
||||||
1212,
|
};
|
||||||
form.purchaseinventoryList[index].price
|
|
||||||
);
|
const persistStore = () => {
|
||||||
if (form.purchaseinventoryList[index].price > 1) {
|
store.setCurrentDataLYCK({
|
||||||
form.purchaseinventoryList[index].price =
|
purchaseinventoryList: form.purchaseinventoryList,
|
||||||
form.purchaseinventoryList[index].price.toFixed(4);
|
receiptHeaderForm: receiptHeaderForm,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
runGet(true)
|
||||||
|
.then((res) => {
|
||||||
|
const list = res.data || [];
|
||||||
|
const d = pickBestOrgQuantityRow(list);
|
||||||
|
const strictOk = d && Number(d.orgQuantity ?? 0) > 0;
|
||||||
|
if (strictOk) {
|
||||||
|
applyFromDto(d, false);
|
||||||
|
if (Number(r.totalQuantity) <= 0) {
|
||||||
|
proxy.$message.warning('仓库数量为0,无法调用!');
|
||||||
}
|
}
|
||||||
}
|
persistStore();
|
||||||
if (form.purchaseinventoryList[index].totalQuantity == 0) {
|
|
||||||
proxy.$message.warning('仓库数量为0,无法调用!');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
if (lotTrimmed) {
|
||||||
form.purchaseinventoryList[index].totalQuantity = 0;
|
return runGet(false).then((res2) => {
|
||||||
form.purchaseinventoryList[index].price = 0;
|
const list2 = res2.data || [];
|
||||||
// if(form.purchaseinventoryList[index].totalQuantity==0){
|
const d2 = pickBestOrgQuantityRow(list2);
|
||||||
|
if (d2 && Number(d2.orgQuantity ?? 0) > 0) {
|
||||||
|
applyFromDto(d2, true);
|
||||||
|
proxy.$message.info(
|
||||||
|
'所选批号在本仓库无对应库存或批号不一致,已按仓库实物回显批号与可领数量,请核对。'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
r.totalQuantity = 0;
|
||||||
|
r.price = 0;
|
||||||
|
proxy.$message.warning('仓库数量为0,无法调用!');
|
||||||
|
}
|
||||||
|
persistStore();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
r.totalQuantity = 0;
|
||||||
|
r.price = 0;
|
||||||
proxy.$message.warning('仓库数量为0,无法调用!');
|
proxy.$message.warning('仓库数量为0,无法调用!');
|
||||||
// }
|
persistStore();
|
||||||
}
|
})
|
||||||
}).catch(() => {
|
.catch(() => {
|
||||||
form.purchaseinventoryList[index].totalQuantity = 0;
|
r.totalQuantity = 0;
|
||||||
form.purchaseinventoryList[index].price = 0;
|
r.price = 0;
|
||||||
});
|
persistStore();
|
||||||
store.setCurrentDataLYCK({
|
});
|
||||||
purchaseinventoryList: form.purchaseinventoryList,
|
|
||||||
receiptHeaderForm: receiptHeaderForm,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
// 切换仓库类型获取药房/药库列表
|
// 切换仓库类型获取药房/药库列表
|
||||||
// function handleChangeLocationType(value) {
|
// function handleChangeLocationType(value) {
|
||||||
@@ -1230,20 +1329,19 @@ function getMaxCounts(row, index, counts) {
|
|||||||
}
|
}
|
||||||
// 计算总价
|
// 计算总价
|
||||||
function handleTotalPrice(index) {
|
function handleTotalPrice(index) {
|
||||||
form.purchaseinventoryList[index].olditemQuantity =
|
const r = form.purchaseinventoryList[index];
|
||||||
form.purchaseinventoryList[index].itemQuantity * row.partPercent;
|
r.olditemQuantity = r.itemQuantity * (r.partPercent ?? 1);
|
||||||
form.purchaseinventoryList[index].itemMaxQuantity =
|
r.itemMaxQuantity = r.itemQuantity;
|
||||||
form.purchaseinventoryList[index].itemQuantity;
|
let purchaseItem = r;
|
||||||
let purchaseItem = form.purchaseinventoryList[index];
|
|
||||||
if (purchaseItem.price > 0 && purchaseItem.itemQuantity > 0) {
|
if (purchaseItem.price > 0 && purchaseItem.itemQuantity > 0) {
|
||||||
form.purchaseinventoryList[index].totalPrice = purchaseItem.price * purchaseItem.itemQuantity;
|
r.totalPrice = purchaseItem.price * purchaseItem.itemQuantity;
|
||||||
form.purchaseinventoryList[index].totalPrice =
|
r.totalPrice = r.totalPrice.toFixed(4);
|
||||||
form.purchaseinventoryList[index].totalPrice.toFixed(4);
|
|
||||||
// parseFloat(form.purchaseinventoryList[index].totalPrice.toFixed(4))
|
|
||||||
}
|
}
|
||||||
if (form.purchaseinventoryList[index].itemQuantity == 0) {
|
if (r.itemQuantity == 0) {
|
||||||
form.purchaseinventoryList[index].totalPrice = 0;
|
r.totalPrice = 0;
|
||||||
}
|
}
|
||||||
|
const qtyErr = validateRequisitionQtyVsStock(r, index + 1);
|
||||||
|
r.error = !!qtyErr;
|
||||||
store.setCurrentDataLYCK({
|
store.setCurrentDataLYCK({
|
||||||
purchaseinventoryList: form.purchaseinventoryList,
|
purchaseinventoryList: form.purchaseinventoryList,
|
||||||
receiptHeaderForm: receiptHeaderForm,
|
receiptHeaderForm: receiptHeaderForm,
|
||||||
@@ -1252,6 +1350,15 @@ function handleTotalPrice(index) {
|
|||||||
// 保存
|
// 保存
|
||||||
function handleSave(row, index) {
|
function handleSave(row, index) {
|
||||||
rowList.value = [];
|
rowList.value = [];
|
||||||
|
for (let i = 0; i < form.purchaseinventoryList.length; i++) {
|
||||||
|
const line = form.purchaseinventoryList[i];
|
||||||
|
if (!line) continue;
|
||||||
|
const err = validateRequisitionQtyVsStock(line, i + 1);
|
||||||
|
if (err) {
|
||||||
|
proxy.$message.warning(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
form.purchaseinventoryList.map((row, index) => {
|
form.purchaseinventoryList.map((row, index) => {
|
||||||
if (row) {
|
if (row) {
|
||||||
// 触发校验
|
// 触发校验
|
||||||
@@ -1299,7 +1406,13 @@ function handleSave(row, index) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
function addTransferProducts(rowList) {
|
function addTransferProducts(rowList) {
|
||||||
addTransferProduct(JSON.parse(JSON.stringify(rowList))).then((res) => {
|
const payload = (Array.isArray(rowList) ? rowList : []).map((item) => ({
|
||||||
|
...item,
|
||||||
|
startTime: toIssueDateTimeStr(item.startTime),
|
||||||
|
endTime: toIssueDateTimeStr(item.endTime),
|
||||||
|
occurrenceTime: toIssueDateTimeStr(item.occurrenceTime) ?? item.occurrenceTime,
|
||||||
|
}));
|
||||||
|
addTransferProduct(JSON.parse(JSON.stringify(payload))).then((res) => {
|
||||||
// 当前行没有id视为首次新增
|
// 当前行没有id视为首次新增
|
||||||
// if (!row.id) {
|
// if (!row.id) {
|
||||||
// data.isAdding = false; // 允许新增下一行
|
// data.isAdding = false; // 允许新增下一行
|
||||||
|
|||||||
@@ -966,7 +966,7 @@ const form = reactive({
|
|||||||
allergyRemark: undefined,
|
allergyRemark: undefined,
|
||||||
surgeryNature: undefined,
|
surgeryNature: undefined,
|
||||||
surgerySite: undefined,
|
surgerySite: undefined,
|
||||||
incisionLevel: undefined,
|
incisionType: undefined,
|
||||||
surgeryLevel: undefined,
|
surgeryLevel: undefined,
|
||||||
|
|
||||||
admissionTime: undefined,
|
admissionTime: undefined,
|
||||||
@@ -2050,7 +2050,12 @@ function resetForm() {
|
|||||||
function submitForm() {
|
function submitForm() {
|
||||||
proxy.$refs['surgeryRef'].validate((valid) => {
|
proxy.$refs['surgeryRef'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const submitData = { ...form, orgId: userStore.orgId }
|
const submitData = {
|
||||||
|
...form,
|
||||||
|
orgId: userStore.orgId,
|
||||||
|
incisionLevel: form.incisionType
|
||||||
|
}
|
||||||
|
delete submitData.incisionType
|
||||||
if (!form.scheduleId) {
|
if (!form.scheduleId) {
|
||||||
// 新增手术安排
|
// 新增手术安排
|
||||||
addSurgerySchedule(submitData).then((res) => {
|
addSurgerySchedule(submitData).then((res) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user