Fix Bug #426: 门诊医生站-检查开立:已选择列表应支持树形展开,显示套餐明细(项目/数量/单价)

- 已选择面板的套餐项增加"套餐"标签,便于用户识别
- 展开/收起图标改为 ArrowRight 旋转样式,符合标准交互习惯
- toggleItemExpand 函数增加 packageName 兜底判断,不强制依赖 isPackage 标记
- loadPackageDetailsForItem 添加 loading 状态和更健壮的 packageId 解析逻辑
- 新增 expanded-content 和 package-loading-hint CSS 样式

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
赵云
2026-05-14 09:30:04 +08:00
committed by 关羽
parent 0f1b29fcea
commit 34774411eb

View File

@@ -413,29 +413,33 @@
:key="idx"
class="selected-item-card"
>
<!-- Bug #384修复: 项目卡片头部可展开/收起 -->
<!-- Bug #384修复 + #426修复: 项目卡片头部可展开/收起 -->
<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>
<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 class="expand-icon" :class="{ expanded: item.expanded }">
<ArrowRight />
</el-icon>
<!-- 删除按钮 -->
<el-button link type="danger" size="small" @click.stop="handleRemoveItem(idx, item)">
<el-icon><Close /></el-icon>
</el-button>
</div>
<!-- Bug #428修复: 展开后显示套餐明细或检查方法 -->
<div v-if="item.expanded">
<!-- Bug #428修复 + #426修复: 展开后显示套餐明细或检查方法 -->
<div v-show="item.expanded" class="expanded-content">
<!-- 显示套餐明细 -->
<div v-if="item.packageDetails && item.packageDetails.length > 0" class="package-details-list">
<div v-if="(item.isPackage || item.packageName) && item.packageDetails && item.packageDetails.length > 0" class="package-details-list">
<div class="detail-row" v-for="detail in item.packageDetails" :key="detail.id">
<span class="detail-name">{{ detail.name }}</span>
<span class="detail-info">数量: {{ detail.quantity }} 单价: ¥{{ detail.price }}</span>
</div>
</div>
<!-- 套餐明细加载中 -->
<div v-else-if="(item.isPackage || item.packageName) && item.packageDetailsLoading" class="package-loading-hint">
加载中...
</div>
<!-- 显示检查方法 -->
<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">
@@ -473,7 +477,7 @@
<script setup>
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Printer, Delete, ArrowDown, ArrowUp, Close } from '@element-plus/icons-vue';
import { Printer, Delete, ArrowDown, ArrowUp, Close, ArrowRight } from '@element-plus/icons-vue';
import useUserStore from '@/store/modules/user';
import request from '@/utils/request';
import { listCheckMethod, searchCheckMethod, listCheckPackage } from '@/api/system/checkType';
@@ -592,11 +596,13 @@ async function loadPackageDetails(row, treeNode, resolve) {
}
}
// #428修复: 为已选择项目加载套餐明细通过packageId或packageName查询
// #428修复 + #426修复: 为已选择项目加载套餐明细通过packageId或packageName查询
async function loadPackageDetailsForItem(item) {
if (!item.isPackage || (!item.packageId && !item.packageName)) {
// 只要有 packageName 就认为是套餐,不强制要求 isPackage 或 packageId
if (!item.packageName && !item.packageId) {
return;
}
item.packageDetailsLoading = true;
try {
let packageId = item.packageId;
if (!packageId && item.packageName) {
@@ -612,6 +618,10 @@ async function loadPackageDetailsForItem(item) {
}
packageId = packages[0].id;
}
if (!packageId) {
item.packageDetails = [];
return;
}
const res = await request({
url: `/system/package/${packageId}/details`,
method: 'get'
@@ -630,6 +640,8 @@ async function loadPackageDetailsForItem(item) {
} catch (err) {
console.error('加载套餐明细失败:', err);
item.packageDetails = [];
} finally {
item.packageDetailsLoading = false;
}
}
const detailTableRef = ref(null);
@@ -1396,11 +1408,11 @@ async function handleItemSelect(checked, item, cat) {
// Bug #382 修复:移除自动切换页签逻辑,保持当前页签状态
}
// Bug #384修复: 展开/收起项目卡片
// Bug #384修复 + #426修复: 展开/收起项目卡片
async function toggleItemExpand(item) {
item.expanded = !item.expanded;
// 如果是展开且该项目是套餐,加载套餐明细
if (item.expanded && item.isPackage && (!item.packageDetails || item.packageDetails.length === 0)) {
// 如果是展开且该项目是套餐(通过 isPackage 或 packageName 判断),加载套餐明细
if (item.expanded && (item.isPackage || item.packageName) && (!item.packageDetails || item.packageDetails.length === 0) && !item.packageDetailsLoading) {
await loadPackageDetailsForItem(item);
}
}
@@ -1812,10 +1824,24 @@ defineExpose({ getList });
font-size: 12px;
color: #909399;
transition: transform 0.2s;
transform: rotate(0deg);
}
.expand-icon.expanded {
transform: rotate(180deg);
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修复: 套餐明细列表样式 */