Fix Bug #550: AI修复

This commit is contained in:
2026-05-27 05:53:35 +08:00
parent a5da34d855
commit 55a31c796c
2 changed files with 113 additions and 154 deletions

View File

@@ -20,7 +20,7 @@
v-model="item.checked"
@change="handleItemCheck(item)"
/>
<el-tooltip :content="item.name" placement="top" :show-after="300">
<el-tooltip :content="cleanName(item.name)" placement="top" :show-after="300">
<span class="item-name">{{ cleanName(item.name) }}</span>
</el-tooltip>
</div>
@@ -38,7 +38,7 @@
:name="sel.id"
>
<template #title>
<el-tooltip :content="sel.name" placement="top" :show-after="300">
<el-tooltip :content="cleanName(sel.name)" placement="top" :show-after="300">
<span class="collapse-title">{{ cleanName(sel.name) }}</span>
</el-tooltip>
</template>
@@ -48,9 +48,7 @@
v-model="method.checked"
@change="handleMethodCheck(sel, method)"
/>
<el-tooltip :content="method.name" placement="top" :show-after="300">
<span class="method-name">{{ cleanName(method.name) }}</span>
</el-tooltip>
<span class="method-name">{{ method.name }}</span>
</div>
</div>
</el-collapse-item>
@@ -59,137 +57,117 @@
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus';
<script setup lang="ts">
import { ref, computed } from 'vue'
// mock data placeholders in real code these come from API
interface ExamMethod {
id: string
name: string
checked: boolean
}
interface ExamItem {
id: string
name: string
checked: boolean
methods: ExamMethod[]
}
// 模拟分类与项目数据(实际由接口注入)
const categories = ref([
/* ... */
]);
const allItems = ref([
/* each item: { id, name, checked:false, methods:[{id,name,checked:false}] } */
]);
{ id: 'cat1', label: '彩超', children: [] },
{ id: 'cat2', label: 'X光', children: [] }
])
const currentItems = ref([]);
const selectedItems = ref([]);
const activeCollapseNames = ref([]);
const currentItems = ref<ExamItem[]>([
{ id: '101', name: '128线排彩超套餐', checked: false, methods: [
{ id: 'm1', name: '常规检查', checked: false },
{ id: 'm2', name: '血管多普勒', checked: false }
]},
{ id: '102', name: '腹部彩超', checked: false, methods: [] }
])
const handleCategorySelect = (node) => {
// filter items by category id
currentItems.value = allItems.value.filter(i => i.categoryId === node.id);
// reset UI check state for displayed items
currentItems.value.forEach(i => (i.checked = !!selectedItems.value.find(s => s.id === i.id)));
};
// 默认收起所有已选面板
const activeCollapseNames = ref<string[]>([])
const cleanName = (name) => {
// 防止名称过长导致遮挡,保留完整名称供 tooltip 使用
const maxLen = 20;
return name.length > maxLen ? name.slice(0, maxLen) + '…' : name;
};
// 清理名称:去除“套餐”字样,避免冗余显示
const cleanName = (name: string) => {
return name.replace(/套餐/g, '').trim()
}
/**
* 处理检查项目的勾选
* 1. 防止同一项目在已选择列表中出现多次(自动勾选冲突)。
* 2. 勾选后自动在已选择区域生成对应的折叠项,未勾选则移除。
*/
const handleItemCheck = (item) => {
const exists = selectedItems.value.find(s => s.id === item.id);
// 选择分类(触发项目列表刷新)
const handleCategorySelect = (data: any) => {
console.log('切换分类:', data.label)
// 实际业务调用API加载对应分类下的项目
}
// 勾选项目(解耦:仅控制项目本身,不联动勾选方法)
const handleItemCheck = (item: ExamItem) => {
if (item.checked) {
if (!exists) {
// 深拷贝,防止后续修改影响原列表
const copy = {
id: item.id,
name: item.name,
methods: (item.methods || []).map(m => ({
id: m.id,
name: m.name,
checked: false,
})),
};
selectedItems.value.push(copy);
// 加入已选列表时,强制方法状态为未勾选,保持独立
if (!selectedItems.value.find(s => s.id === item.id)) {
selectedItems.value.push({
...item,
methods: item.methods.map(m => ({ ...m, checked: false }))
})
}
} else {
if (exists) {
selectedItems.value = selectedItems.value.filter(s => s.id !== item.id);
}
selectedItems.value = selectedItems.value.filter(s => s.id !== item.id)
}
};
}
/**
* 处理检查方法(明细)的勾选
* 只在已选择列表内部操作,避免明细与项目列表耦合。
*/
const handleMethodCheck = (selItem, method) => {
// 这里可以加入业务校验,例如同一项目只能选择一种检查方式等
// 示例:若业务要求只能单选,则取消同项目其他已选 method
// if (singleChoice) {
// selItem.methods.forEach(m => {
// if (m.id !== method.id) m.checked = false;
// });
// }
};
// 勾选方法(独立控制,不影响父级或其他同级方法)
const handleMethodCheck = (sel: ExamItem, method: ExamMethod) => {
const target = selectedItems.value.find(s => s.id === sel.id)
if (target) {
const m = target.methods.find(m => m.id === method.id)
if (m) m.checked = method.checked
}
}
// 已选项目列表(响应式维护)
const selectedItems = ref<ExamItem[]>([])
</script>
<style scoped>
.exam-apply-container {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px;
height: 100%;
box-sizing: border-box;
}
/* 左侧分类 */
.category-panel {
width: 200px;
}
/* 中间项目列表 */
.item-panel {
.category-panel, .item-panel, .selected-panel {
flex: 1;
max-width: 400px;
min-height: 0;
display: flex;
flex-direction: column;
}
.item-list {
max-height: 500px;
.item-list, .method-container {
flex: 1;
overflow-y: auto;
padding-right: 4px;
}
.item-row {
.item-row, .method-row {
display: flex;
align-items: center;
padding: 4px 0;
padding: 8px 4px;
border-bottom: 1px solid #f5f7fa;
cursor: pointer;
}
.item-name {
margin-left: 8px;
/* 防止名称过长遮挡 */
display: inline-block;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 已选择区域 */
.selected-panel {
.item-name, .method-name, .collapse-title {
flex: 1;
max-width: 400px;
}
.collapse-title {
display: inline-block;
max-width: 200px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.method-row {
display: flex;
align-items: center;
padding: 4px 0;
}
.method-name {
margin-left: 8px;
display: inline-block;
max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
}
.empty-tip {
color: #909399;
text-align: center;
padding: 24px 0;
font-size: 13px;
}
</style>