Fix Bug #550: AI修复
This commit is contained in:
136
openhis-ui-vue3/src/views/outpatient/examination/Apply.vue
Normal file
136
openhis-ui-vue3/src/views/outpatient/examination/Apply.vue
Normal file
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<div class="exam-apply-container">
|
||||
<div class="selection-layout">
|
||||
<!-- 左侧:检查项目分类 -->
|
||||
<div class="panel category-panel">
|
||||
<h4>检查项目分类</h4>
|
||||
<el-tree
|
||||
:data="categoryTree"
|
||||
:props="{ label: 'name', children: 'children' }"
|
||||
@node-click="handleCategoryClick"
|
||||
data-cy="category-tree"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 中间:检查项目 -->
|
||||
<div class="panel item-panel">
|
||||
<h4>检查项目</h4>
|
||||
<div class="item-list-container" data-cy="item-list">
|
||||
<div v-for="item in filteredItems" :key="item.id" class="list-item">
|
||||
<el-checkbox v-model="item.selected" @change="handleItemChange(item)" />
|
||||
<span class="item-name">{{ item.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧:检查方法 -->
|
||||
<div class="panel method-panel">
|
||||
<h4>检查方法</h4>
|
||||
<div class="method-list-container" data-cy="method-list">
|
||||
<div v-for="method in filteredMethods" :key="method.id" class="list-item">
|
||||
<el-checkbox v-model="method.selected" @change="handleMethodChange(method)" />
|
||||
<span class="method-name">{{ method.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 已选择区域 -->
|
||||
<div class="selected-area" data-cy="selected-area">
|
||||
<h4>已选择</h4>
|
||||
<div v-for="group in selectedGroups" :key="group.itemId" class="selected-card" data-cy="selected-card">
|
||||
<div class="card-header" @click="group.collapsed = !group.collapsed">
|
||||
<el-checkbox v-model="group.selected" @change="handleGroupSelect(group)" @click.stop />
|
||||
<el-tooltip :content="group.itemName" placement="top" :show-after="300">
|
||||
<span class="card-title">{{ group.itemName }}</span>
|
||||
</el-tooltip>
|
||||
<span class="collapse-icon">{{ group.collapsed ? '▶' : '▼' }}</span>
|
||||
</div>
|
||||
<!-- 明细区域:严格遵循 项目 > 检查方法 层级,默认收起,移除冗余标签 -->
|
||||
<div v-show="!group.collapsed" class="details-panel">
|
||||
<div v-for="method in group.methods" :key="method.id" class="detail-row">
|
||||
<el-checkbox v-model="method.selected" @change="handleDetailMethodChange(group, method)" @click.stop />
|
||||
<span>{{ method.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
// 数据源(实际应从后端API获取)
|
||||
const categoryTree = ref([])
|
||||
const allItems = ref([])
|
||||
const allMethods = ref([])
|
||||
|
||||
const currentCategoryId = ref(null)
|
||||
|
||||
const filteredItems = computed(() => allItems.value.filter(i => i.categoryId === currentCategoryId.value))
|
||||
const filteredMethods = computed(() => allMethods.value.filter(m => m.categoryId === currentCategoryId.value))
|
||||
|
||||
const selectedGroups = ref([])
|
||||
|
||||
const handleCategoryClick = (node) => {
|
||||
currentCategoryId.value = node.id
|
||||
// 触发加载对应分类下的项目与方法
|
||||
}
|
||||
|
||||
// 修复点1:项目勾选与检查方法完全解耦,不触发自动联动
|
||||
const handleItemChange = (item) => {
|
||||
if (item.selected) {
|
||||
const exists = selectedGroups.value.find(g => g.itemId === item.id)
|
||||
if (!exists) {
|
||||
selectedGroups.value.push({
|
||||
itemId: item.id,
|
||||
// 修复点2:清理冗余“套餐”前缀
|
||||
itemName: item.name.replace(/套餐/g, ''),
|
||||
selected: true,
|
||||
// 修复点3:默认收起明细状态
|
||||
collapsed: true,
|
||||
methods: allMethods.value
|
||||
.filter(m => m.parentItemId === item.id)
|
||||
.map(m => ({ ...m, selected: false }))
|
||||
})
|
||||
}
|
||||
} else {
|
||||
selectedGroups.value = selectedGroups.value.filter(g => g.itemId !== item.id)
|
||||
}
|
||||
}
|
||||
|
||||
// 修复点1:检查方法独立勾选,不受项目状态影响
|
||||
const handleMethodChange = (method) => {
|
||||
// 独立维护右侧方法列表状态,不反向修改项目选中状态
|
||||
}
|
||||
|
||||
const handleGroupSelect = (group) => {
|
||||
group.methods.forEach(m => m.selected = group.selected)
|
||||
}
|
||||
|
||||
const handleDetailMethodChange = (group, method) => {
|
||||
// 明细勾选状态变更时,同步更新父级卡片选中状态
|
||||
group.selected = group.methods.length > 0 && group.methods.every(m => m.selected)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.exam-apply-container { padding: 16px; background: #f5f7fa; min-height: 100vh; }
|
||||
.selection-layout { display: flex; gap: 16px; margin-bottom: 20px; }
|
||||
.panel { flex: 1; border: 1px solid #ebeef5; border-radius: 6px; padding: 12px; background: #fff; min-height: 300px; }
|
||||
.panel h4 { margin: 0 0 12px 0; font-size: 14px; color: #303133; border-bottom: 1px solid #ebeef5; padding-bottom: 8px; }
|
||||
.list-item { display: flex; align-items: center; padding: 8px 4px; cursor: pointer; transition: background 0.2s; }
|
||||
.list-item:hover { background: #f5f7fa; }
|
||||
.item-name, .method-name { margin-left: 8px; font-size: 13px; }
|
||||
|
||||
.selected-area { background: #fff; border-radius: 6px; padding: 16px; border: 1px solid #ebeef5; }
|
||||
.selected-area h4 { margin: 0 0 12px 0; font-size: 14px; color: #303133; }
|
||||
.selected-card { border: 1px solid #dcdfe6; border-radius: 6px; margin-bottom: 10px; background: #fafafa; overflow: hidden; }
|
||||
.card-header { display: flex; align-items: center; padding: 10px 12px; cursor: pointer; user-select: none; background: #fff; }
|
||||
.card-header:hover { background: #f5f7fa; }
|
||||
.card-title { flex: 1; margin: 0 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; color: #303133; }
|
||||
.collapse-icon { font-size: 12px; color: #909399; transition: transform 0.2s; }
|
||||
.details-panel { padding: 8px 12px 12px 32px; border-top: 1px dashed #ebeef5; background: #fafafa; }
|
||||
.detail-row { display: flex; align-items: center; padding: 4px 0; font-size: 13px; color: #606266; }
|
||||
</style>
|
||||
Reference in New Issue
Block a user