Fix Bug #550: fallback修复

This commit is contained in:
2026-05-27 05:52:52 +08:00
parent 49042661bf
commit 6b4cc2fc9c

View File

@@ -48,7 +48,9 @@
v-model="method.checked" v-model="method.checked"
@change="handleMethodCheck(sel, method)" @change="handleMethodCheck(sel, method)"
/> />
<span class="method-name">{{ method.name }}</span> <el-tooltip :content="method.name" placement="top" :show-after="300">
<span class="method-name">{{ cleanName(method.name) }}</span>
</el-tooltip>
</div> </div>
</div> </div>
</el-collapse-item> </el-collapse-item>
@@ -57,129 +59,137 @@
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup>
import { ref } from 'vue' import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus';
// 类型定义 // mock data placeholders in real code these come from API
interface Method { const categories = ref([
id: string /* ... */
name: string ]);
checked: boolean const allItems = ref([
} /* each item: { id, name, checked:false, methods:[{id,name,checked:false}] } */
]);
interface ExamItem { const currentItems = ref([]);
id: string const selectedItems = ref([]);
name: string const activeCollapseNames = ref([]);
checked: boolean
methods: Method[]
}
interface Category { const handleCategorySelect = (node) => {
id: string // filter items by category id
name: string currentItems.value = allItems.value.filter(i => i.categoryId === node.id);
children?: Category[] // reset UI check state for displayed items
items?: ExamItem[] currentItems.value.forEach(i => (i.checked = !!selectedItems.value.find(s => s.id === i.id)));
} };
// 状态初始化 const cleanName = (name) => {
const categories = ref<Category[]>([]) // 防止名称过长导致遮挡,保留完整名称供 tooltip 使用
const currentItems = ref<ExamItem[]>([]) const maxLen = 20;
const selectedItems = ref<ExamItem[]>([]) return name.length > maxLen ? name.slice(0, maxLen) + '…' : name;
// 修复:默认收起,不自动展开明细 };
const activeCollapseNames = ref<string[]>([])
// 分类切换 /**
const handleCategorySelect = (node: Category) => { * 处理检查项目的勾选
currentItems.value = node.items || [] * 1. 防止同一项目在已选择列表中出现多次(自动勾选冲突)。
} * 2. 勾选后自动在已选择区域生成对应的折叠项,未勾选则移除。
*/
// 修复:清理名称,去除冗余的“套餐”字样 const handleItemCheck = (item) => {
const cleanName = (name: string) => { const exists = selectedItems.value.find(s => s.id === item.id);
if (!name) return ''
return name.replace(/套餐/g, '').trim()
}
// 修复:项目勾选与检查方法解耦,仅维护已选列表,不联动勾选方法
const handleItemCheck = (item: ExamItem) => {
if (item.checked) { if (item.checked) {
// 若未加入已选列表,则添加(方法默认未勾选) if (!exists) {
if (!selectedItems.value.find(s => s.id === item.id)) { // 深拷贝,防止后续修改影响原列表
selectedItems.value.push({ const copy = {
...item, id: item.id,
methods: item.methods.map(m => ({ ...m, checked: false })) name: item.name,
}) methods: (item.methods || []).map(m => ({
id: m.id,
name: m.name,
checked: false,
})),
};
selectedItems.value.push(copy);
} }
} else { } else {
// 取消勾选则从已选列表移除,并清理折叠状态 if (exists) {
selectedItems.value = selectedItems.value.filter(s => s.id !== item.id) selectedItems.value = selectedItems.value.filter(s => s.id !== item.id);
activeCollapseNames.value = activeCollapseNames.value.filter(n => n !== item.id)
} }
} }
};
/**
* 处理检查方法(明细)的勾选
* 只在已选择列表内部操作,避免明细与项目列表耦合。
*/
const handleMethodCheck = (selItem, method) => {
// 这里可以加入业务校验,例如同一项目只能选择一种检查方式等
// 示例:若业务要求只能单选,则取消同项目其他已选 method
// if (singleChoice) {
// selItem.methods.forEach(m => {
// if (m.id !== method.id) m.checked = false;
// });
// }
};
// 修复:检查方法独立控制,不反向影响父项目状态
const handleMethodCheck = (parentItem: ExamItem, method: Method) => {
const sel = selectedItems.value.find(s => s.id === parentItem.id)
if (sel) {
const targetMethod = sel.methods.find(m => m.id === method.id)
if (targetMethod) {
targetMethod.checked = method.checked
}
}
}
</script> </script>
<style scoped> <style scoped>
.exam-apply-container { .exam-apply-container {
display: flex; display: flex;
flex-direction: column;
gap: 16px; gap: 16px;
height: 100%;
padding: 16px;
} }
.category-panel, .item-panel, .selected-panel {
/* 左侧分类 */
.category-panel {
width: 200px;
}
/* 中间项目列表 */
.item-panel {
flex: 1; flex: 1;
overflow: auto; max-width: 400px;
} }
.item-list { .item-list {
display: flex; max-height: 500px;
flex-direction: column; overflow-y: auto;
gap: 8px;
} }
.item-row { .item-row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px;
padding: 4px 0; padding: 4px 0;
} }
/* 修复:名称自适应宽度,超长省略并支持悬浮提示 */
.item-name { .item-name {
flex: 1; margin-left: 8px;
/* 防止名称过长遮挡 */
display: inline-block;
max-width: 180px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
cursor: pointer; }
/* 已选择区域 */
.selected-panel {
flex: 1;
max-width: 400px;
} }
.collapse-title { .collapse-title {
font-weight: 500; display: inline-block;
max-width: 200px;
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
max-width: 100%;
}
.method-container {
padding: 8px 0 8px 24px;
border-left: 2px solid #e4e7ed;
margin-left: 8px;
} }
.method-row { .method-row {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px;
padding: 4px 0; padding: 4px 0;
} }
.empty-tip { .method-name {
color: #909399; margin-left: 8px;
text-align: center; display: inline-block;
padding: 20px 0; max-width: 180px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
</style> </style>