Files
his/openhis-ui-vue3/src/views/outpatient/check/CheckApplication.vue
2026-05-27 06:36:53 +08:00

221 lines
5.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="check-application-container">
<!-- 左侧检查项目分类 -->
<div class="panel category-panel">
<h3 class="panel-title">检查项目分类</h3>
<el-tree
:data="categories"
:props="{ label: 'name', children: 'children' }"
node-key="id"
highlight-current
@node-click="handleCategoryClick"
/>
</div>
<!-- 中间检查项目列表 -->
<div class="panel project-panel">
<h3 class="panel-title">检查项目</h3>
<el-checkbox-group v-model="selectedProjectIds" @change="onProjectChange">
<el-checkbox
v-for="proj in currentProjects"
:key="proj.id"
:label="proj.id"
class="project-item"
>
<!-- 修复去除冗余套餐字样 -->
{{ proj.name.replace(/套餐/g, '') }}
</el-checkbox>
</el-checkbox-group>
</div>
<!-- 右侧已选择区域 -->
<div class="panel selected-panel">
<h3 class="panel-title">已选择</h3>
<div v-if="selectedList.length === 0" class="empty-tip">暂无选择项目</div>
<div v-for="item in selectedList" :key="item.id" class="selected-card">
<!-- 卡片头部支持点击展开/收起默认收起 -->
<div class="card-header" @click="toggleExpand(item)">
<!-- 修复名称遮挡问题使用 title 属性提示完整名称 -->
<span class="card-title" :title="item.name">{{ item.name.replace(/套餐/g, '') }}</span>
<el-icon class="expand-icon">
<ArrowDown v-if="item.expanded" />
<ArrowRight v-else />
</el-icon>
</div>
<!-- 修复移除项目套餐明细冗余标签结构化展示层级 -->
<div v-show="item.expanded" class="card-details">
<div class="hierarchy-label">检查项目 &gt; 检查方法</div>
<div class="method-group">
<el-checkbox-group v-model="item.selectedMethods" @change="onMethodChange(item)">
<el-checkbox
v-for="method in item.availableMethods"
:key="method.id"
:label="method.id"
>
{{ method.name }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue';
import { ArrowDown, ArrowRight } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
// 类型定义
interface CheckMethod { id: string; name: string; }
interface CheckProject { id: string; name: string; methods: CheckMethod[]; }
interface SelectedItem extends CheckProject {
selectedMethods: string[];
expanded: boolean;
}
// 状态管理
const categories = ref<any[]>([]);
const currentProjects = ref<CheckProject[]>([]);
const selectedProjectIds = ref<string[]>([]);
const selectedList = ref<SelectedItem[]>([]);
// 模拟数据加载(实际应调用 API
const handleCategoryClick = async (node: any) => {
// 此处替换为实际 API 调用: const res = await fetchProjectsByCategory(node.id);
currentProjects.value = node.projects || [];
};
// 修复:项目勾选与检查方法解耦
const onProjectChange = (ids: string[]) => {
// 仅同步项目列表,不触发任何方法自动勾选逻辑
const updatedList: SelectedItem[] = [];
ids.forEach(id => {
const existing = selectedList.value.find(i => i.id === id);
if (existing) {
updatedList.push(existing);
} else {
const proj = currentProjects.value.find(p => p.id === id);
if (proj) {
updatedList.push({
...proj,
selectedMethods: [], // 默认不勾选任何方法
expanded: false // 默认收起状态
});
}
}
});
// 保持原有顺序,移除已取消勾选的项目
selectedList.value = updatedList;
};
// 修复:检查方法独立勾选,互不干扰
const onMethodChange = (item: SelectedItem) => {
// 可在此处触发后端同步或本地状态更新
// 确保方法勾选状态仅绑定到当前 item.selectedMethods
};
// 修复:点击展开/收起明细
const toggleExpand = (item: SelectedItem) => {
item.expanded = !item.expanded;
};
</script>
<style scoped>
.check-application-container {
display: flex;
gap: 16px;
padding: 16px;
height: 100%;
background: #f5f7fa;
}
.panel {
flex: 1;
background: #fff;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
display: flex;
flex-direction: column;
}
.panel-title {
margin: 0 0 12px 0;
font-size: 16px;
font-weight: 600;
color: #303133;
border-bottom: 1px solid #ebeef5;
padding-bottom: 8px;
}
.project-item {
display: block;
margin-bottom: 8px;
padding: 4px 0;
}
.selected-card {
border: 1px solid #dcdfe6;
border-radius: 6px;
margin-bottom: 10px;
overflow: hidden;
transition: all 0.2s;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 12px;
background: #fafafa;
cursor: pointer;
user-select: none;
}
.card-title {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: 500;
color: #303133;
}
.expand-icon {
margin-left: 8px;
color: #909399;
}
.card-details {
padding: 12px;
border-top: 1px solid #ebeef5;
background: #fff;
}
.hierarchy-label {
font-size: 12px;
color: #909399;
margin-bottom: 8px;
padding-bottom: 4px;
border-bottom: 1px dashed #ebeef5;
}
.method-group {
display: flex;
flex-direction: column;
gap: 6px;
}
.empty-tip {
text-align: center;
color: #909399;
padding: 40px 0;
}
</style>