Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
2026-03-17 17:29:22 +08:00

View File

@@ -180,13 +180,26 @@
</div> </div>
<div class="filter-item"> <div class="filter-item">
<label>费用套餐</label> <label>费用套餐</label>
<el-select v-model="packageFilter" placeholder="选择费用套餐" clearable size="default" style="width: 140px;"> <!-- <el-select v-model="packageFilter" placeholder="选择费用套餐" clearable size="default" style="width: 140px;">-->
<el-select
v-model="packageFilter"
placeholder="点击选择套餐"
filterable
:loading="loading"
clearable
size="default"
style="width: 140px;"
no-data-text="未找到相关套餐"
@change="handleChange"
@visible-change="handlePackageVisibleChange">
<el-option <el-option
v-for="pkg in feePackages" v-for="item in feePackages"
:key="pkg.value" :key="item.id"
:label="pkg.label" :label="item.packageName"
:value="pkg.value" :value="item.id"
/> >
</el-option>
</el-select> </el-select>
</div> </div>
<div class="filter-actions"> <div class="filter-actions">
@@ -250,13 +263,13 @@
<el-table-column label="费用套餐" min-width="120" align="center"> <el-table-column label="费用套餐" min-width="120" align="center">
<template #default="{ row }"> <template #default="{ row }">
<template v-if="editingRowId === row.id"> <template v-if="editingRowId === row.id">
<el-select v-model="row.package" placeholder="选择费用套餐" size="small" style="width: 100%;" @change="updateAmountFromPackage(row)"> <el-select v-model="row.package" placeholder="选择费用套餐" size="small" style="width: 100%;" filterable clearable @change="updateAmountFromPackage(row)" @visible-change="(visible) => { if (visible && feePackages.length === 0) getFeePackages() }">
<el-option label="选择费用套餐" value="" /> <el-option label="选择费用套餐" value="" />
<el-option <el-option
v-for="pkg in feePackages" v-for="pkg in feePackages"
:key="pkg.value" :key="pkg.id"
:label="pkg.label" :label="pkg.packageName"
:value="pkg.value" :value="pkg.id"
/> />
</el-select> </el-select>
</template> </template>
@@ -686,6 +699,7 @@
</template> </template>
<script setup> <script setup>
import request from '@/utils/request';
import useUserStore from '@/store/modules/user'; import useUserStore from '@/store/modules/user';
import {computed, getCurrentInstance, nextTick, onActivated, onMounted, ref, watch} from 'vue'; import {computed, getCurrentInstance, nextTick, onActivated, onMounted, ref, watch} from 'vue';
import {ElLoading, ElMessage, ElMessageBox} from 'element-plus'; import {ElLoading, ElMessage, ElMessageBox} from 'element-plus';
@@ -944,23 +958,88 @@ function handlePackageDepartmentChange(selectedNode) {
} }
// 费用套餐数据 // 费用套餐数据
const feePackages = ref([ const feePackages = ref([]);
{ value: '肝功能12项', label: '肝功能12项', amount: 120.00 }, const loading = ref(false);
{ value: '血常规', label: '血常规', amount: 35.00 },
{ value: '尿常规', label: '尿常规', amount: 25.00 },
{ value: '血脂五项', label: '血脂五项', amount: 80.00 }, /**
{ value: '肾功能三项', label: '肾功能三项', amount: 50.00 }, * 核心修改:点击/聚焦时触发
{ value: '乙肝套餐', label: '乙肝套餐', amount: 75.00 }, * 只有当列表为空 或 用户明确点击时,才去后端拉取最新数据
{ value: '糖尿病套餐', label: '糖尿病套餐', amount: 65.00 }, */
{ value: '肾功能套餐', label: '肾功能套餐', amount: 45.00 }, const handleFocus = () => {
{ value: '肿瘤筛查套餐', label: '肿瘤筛查套餐', amount: 200.00 }, // 如果正在加载中,防止重复点击
{ value: '心脑血管套餐', label: '心脑血管套餐', amount: 180.00 }, if (loading.value) return;
{ value: '甲状腺功能套餐', label: '甲状腺功能套餐', amount: 150.00 },
{ value: '微量元素套餐', label: '微量元素套餐', amount: 90.00 }, // 策略 A: 每次点击都刷新最新数据 (推荐用于数据变动频繁的场景)
{ value: '电解质套餐', label: '电解质套餐', amount: 40.00 }, getFeePackages();
{ value: '风湿免疫套餐', label: '风湿免疫套餐', amount: 120.00 },
{ value: '性激素套餐', label: '性激素套餐', amount: 160.00 } // 策略 B: 仅第一次点击时加载,后续使用缓存数据 (如果数据不常变,可取消下面注释并注释掉上面那行)
]); /*
if (!hasLoadedOnce.value) {
getFeePackages();
hasLoadedOnce.value = true;
}
*/
};
/**
* 获取数据方法
* 这里不再接收搜索关键词,而是直接拉取所有启用的套餐
* 如果需要后端支持模糊搜索,可以配合 filterable 在前端做,或者在这里加逻辑
*/
const getFeePackages = async () => {
loading.value = true;
try {
const response = await request({
url: '/system/inspection-package/list',
method: 'get',
params: {
pageNum: 1,
pageSize: 100, // 点击加载时,建议稍微多拉一点,方便前端过滤
isDisabled: false // 只查未禁用的
// 注意:这里没有传 packageName因为我们是全量加载供用户选择
}
});
if (response.code === 200) {
feePackages.value = response.rows || [];
} else {
ElMessage.warning(response.msg || '查询失败');
}
} catch (error) {
console.error('加载套餐列表失败:', error);
// 错误拦截器通常会处理弹窗,这里可不处理或简单记录
} finally {
loading.value = false;
}
};
/**
* 选中值变化回调
*/
const handleChange = (val) => {
if (val) {
const selected = feePackages.value.find(item => item.id === val);
console.log('用户选中了套餐:', selected);
}
};
/**
* 顶部筛选费用套餐下拉展开/收起回调
* 展开时若列表为空则加载数据
*/
const handlePackageVisibleChange = (visible) => {
if (visible && feePackages.value.length === 0) {
getFeePackages();
}
};
// 可选:如果希望页面一打开就预加载一次,保留 onMounted
// 如果希望完全由用户点击触发,可以注释掉 onMounted
onMounted(() => {
// getFeePackages();
});
// 样本类型数据 // 样本类型数据
const sampleTypes = ref([ const sampleTypes = ref([
@@ -1094,6 +1173,7 @@ const testTypeFilter = ref('');
const nameFilter = ref(''); const nameFilter = ref('');
const packageFilter = ref(''); const packageFilter = ref('');
// 过滤后的检验项目数据(仅保留费用套餐的前端过滤,其他过滤已由后端处理) // 过滤后的检验项目数据(仅保留费用套餐的前端过滤,其他过滤已由后端处理)
const filteredInspectionItems = computed(() => { const filteredInspectionItems = computed(() => {
return inspectionItems.value.filter(item => { return inspectionItems.value.filter(item => {
@@ -1671,9 +1751,12 @@ const editItem = (item) => {
const updateAmountFromPackage = (item) => { const updateAmountFromPackage = (item) => {
if (item.package) { if (item.package) {
const selectedPackage = feePackages.value.find(pkg => pkg.value === item.package); const selectedPackage = feePackages.value.find(pkg => pkg.id === item.package);
if (selectedPackage) { if (selectedPackage) {
item.amount = selectedPackage.amount; // 套餐总金额 = 套餐金额 + 服务费
const packageAmount = parseFloat(selectedPackage.packageAmount || 0);
const serviceFee = parseFloat(selectedPackage.serviceFee || 0);
item.amount = parseFloat((packageAmount + serviceFee).toFixed(2));
} }
} else { } else {
item.amount = 0.00; item.amount = 0.00;