Bug #384: 检查方法联动功能完善,增加套餐价格查询和项目卡片展开选择
Bug #386: 检验申请删除时同步删除关联收费项目 Bug #382: 选择项目后保持当前页签状态 Bug #380,381: 临床诊断获取主诊断字段名修正 Bug #387: 套餐项目回充默认展开并自动加载明细
This commit is contained in:
@@ -4,8 +4,11 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.check.domain.CheckMethod;
|
||||
import com.openhis.check.domain.CheckPackage;
|
||||
import com.openhis.check.service.ICheckMethodService;
|
||||
import com.openhis.check.service.ICheckPackageService;
|
||||
import com.openhis.web.check.appservice.ICheckMethodAppService;
|
||||
import com.openhis.web.check.dto.CheckMethodDto;
|
||||
import com.openhis.web.reportmanage.utils.ExcelFillerUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -16,6 +19,7 @@ import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
@@ -24,10 +28,15 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
@Resource
|
||||
private ICheckMethodService checkMethodService;
|
||||
|
||||
@Resource
|
||||
private ICheckPackageService checkPackageService; // Bug #384修复:注入套餐服务
|
||||
|
||||
@Override
|
||||
public R<?> getCheckMethodList() {
|
||||
List<CheckMethod> list = checkMethodService.list();
|
||||
return R.ok(list);
|
||||
// Bug #384修复:转换为DTO并关联套餐价格
|
||||
List<CheckMethodDto> dtoList = convertToDtoWithPackagePrice(list);
|
||||
return R.ok(dtoList);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,7 +52,67 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
|
||||
wrapper.eq(CheckMethod::getPackageName, packageName);
|
||||
}
|
||||
List<CheckMethod> list = checkMethodService.list(wrapper);
|
||||
return R.ok(list);
|
||||
// Bug #384修复:转换为DTO并关联套餐价格
|
||||
List<CheckMethodDto> dtoList = convertToDtoWithPackagePrice(list);
|
||||
return R.ok(dtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bug #384修复:转换CheckMethod为DTO,并通过packageName关联查询套餐价格
|
||||
* @param methods 检查方法列表
|
||||
* @return 包含套餐价格的DTO列表
|
||||
*/
|
||||
private List<CheckMethodDto> convertToDtoWithPackagePrice(List<CheckMethod> methods) {
|
||||
if (methods == null || methods.isEmpty()) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
// 获取所有packageName,批量查询套餐
|
||||
List<String> packageNames = methods.stream()
|
||||
.map(CheckMethod::getPackageName)
|
||||
.filter(ObjectUtil::isNotEmpty)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Bug #384修复: 批量查询套餐信息,使用final变量
|
||||
final Map<String, CheckPackage> packageMap;
|
||||
if (!packageNames.isEmpty()) {
|
||||
List<CheckPackage> packages = checkPackageService.list(
|
||||
new LambdaQueryWrapper<CheckPackage>()
|
||||
.in(CheckPackage::getPackageName, packageNames)
|
||||
.eq(CheckPackage::getIsDisabled, 0) // 只查未停用的套餐
|
||||
);
|
||||
packageMap = packages.stream()
|
||||
.collect(Collectors.toMap(CheckPackage::getPackageName, p -> p, (p1, p2) -> p1));
|
||||
} else {
|
||||
packageMap = Map.of();
|
||||
}
|
||||
|
||||
// 转换为DTO并填充价格
|
||||
return methods.stream().map(m -> {
|
||||
CheckMethodDto dto = new CheckMethodDto();
|
||||
dto.setId(m.getId() != null ? m.getId().longValue() : null);
|
||||
dto.setCheckType(m.getCheckType());
|
||||
dto.setCode(m.getCode());
|
||||
dto.setName(m.getName());
|
||||
dto.setPackageName(m.getPackageName());
|
||||
dto.setExposureNum(m.getExposureNum());
|
||||
dto.setOrderNum(m.getOrderNum());
|
||||
dto.setRemark(m.getRemark());
|
||||
dto.setCreateTime(m.getCreateTime());
|
||||
dto.setUpdateTime(m.getUpdateTime());
|
||||
|
||||
// 通过packageName匹配套餐价格
|
||||
if (ObjectUtil.isNotEmpty(m.getPackageName())) {
|
||||
CheckPackage pkg = packageMap.get(m.getPackageName());
|
||||
if (pkg != null) {
|
||||
dto.setPackagePrice(pkg.getPackagePrice());
|
||||
dto.setServiceFee(pkg.getServiceFee());
|
||||
}
|
||||
}
|
||||
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package com.openhis.web.check.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 检查方法DTO - Bug #384修复:增加套餐价格字段
|
||||
* 用于API返回数据传输,不含数据库注解
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class CheckMethodDto {
|
||||
@@ -14,7 +17,6 @@ public class CheckMethodDto {
|
||||
/**
|
||||
* 检查方法ID
|
||||
*/
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
/* 检查类型 */
|
||||
@@ -29,6 +31,12 @@ public class CheckMethodDto {
|
||||
/* 套餐名称 */
|
||||
private String packageName;
|
||||
|
||||
/* 套餐价格 - Bug #384修复:通过packageName匹配CheckPackage获取 */
|
||||
private BigDecimal packagePrice;
|
||||
|
||||
/* 服务费 - Bug #384修复:通过packageName匹配CheckPackage获取 */
|
||||
private BigDecimal serviceFee;
|
||||
|
||||
/* 曝光次数 */
|
||||
private Integer exposureNum;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.enums.DbOpType;
|
||||
import com.openhis.administration.service.IAccountService;
|
||||
import com.openhis.administration.domain.Account;
|
||||
import com.openhis.administration.service.IChargeItemService; // Bug #386修复: 添加 ChargeItemService
|
||||
import com.openhis.lab.domain.InspectionLabApply;
|
||||
import com.openhis.lab.domain.InspectionLabApplyItem;
|
||||
import com.openhis.lab.domain.BarCode;
|
||||
@@ -97,6 +98,10 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
@Autowired
|
||||
private ILabActivityDefinitionService labActivityDefinitionService;
|
||||
|
||||
// Bug #386修复: ChargeItemService 用于删除收费项目
|
||||
@Autowired
|
||||
private IChargeItemService chargeItemService;
|
||||
|
||||
/**
|
||||
* 保存检验申请单信息
|
||||
* @param doctorStationLabApplyDto
|
||||
@@ -600,6 +605,12 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
|
||||
if (updateResult) {
|
||||
log.debug("成功将申请单号 [{}] 关联的 {} 条门诊医嘱的删除状态更新为1,更新人:{},更新时间:{}",
|
||||
applyNo, requestIds.size(), currentUsername, currentTime);
|
||||
|
||||
// Bug #386修复: 同步删除关联的收费项目
|
||||
for (Long requestId : requestIds) {
|
||||
chargeItemService.deleteByServiceTableAndId("wor_service_request", requestId);
|
||||
}
|
||||
log.debug("成功删除申请单号 [{}] 关联的 {} 条收费项目", applyNo, requestIds.size());
|
||||
} else {
|
||||
log.warn("更新申请单号 [{}] 关联的门诊医嘱删除状态失败", applyNo);
|
||||
}
|
||||
|
||||
@@ -104,14 +104,14 @@
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请科室" prop="applyDeptCode">
|
||||
<el-input v-model="form.applyDeptCode" />
|
||||
<el-input v-model="form.applyDeptCode" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="12">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="申请医生" prop="applyDocCode">
|
||||
<el-input v-model="form.applyDocCode" />
|
||||
<el-input v-model="form.applyDocCode" disabled />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
@@ -184,16 +184,10 @@
|
||||
<el-input v-model="form.inspectionArea" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- Bug #384修复: 添加检查方法只读输入框,联动显示选中的检查方法 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="检查方法">
|
||||
<el-select v-model="form.inspectionMethod" placeholder="请选择" clearable filterable style="width: 100%;">
|
||||
<el-option
|
||||
v-for="method in availableMethods"
|
||||
:key="method.id"
|
||||
:label="method.name"
|
||||
:value="method.name"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input v-model="form.selectedMethodDisplay" readonly placeholder="请在右侧选择" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -233,16 +227,34 @@
|
||||
<el-input v-model="scope.row.applyPart" size="small" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="检查方法" min-width="120">
|
||||
<template #default="scope">
|
||||
<!-- Bug #384修复: 显示检查方法名称,不显示套餐名称 -->
|
||||
<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>
|
||||
</el-table-column>
|
||||
<el-table-column label="单位" prop="unit" width="55" align="center" />
|
||||
<el-table-column label="总量" prop="quantity" width="70" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number v-model="scope.row.quantity" :min="1" size="small" :controls="false" style="width:100%" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="单价" prop="price" width="75" align="right" />
|
||||
<!-- Bug #384修复: 单价显示套餐价格(如果选中)或部位价格 -->
|
||||
<el-table-column label="单价" width="75" align="right">
|
||||
<template #default="scope">
|
||||
{{ scope.row.selectedMethod?.packagePrice || scope.row.price }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- Bug #384修复: 金额使用有效价格计算 -->
|
||||
<el-table-column label="金额" width="80" align="right">
|
||||
<template #default="scope">
|
||||
{{ ((scope.row.price || 0) * (scope.row.quantity || 1)).toFixed(2) }}
|
||||
{{ ((scope.row.selectedMethod?.packagePrice || scope.row.price || 0) * (scope.row.quantity || 1)).toFixed(2) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型" prop="checkType" width="70" align="center" />
|
||||
@@ -307,22 +319,48 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:已选择 tags -->
|
||||
<!-- 右侧:已选择 项目卡片(可展开显示检查方法) -->
|
||||
<div class="selected-panel">
|
||||
<div class="panel-label">已选择:</div>
|
||||
<div class="selected-tags">
|
||||
<div v-if="selectedItems.length === 0" class="empty-selected">–</div>
|
||||
<el-tag
|
||||
<div
|
||||
v-else
|
||||
v-for="(item, idx) in selectedItems"
|
||||
:key="idx"
|
||||
closable
|
||||
size="small"
|
||||
@close="handleRemoveItem(idx, item)"
|
||||
class="selected-tag"
|
||||
class="selected-item-card"
|
||||
>
|
||||
{{ item.name }} ¥{{ item.price }}
|
||||
</el-tag>
|
||||
<!-- Bug #384修复: 项目卡片头部,可展开/收起 -->
|
||||
<div class="card-header" @click="toggleItemExpand(item)">
|
||||
<span class="card-name">{{ item.name }}</span>
|
||||
<span class="card-price">¥{{ item.price }}</span>
|
||||
<!-- 展开图标 -->
|
||||
<el-icon :class="['expand-icon', { expanded: item.expanded }]">
|
||||
<ArrowDown v-if="!item.expanded" />
|
||||
<ArrowUp v-if="item.expanded" />
|
||||
</el-icon>
|
||||
<!-- 删除按钮 -->
|
||||
<el-button link type="danger" size="small" @click.stop="handleRemoveItem(idx, item)">
|
||||
<el-icon><Close /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
<!-- Bug #384修复: 展开后显示检查方法勾选框列表 -->
|
||||
<div v-if="item.expanded && item.methods && item.methods.length > 0" class="method-list">
|
||||
<div
|
||||
v-for="method in item.methods"
|
||||
:key="method.id"
|
||||
class="method-option"
|
||||
>
|
||||
<el-checkbox
|
||||
:model-value="item.selectedMethod?.id === method.id"
|
||||
@change="(val) => selectMethodCheckbox(val, item, method)"
|
||||
>
|
||||
<span class="method-name">{{ method.name }}</span>
|
||||
<span class="method-price">¥{{ method.packagePrice || item.price }}</span>
|
||||
</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -334,10 +372,11 @@
|
||||
<script setup>
|
||||
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { Printer, Delete } from '@element-plus/icons-vue';
|
||||
import { Printer, Delete, ArrowDown, ArrowUp, Close } from '@element-plus/icons-vue';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import request from '@/utils/request';
|
||||
import { listCheckMethod } from '@/api/system/checkType';
|
||||
import { listCheckMethod, searchCheckMethod } from '@/api/system/checkType';
|
||||
import { getEncounterDiagnosis } from '../api.js';
|
||||
|
||||
const props = defineProps({
|
||||
patientInfo: { type: Object, default: () => ({}) },
|
||||
@@ -384,7 +423,8 @@ const form = reactive({
|
||||
isCharged: 0,
|
||||
isRefunded: 0,
|
||||
isExecuted: 0,
|
||||
examTypeCode: '' // 检查类型编码,必填字段,保存时从已选项目自动推导
|
||||
examTypeCode: '', // 检查类型编码,必填字段,保存时从已选项目自动推导
|
||||
selectedMethodDisplay: '' // Bug #384修复: 检查方法显示字段(联动)
|
||||
});
|
||||
|
||||
const rules = {
|
||||
@@ -590,6 +630,7 @@ async function loadCategoryList() {
|
||||
unit: '次',
|
||||
checkType: p.checkType || '',
|
||||
nationalCode: p.nationalCode || '',
|
||||
packageName: p.packageName || '',
|
||||
checked: false
|
||||
};
|
||||
|
||||
@@ -631,9 +672,11 @@ const filteredCategoryList = computed(() => {
|
||||
});
|
||||
|
||||
// ====== 合计 ======
|
||||
// Bug #384修复: 如果选中了检查方法,使用套餐价格;否则使用部位价格
|
||||
const totalAmountCalc = computed(() => {
|
||||
const total = selectedItems.value.reduce((sum, item) => {
|
||||
return sum + (item.price * (item.quantity || 1));
|
||||
const effectivePrice = item.selectedMethod?.packagePrice || item.price;
|
||||
return sum + (effectivePrice * (item.quantity || 1));
|
||||
}, 0);
|
||||
return total.toFixed(2);
|
||||
});
|
||||
@@ -652,19 +695,49 @@ watch(() => props.patientInfo, (newVal) => {
|
||||
}
|
||||
}, { immediate: true, deep: true });
|
||||
|
||||
watch(() => props.activeTab, (val) => {
|
||||
if (val === 'examination') getList();
|
||||
watch(() => props.activeTab, async (val) => {
|
||||
if (val === 'examination') {
|
||||
getList();
|
||||
// 切换到检查页签时,重新获取临床诊断(确保与诊断页签同步)
|
||||
if (props.patientInfo?.encounterId) {
|
||||
await loadClinicalDiag();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function initPatientForm(patient) {
|
||||
form.patientName = patient.patientName || '';
|
||||
form.medicalrecordNumber = patient.busNo || patient.visitNo || '';
|
||||
// 就诊卡号应取值于 identifierNo,而非 busNo(busNo 是病历号)
|
||||
form.medicalrecordNumber = patient.identifierNo || patient.visitNo || '';
|
||||
form.patientId = patient.patientId || '';
|
||||
form.visitNo = patient.visitNo || '';
|
||||
form.applyDeptCode = userStore.orgName || patient.organizationName || '';
|
||||
form.applyDocCode = userStore.nickName || '';
|
||||
}
|
||||
|
||||
// 加载临床诊断:获取患者主诊断并填充到临床诊断字段
|
||||
async function loadClinicalDiag() {
|
||||
if (!props.patientInfo?.encounterId) return;
|
||||
try {
|
||||
const res = await getEncounterDiagnosis(props.patientInfo.encounterId);
|
||||
const diagnoses = res.data || res.rows || res;
|
||||
if (Array.isArray(diagnoses) && diagnoses.length > 0) {
|
||||
// Bug #380, #381 修复: 主诊断字段名为 maindiseFlag (后端 DiagnosisQueryDto 定义)
|
||||
const mainDiag = diagnoses.find(d => d.maindiseFlag === 1 || d.maindiseFlag === '1');
|
||||
// 如果有主诊断使用主诊断,否则使用第一个诊断
|
||||
const targetDiag = mainDiag || diagnoses[0];
|
||||
// 优先使用 diagnosisName,其次是 conditionName 或 name
|
||||
form.clinicalDiag = targetDiag.diagnosisName || targetDiag.conditionName || targetDiag.name || '';
|
||||
} else {
|
||||
// 如果没有诊断,清空临床诊断字段
|
||||
form.clinicalDiag = '';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载临床诊断失败', err);
|
||||
// 获取失败时不阻断用户操作,保持字段为空
|
||||
}
|
||||
}
|
||||
|
||||
// ====== 申请单 CRUD ======
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
@@ -682,24 +755,30 @@ function getList() {
|
||||
function handleAdd() {
|
||||
formRef.value?.resetFields();
|
||||
Object.assign(form, {
|
||||
applyNo: '', patientId: props.patientInfo?.patientId || '',
|
||||
applyNo: '',
|
||||
patientId: props.patientInfo?.patientId || '',
|
||||
visitNo: props.patientInfo?.visitNo || '',
|
||||
// 保留患者姓名和就诊卡号,不应重置为空
|
||||
patientName: props.patientInfo?.patientName || '',
|
||||
medicalrecordNumber: props.patientInfo?.identifierNo || '',
|
||||
applyDeptCode: userStore.orgName || '',
|
||||
performDeptCode: '',
|
||||
applyDocCode: userStore.nickName || '',
|
||||
applyTime: new Date().toISOString().split('T')[0] + ' 12:00:00',
|
||||
medicalrecordNumber: props.patientInfo?.busNo || '',
|
||||
natureofCost: '自费医疗',
|
||||
clinicDesc: '', contraindication: '', medicalHistorySummary: '',
|
||||
purposeofInspection: '', inspectionArea: '', inspectionMethod: '',
|
||||
applyRemark: '', clinicalDiag: '', purposeDesc: '',
|
||||
isUrgent: 0, pregnancyState: 0, allergyDesc: '',
|
||||
applyStatus: 0, isCharged: 0, isRefunded: 0, isExecuted: 0,
|
||||
examTypeCode: ''
|
||||
examTypeCode: '',
|
||||
selectedMethodDisplay: '' // Bug #384修复: 重置检查方法显示
|
||||
});
|
||||
selectedItems.value = [];
|
||||
resetCategoryChecked();
|
||||
activeDetailTab.value = 'applyForm';
|
||||
// 自动加载临床诊断
|
||||
loadClinicalDiag();
|
||||
}
|
||||
|
||||
function handleSave() {
|
||||
@@ -713,6 +792,12 @@ function handleSave() {
|
||||
const firstCheckType = selectedItems.value[0]?.checkType || 'unknown';
|
||||
form.examTypeCode = firstCheckType;
|
||||
|
||||
// 如果有选中的检查方法,更新表单中的检查方法字段(取第一个选中项目的检查方法)
|
||||
const firstItemWithMethod = selectedItems.value.find(item => item.selectedMethod);
|
||||
if (firstItemWithMethod?.selectedMethod) {
|
||||
form.inspectionMethod = firstItemWithMethod.selectedMethod.name;
|
||||
}
|
||||
|
||||
const payload = {
|
||||
...form,
|
||||
encounterId: props.patientInfo?.encounterId || null,
|
||||
@@ -721,10 +806,16 @@ function handleSave() {
|
||||
itemCode: String(item.id),
|
||||
itemName: item.name,
|
||||
bodyPartCode: item.checkType || 'unknown',
|
||||
itemFee: item.price,
|
||||
// Bug #384修复: 如果选中了检查方法且有套餐价格,使用套餐价格;否则使用部位价格
|
||||
itemFee: item.selectedMethod?.packagePrice || item.price,
|
||||
performDeptCode: form.performDeptCode || '',
|
||||
itemStatus: 0,
|
||||
itemSeq: index + 1
|
||||
itemSeq: index + 1,
|
||||
// 检查方法信息
|
||||
checkMethodId: item.selectedMethod?.id || null,
|
||||
checkMethodName: item.selectedMethod?.name || null,
|
||||
checkMethodCode: item.selectedMethod?.code || null,
|
||||
checkMethodPackageName: item.selectedMethod?.packageName || null // Bug #384修复: 保存套餐名称
|
||||
}))
|
||||
};
|
||||
request({
|
||||
@@ -743,22 +834,70 @@ function handleSave() {
|
||||
|
||||
function handleRowClick(row) {
|
||||
Object.assign(form, row);
|
||||
form.selectedMethodDisplay = ''; // Bug #384修复: 先清空,后面根据回充数据更新
|
||||
selectedItems.value = [];
|
||||
activeDetailTab.value = 'applyForm';
|
||||
request({ url: `/exam/apply/${row.applyNo}`, method: 'get' }).then(res => {
|
||||
request({ url: `/exam/apply/${row.applyNo}`, method: 'get' }).then(async res => {
|
||||
const d = res.data || res;
|
||||
if (d.data) Object.assign(form, d.data);
|
||||
if (d.items && Array.isArray(d.items)) {
|
||||
selectedItems.value = d.items.map(m => ({
|
||||
id: m.itemCode, name: m.itemName,
|
||||
price: m.itemFee || 0, quantity: 1,
|
||||
serviceFee: 0, unit: '次',
|
||||
applyPart: m.itemName,
|
||||
checkType: m.bodyPartCode || '',
|
||||
nationalCode: '', checked: true
|
||||
}));
|
||||
syncCategoryChecked();
|
||||
try {
|
||||
// 为每个项目加载检查方法
|
||||
const itemsWithMethods = await Promise.all(d.items.map(async m => {
|
||||
const item = {
|
||||
id: m.itemCode, name: m.itemName,
|
||||
price: m.itemFee || 0, quantity: 1,
|
||||
serviceFee: 0, unit: '次',
|
||||
applyPart: m.itemName,
|
||||
checkType: m.bodyPartCode || '',
|
||||
nationalCode: '', checked: true,
|
||||
methods: [],
|
||||
selectedMethod: null,
|
||||
expanded: false // Bug #384修复: 添加展开状态
|
||||
};
|
||||
// 加载该项目的检查方法
|
||||
if (m.bodyPartCode) {
|
||||
try {
|
||||
const methodRes = await searchCheckMethod({ checkType: m.bodyPartCode });
|
||||
// Bug #384修复: 正确解析 API 返回结构
|
||||
let methodData = methodRes?.data?.data || methodRes?.data || methodRes?.rows || methodRes;
|
||||
if (!Array.isArray(methodData) && methodRes?.data && Array.isArray(methodRes.data.data)) {
|
||||
methodData = methodRes.data.data;
|
||||
}
|
||||
if (Array.isArray(methodData)) {
|
||||
item.methods = methodData.map(md => ({
|
||||
id: md.id,
|
||||
name: md.name,
|
||||
code: md.code,
|
||||
price: m.itemFee || 0, // fallback 到已保存的价格
|
||||
packageName: md.packageName || '',
|
||||
packagePrice: md.packagePrice || null, // Bug #384修复: 套餐价格
|
||||
serviceFee: md.serviceFee || null
|
||||
}));
|
||||
// 如果有已保存的检查方法信息,尝试匹配
|
||||
if (m.checkMethodId) {
|
||||
item.selectedMethod = item.methods.find(md => md.id === m.checkMethodId) || null;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载检查方法失败', err);
|
||||
// 单个项目加载失败不影响其他项目,继续返回 item
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}));
|
||||
selectedItems.value = itemsWithMethods;
|
||||
syncCategoryChecked();
|
||||
// Bug #384修复: 回充后更新检查方法显示
|
||||
updateMethodDisplay();
|
||||
} catch (err) {
|
||||
console.error('加载申请单详情失败', err);
|
||||
ElMessage.error('加载申请单详情失败');
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取申请单详情失败', err);
|
||||
ElMessage.error('获取申请单详情失败');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -775,8 +914,37 @@ function handleDelete(row) {
|
||||
}
|
||||
|
||||
// ====== 勾选逻辑 ======
|
||||
function handleItemSelect(checked, item, cat) {
|
||||
async function handleItemSelect(checked, item, cat) {
|
||||
if (checked) {
|
||||
// Bug #384修复: 检查方法表的 checkType 字段关联的是检查类型的 name(中文名称,如"心电图")
|
||||
const effectiveCheckType = cat?.typeName || cat?.categoryName || '';
|
||||
|
||||
// 查询该检查类型对应的检查方法
|
||||
let methods = [];
|
||||
try {
|
||||
if (effectiveCheckType) {
|
||||
const res = await searchCheckMethod({ checkType: effectiveCheckType });
|
||||
// Bug #384修复: API 返回结构可能是 {data: {data: Array}} 或 {data: Array}
|
||||
let data = res?.data?.data || res?.data || res?.rows || res;
|
||||
if (!Array.isArray(data) && res?.data && Array.isArray(res.data.data)) {
|
||||
data = res.data.data;
|
||||
}
|
||||
if (Array.isArray(data)) {
|
||||
methods = data.map(m => ({
|
||||
id: m.id,
|
||||
name: m.name,
|
||||
code: m.code,
|
||||
price: m.price || item.price, // fallback 到项目价格
|
||||
packageName: m.packageName || '',
|
||||
packagePrice: m.packagePrice || null, // Bug #384修复: 套餐价格
|
||||
serviceFee: m.serviceFee || null // Bug #384修复: 服务费
|
||||
}));
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载检查方法失败', err);
|
||||
}
|
||||
|
||||
if (selectedItems.value.length > 0) {
|
||||
const currentCategory = selectedItems.value[0].checkType;
|
||||
const newCategory = cat.typeCode || '';
|
||||
@@ -793,9 +961,12 @@ function handleItemSelect(checked, item, cat) {
|
||||
serviceFee: item.serviceFee || 0,
|
||||
unit: item.unit || '次',
|
||||
applyPart: item.name,
|
||||
checkType: cat.typeCode || '',
|
||||
checkType: effectiveCheckType, // Bug #384修复: 使用有效的 checkType
|
||||
nationalCode: item.nationalCode || '',
|
||||
checked: true
|
||||
checked: true,
|
||||
methods: methods,
|
||||
selectedMethod: null,
|
||||
expanded: false // Bug #384修复: 新增展开状态,默认不展开
|
||||
});
|
||||
|
||||
// 自动回填执行科室:按检查项目类型 → 检查类型管理里配置的执行科室
|
||||
@@ -804,6 +975,13 @@ function handleItemSelect(checked, item, cat) {
|
||||
} else if (!form.performDeptCode && cat?.performDeptName) {
|
||||
form.performDeptCode = cat.performDeptName;
|
||||
}
|
||||
|
||||
// 如果有且仅有一个检查方法,自动选中并更新显示
|
||||
if (methods.length === 1) {
|
||||
const lastIdx = selectedItems.value.length - 1;
|
||||
selectedItems.value[lastIdx].selectedMethod = methods[0];
|
||||
updateMethodDisplay(); // Bug #384修复: 联动更新显示
|
||||
}
|
||||
} else {
|
||||
const idx = selectedItems.value.findIndex(s => s.id === item.id);
|
||||
if (idx > -1) selectedItems.value.splice(idx, 1);
|
||||
@@ -813,11 +991,45 @@ function handleItemSelect(checked, item, cat) {
|
||||
form.examTypeCode = '';
|
||||
}
|
||||
}
|
||||
// 有选项时切换到明细tab
|
||||
if (selectedItems.value.length > 0) {
|
||||
activeDetailTab.value = 'applyDetail';
|
||||
nextTick(() => detailTableRef.value?.doLayout());
|
||||
// Bug #382 修复:移除自动切换页签逻辑,保持当前页签状态
|
||||
}
|
||||
|
||||
// Bug #384修复: 展开/收起项目卡片
|
||||
function toggleItemExpand(item) {
|
||||
item.expanded = !item.expanded;
|
||||
}
|
||||
|
||||
// Bug #384修复: 勾选框选择检查方法(单选逻辑)
|
||||
function selectMethodCheckbox(checked, item, method) {
|
||||
if (checked) {
|
||||
item.selectedMethod = method;
|
||||
} else {
|
||||
item.selectedMethod = null;
|
||||
}
|
||||
// 联动更新表单检查方法显示字段
|
||||
updateMethodDisplay();
|
||||
}
|
||||
|
||||
// Bug #384修复: 更新检查方法显示字段(联动)
|
||||
function updateMethodDisplay() {
|
||||
// 找到第一个有选中检查方法的项目
|
||||
const itemWithMethod = selectedItems.value.find(item => item.selectedMethod);
|
||||
if (itemWithMethod?.selectedMethod) {
|
||||
form.selectedMethodDisplay = itemWithMethod.selectedMethod.name; // 显示检查方法名称,不显示套餐名称
|
||||
} else {
|
||||
form.selectedMethodDisplay = '';
|
||||
}
|
||||
}
|
||||
|
||||
// 选择检查方法
|
||||
function selectMethod(item, method) {
|
||||
if (item.selectedMethod?.id === method.id) {
|
||||
item.selectedMethod = null;
|
||||
} else {
|
||||
item.selectedMethod = method;
|
||||
}
|
||||
// Bug #384修复: 联动更新表单检查方法显示字段
|
||||
updateMethodDisplay();
|
||||
}
|
||||
|
||||
function handleRemoveItem(idx, item) {
|
||||
@@ -831,6 +1043,10 @@ function handleRemoveItem(idx, item) {
|
||||
if (selectedItems.value.length === 0) {
|
||||
form.performDeptCode = '';
|
||||
form.examTypeCode = '';
|
||||
form.selectedMethodDisplay = ''; // Bug #384修复: 清空检查方法显示
|
||||
} else {
|
||||
// Bug #384修复: 移除后重新计算检查方法显示
|
||||
updateMethodDisplay();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -999,7 +1215,7 @@ defineExpose({ getList });
|
||||
|
||||
/* 已选择 tags */
|
||||
.selected-panel {
|
||||
width: 120px;
|
||||
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -1009,7 +1225,7 @@ defineExpose({ getList });
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
gap: 6px;
|
||||
}
|
||||
.selected-tag {
|
||||
max-width: 100%;
|
||||
@@ -1022,6 +1238,86 @@ defineExpose({ getList });
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* Bug #384修复: 已选择项目卡片(可展开) */
|
||||
.selected-item-card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #e4e7ed;
|
||||
}
|
||||
|
||||
.selected-item-card .card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 10px;
|
||||
cursor: pointer;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.selected-item-card .card-header:hover {
|
||||
background: #E6F7FF;
|
||||
}
|
||||
|
||||
.card-name {
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
color: #303133;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-price {
|
||||
font-size: 12px;
|
||||
color: #1890FF;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.expand-icon {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.expand-icon.expanded {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
/* Bug #384修复: 检查方法勾选框列表 */
|
||||
.method-list {
|
||||
padding: 6px 10px;
|
||||
background: #fff;
|
||||
border-top: 1px solid #e4e7ed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.method-option {
|
||||
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;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.method-option .method-price {
|
||||
font-size: 11px;
|
||||
color: #e6a23c;
|
||||
font-weight: 500;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 折叠组件细节 */
|
||||
:deep(.el-collapse) {
|
||||
border: none;
|
||||
|
||||
@@ -45,35 +45,10 @@
|
||||
class="inspection-table"
|
||||
highlight-current-row
|
||||
row-key="applicationId"
|
||||
:expand-row-keys="expandedRowKeys"
|
||||
@expand-change="handleExpandChange"
|
||||
@selection-change="handleSelectionChange"
|
||||
@current-change="handleRowClick"
|
||||
@cell-click="handleCellClick"
|
||||
>
|
||||
<el-table-column type="expand" width="50" align="center" header-align="center">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.children && scope.row.children.length > 0" class="expand-content">
|
||||
<el-table :data="scope.row.children" border size="small" style="width: 100%">
|
||||
<el-table-column label="明细项目" prop="itemName" min-width="150" />
|
||||
<el-table-column label="样本类型" prop="sampleType" width="100" />
|
||||
<el-table-column label="单位" prop="unit" width="80" />
|
||||
<el-table-column label="单价" prop="itemPrice" width="80" align="right">
|
||||
<template #default="itemScope">
|
||||
¥{{ formatAmount(itemScope.row.itemPrice) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数量" prop="itemQty" width="80" align="center" />
|
||||
<el-table-column label="金额" prop="itemAmount" width="80" align="right">
|
||||
<template #default="itemScope">
|
||||
¥{{ formatAmount(itemScope.row.itemAmount) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div v-else class="expand-empty">无明细项目</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column type="selection" width="55" align="center" header-align="center" />
|
||||
<el-table-column label="申请 ID" prop="applicationId" width="80" align="center" header-align="center">
|
||||
<template #default="scope">
|
||||
@@ -83,14 +58,7 @@
|
||||
<el-table-column label="申请单号" prop="applyNo" min-width="160" align="center" header-align="center" />
|
||||
<el-table-column label="检验项目" prop="itemName" min-width="170px" align="center" header-align="center">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.hasChildren" style="color: #409EFF; cursor: pointer" @click.stop="toggleExpand(scope.row)">
|
||||
<el-icon style="vertical-align: middle; margin-right: 4px">
|
||||
<Right v-if="!isExpanded(scope.row.applicationId)" />
|
||||
<Bottom v-else />
|
||||
</el-icon>
|
||||
{{ scope.row.itemName }}
|
||||
</span>
|
||||
<span v-else>{{ scope.row.itemName }}</span>
|
||||
<span>{{ scope.row.itemName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请医生" prop="applyDocName" width="120" align="center" header-align="center" />
|
||||
@@ -645,7 +613,7 @@
|
||||
<script setup>
|
||||
import {onMounted, onUnmounted, reactive, ref, watch, computed, getCurrentInstance} from 'vue'
|
||||
import {ElMessage, ElMessageBox} from 'element-plus'
|
||||
import { DocumentChecked, Plus, Document, Printer, Delete, Check, Loading, Right, Bottom } from '@element-plus/icons-vue'
|
||||
import { DocumentChecked, Plus, Document, Printer, Delete, Check, Loading } from '@element-plus/icons-vue'
|
||||
import {
|
||||
deleteInspectionApplication, getApplyList,
|
||||
saveInspectionApplication,
|
||||
@@ -792,53 +760,39 @@ const loading = ref(false)
|
||||
const saving = ref(false) // 保存状态
|
||||
const total = ref(0)
|
||||
const leftActiveTab = ref('application')
|
||||
const expandedRowKeys = ref([])
|
||||
|
||||
const isExpanded = (applicationId) => {
|
||||
return expandedRowKeys.value.includes(applicationId)
|
||||
}
|
||||
|
||||
const toggleExpand = async (row) => {
|
||||
const applicationId = row.applicationId
|
||||
const isCurrentlyExpanded = isExpanded(applicationId)
|
||||
|
||||
if (isCurrentlyExpanded) {
|
||||
// 收起
|
||||
expandedRowKeys.value = expandedRowKeys.value.filter(id => id !== applicationId)
|
||||
} else {
|
||||
// 展开 - 先检查是否需要加载明细数据
|
||||
if (row.hasChildren && (!row.children || row.children.length === 0)) {
|
||||
// 加载套餐明细
|
||||
await loadPackageDetails(row)
|
||||
}
|
||||
expandedRowKeys.value = [...expandedRowKeys.value, applicationId]
|
||||
}
|
||||
}
|
||||
|
||||
const handleExpandChange = (row, expandedRows) => {
|
||||
expandedRowKeys.value = expandedRows.map(r => r.applicationId)
|
||||
}
|
||||
|
||||
const loadPackageDetails = async (row) => {
|
||||
/**
|
||||
* 加载套餐明细(公共函数)
|
||||
* @param {string|number} packageId 套餐ID
|
||||
* @returns {Promise<Array>} 明细数组
|
||||
*/
|
||||
const fetchPackageDetails = async (packageId) => {
|
||||
if (!packageId) return []
|
||||
try {
|
||||
const packageId = row.feePackageId || row.packageId
|
||||
if (!packageId) return
|
||||
|
||||
const res = await getInspectionPackageDetails(packageId)
|
||||
if (res.code === 200 && res.data) {
|
||||
row.children = res.data.map(detail => ({
|
||||
itemId: detail.detailId || detail.id || detail.itemId,
|
||||
itemName: detail.itemName || detail.name,
|
||||
sampleType: detail.sampleType || '',
|
||||
unit: detail.unit || '',
|
||||
itemPrice: detail.unitPrice || detail.itemPrice || detail.price || 0,
|
||||
itemQty: detail.quantity || detail.itemQty || detail.qty || 1,
|
||||
itemAmount: (detail.unitPrice || detail.itemPrice || 0) * (detail.quantity || detail.itemQty || 1)
|
||||
}))
|
||||
return res.data.map(detail => {
|
||||
const detailId = detail.detailId || detail.id || detail.itemId
|
||||
const qty = detail.quantity || detail.itemQty || detail.qty || 1
|
||||
const price = detail.unitPrice || detail.itemPrice || detail.price || 0
|
||||
return {
|
||||
detailId: detailId,
|
||||
itemId: detailId, // 兼容表格 row-key
|
||||
itemName: detail.itemName || detail.name,
|
||||
sampleType: detail.sampleType || '',
|
||||
unit: detail.unit || '',
|
||||
quantity: qty,
|
||||
itemQty: qty, // 兼容表格"总量"列
|
||||
unitPrice: price,
|
||||
itemPrice: price, // 兼容表格"单价"列
|
||||
itemAmount: price * qty
|
||||
}
|
||||
})
|
||||
}
|
||||
return []
|
||||
} catch (error) {
|
||||
console.error('加载套餐明细失败:', error)
|
||||
row.children = []
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -847,35 +801,9 @@ const loadPackageDetailsForTable = async (row, treeNode, resolve) => {
|
||||
resolve([])
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const packageId = row.feePackageId || row.packageId
|
||||
if (!packageId) {
|
||||
resolve([])
|
||||
return
|
||||
}
|
||||
|
||||
const res = await getInspectionPackageDetails(packageId)
|
||||
if (res.code === 200 && res.data) {
|
||||
// 构建明细数据结构
|
||||
// BugFix: 后端返回字段为 unitPrice 和 quantity,需正确映射
|
||||
const children = res.data.map(detail => ({
|
||||
itemId: detail.detailId || detail.id || detail.itemId,
|
||||
itemName: detail.itemName || detail.name,
|
||||
sampleType: detail.sampleType || '',
|
||||
unit: detail.unit || '',
|
||||
itemPrice: detail.unitPrice || detail.itemPrice || detail.price || 0,
|
||||
itemQty: detail.quantity || detail.itemQty || detail.qty || 1,
|
||||
itemAmount: (detail.unitPrice || detail.itemPrice || 0) * (detail.quantity || detail.itemQty || 1)
|
||||
}))
|
||||
resolve(children)
|
||||
} else {
|
||||
resolve([])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载套餐明细失败:', error)
|
||||
resolve([])
|
||||
}
|
||||
const packageId = row.feePackageId || row.packageId
|
||||
const children = await fetchPackageDetails(packageId)
|
||||
resolve(children)
|
||||
}
|
||||
|
||||
const togglePackageExpand = async (item) => {
|
||||
@@ -885,27 +813,9 @@ const togglePackageExpand = async (item) => {
|
||||
|
||||
if (item.expanded && (!item.children || item.children.length === 0)) {
|
||||
item.loading = true
|
||||
try {
|
||||
const packageId = item.feePackageId || item.packageId
|
||||
if (packageId) {
|
||||
const res = await getInspectionPackageDetails(packageId)
|
||||
if (res.code === 200 && res.data) {
|
||||
item.children = res.data.map(detail => ({
|
||||
detailId: detail.detailId || detail.id || detail.itemId,
|
||||
itemName: detail.itemName || detail.name,
|
||||
unit: detail.unit || '',
|
||||
quantity: detail.quantity || detail.itemQty || detail.qty || 1,
|
||||
unitPrice: detail.unitPrice || detail.itemPrice || detail.price || 0,
|
||||
itemPrice: detail.unitPrice || detail.itemPrice || detail.price || 0
|
||||
}))
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载套餐明细失败:', error)
|
||||
item.children = []
|
||||
} finally {
|
||||
item.loading = false
|
||||
}
|
||||
const packageId = item.feePackageId || item.packageId
|
||||
item.children = await fetchPackageDetails(packageId)
|
||||
item.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1822,6 +1732,26 @@ const clearAllSelected = () => {
|
||||
selectedInspectionItems.value = []
|
||||
}
|
||||
|
||||
// Bug #387修复: 同步分类勾选状态
|
||||
const syncCategoryChecked = () => {
|
||||
// 重置所有分类项目的勾选状态
|
||||
inspectionCategories.value.forEach(category => {
|
||||
category.items.forEach(item => {
|
||||
item.checked = false
|
||||
})
|
||||
})
|
||||
// 获取已选项目的ID集合
|
||||
const ids = new Set(selectedInspectionItems.value.map(s => s.itemId))
|
||||
// 同步勾选状态
|
||||
for (const cat of inspectionCategories.value) {
|
||||
for (const item of cat.items) {
|
||||
if (ids.has(item.itemId)) {
|
||||
item.checked = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 分页大小改变
|
||||
const handleSizeChange = (size) => {
|
||||
queryParams.pageSize = size
|
||||
@@ -1977,6 +1907,7 @@ const loadApplicationToForm = async (row) => {
|
||||
if (detail.labApplyItemList && detail.labApplyItemList.length > 0) {
|
||||
// Bug #326修复: 直接使用后端返回的数据,不再从本地缓存查找匹配项
|
||||
// 后端已返回完整关联信息(activityId、feePackageId、inspectionTypeId、sampleType、unit)
|
||||
// Bug #387修复: 套餐项目默认展开,并自动加载明细
|
||||
selectedInspectionItems.value = detail.labApplyItemList.map(item => {
|
||||
const itemId = item.activityId || item.itemId || item.id || Math.random().toString(36).substring(2, 11)
|
||||
const isPackage = item.feePackageId != null || item.itemName?.includes('套餐')
|
||||
@@ -1995,12 +1926,25 @@ const loadApplicationToForm = async (row) => {
|
||||
feePackageId: item.feePackageId || null,
|
||||
activityId: item.activityId || itemId,
|
||||
inspectionTypeId: item.inspectionTypeId || null,
|
||||
expanded: false,
|
||||
expanded: isPackage, // Bug #387: 套餐默认展开
|
||||
children: [],
|
||||
childrenLoaded: false,
|
||||
childrenLoaded: !isPackage, // Bug #387: 套餐需加载明细
|
||||
loading: false
|
||||
}
|
||||
})
|
||||
|
||||
// Bug #387修复: 自动加载套餐明细
|
||||
for (const pkgItem of selectedInspectionItems.value) {
|
||||
if (pkgItem.isPackage && pkgItem.feePackageId) {
|
||||
pkgItem.loading = true
|
||||
pkgItem.children = await fetchPackageDetails(pkgItem.feePackageId)
|
||||
pkgItem.childrenLoaded = true
|
||||
pkgItem.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
// Bug #387修复: 同步分类勾选状态
|
||||
syncCategoryChecked()
|
||||
} else if (detail.inspectionItem || detail.itemName) {
|
||||
// 如果只有项目名称,尝试从本地分类中查找匹配项
|
||||
const itemNames = (detail.inspectionItem || detail.itemName).split(/[+,]/)
|
||||
|
||||
@@ -181,6 +181,7 @@ function handleGetPrescription() {
|
||||
getPrescriptionList({
|
||||
encounterIds: encounterIds,
|
||||
requestStatus: props.requestStatus,
|
||||
therapyEnum: type.value === 1 ? undefined : type.value === 2 ? 1 : 2, // 1=全部(不传), 2=长期(1), 3=临时(2)
|
||||
pageSize: 10000,
|
||||
pageNo: 1,
|
||||
}).then((res) => {
|
||||
|
||||
Reference in New Issue
Block a user