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