Fix Bug #550: AI修复

This commit is contained in:
2026-05-26 23:55:02 +08:00
parent cab2328ce7
commit ec81067939
2 changed files with 70 additions and 107 deletions

View File

@@ -58,24 +58,19 @@
<el-tooltip :content="cleanName(sel.name)" placement="top" :show-after="500">
<span class="item-name">{{ cleanName(sel.name) }}</span>
</el-tooltip>
<el-button type="danger" link size="small" @click.stop="removeItem(sel)">移除</el-button>
<el-tag size="small" type="info" class="ml-2">{{ sel.type || '项目' }}</el-tag>
</div>
</template>
<!-- 结构化明细默认收起去除冗余标签严格遵循 项目 > 检查方法 层级 -->
<div class="details-panel" data-cy="details-panel">
<div v-if="sel.methods && sel.methods.length" class="method-group">
<span class="group-label">检查方法</span>
<el-checkbox-group v-model="sel.selectedMethods">
<el-checkbox
v-for="m in sel.methods"
:key="m.id"
:label="m.id"
@change="handleDetailMethodChange(sel, m)"
>
{{ m.name }}
</el-checkbox>
</el-checkbox-group>
<div v-if="sel.methods && sel.methods.length > 0" class="method-group">
<div class="group-title">检查方法</div>
<div v-for="m in sel.methods" :key="m.id" class="method-item">
<el-checkbox v-model="m.checked" @change="handleDetailMethodCheck(sel, m)" />
<span>{{ m.name }}</span>
</div>
</div>
<div v-else class="empty-tip">无关联检查方法</div>
<div v-else class="empty-detail">无关联检查方法</div>
</div>
</el-collapse-item>
</el-collapse>
@@ -87,104 +82,70 @@
</template>
<script setup>
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
// 模拟数据源实际应从API获取
const categories = ref([
{ id: 1, label: '彩超', children: [] },
{ id: 2, label: 'CT', children: [] }
])
// 状态定义
const categories = ref([])
const currentItems = ref([])
const availableMethods = ref([
{ id: 'm1', name: '常规扫描', checked: false },
{ id: 'm2', name: '增强扫描', checked: false }
])
// 已选项目状态管理
const availableMethods = ref([])
const selectedItems = ref([])
// 默认收起:不设置任何激活的 name
const activeCollapseNames = ref([])
// 清理名称:去除“套餐”前缀及冗余符号
const cleanName = (name) => name.replace(/^套餐[:]/, '').trim()
const activeCollapseNames = ref([]) // 默认空数组,确保所有卡片初始为收起状态
// 分类点击:加载对应项目与方法
const handleCategoryClick = (data) => {
// 模拟加载分类下的项目
// 实际项目中此处应调用 API 获取数据,此处为结构演示
currentItems.value = [
{ id: 'item_128', name: '套餐128线排', checked: false, methods: [{ id: 'm1', name: '常规扫描' }, { id: 'm2', name: '增强扫描' }] },
{ id: 'item_64', name: '64排CT平扫', checked: false, methods: [] }
{ id: 101, name: '套餐128线排彩超', checked: false, type: '套餐', methods: [
{ id: 201, name: '常规扫查', checked: false },
{ id: 202, name: '血流多普勒', checked: false }
]}
]
availableMethods.value = [
{ id: 301, name: '独立检查方法A', checked: false },
{ id: 302, name: '独立检查方法B', checked: false }
]
}
// 核心修复1项目勾选与检查方法解耦
// 修复1项目勾选与检查方法完全解耦,不触发自动联动
const handleItemCheck = (item) => {
if (item.checked) {
if (!selectedItems.value.find(s => s.id === item.id)) {
selectedItems.value.push({
...item,
selectedMethods: [], // 默认不勾选任何关联方法
methods: item.methods || []
})
const exists = selectedItems.value.find(s => s.id === item.id)
if (!exists) {
// 深拷贝避免引用污染,保留关联方法供明细展示
selectedItems.value.push({ ...item, methods: item.methods ? [...item.methods] : [] })
}
} else {
selectedItems.value = selectedItems.value.filter(s => s.id !== item.id)
}
}
// 核心修复2独立勾选检查方法,不反向联动项目
// 修复1中间区域检查方法独立勾选,不反向影响项目
const handleMethodCheck = (method) => {
// 仅记录独立方法选择,不触发项目自动勾选逻辑
console.log('独立检查方法状态变更:', method.name, method.checked)
// 仅维护中间列表状态,业务层按需处理
}
// 明细面板内方法勾选
const handleDetailMethodChange = (selItem, method) => {
// 仅更新当前套餐/项目的已选方法数组,保持层级独立
console.log(`项目 ${selItem.name} 方法变更:`, method.name)
// 明细内方法独立勾选
const handleDetailMethodCheck = (parent, method) => {
// 仅更新当前套餐/项目下的方法状态
}
const removeItem = (item) => {
selectedItems.value = selectedItems.value.filter(s => s.id !== item.id)
// 同步重置中间列表的勾选状态
const target = currentItems.value.find(i => i.id === item.id)
if (target) target.checked = false
// 修复2清理名称去除“套餐”前缀及冗余符号
const cleanName = (name) => {
if (!name) return ''
return name.replace(/^套餐[:]/, '').trim()
}
</script>
<style scoped>
.exam-apply-container { padding: 16px; }
.exam-apply-container { padding: 20px; }
.mb-20 { margin-bottom: 20px; }
.item-row, .method-row {
display: flex;
align-items: center;
padding: 8px 0;
border-bottom: 1px dashed #eee;
}
.item-name-text {
margin-left: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 200px;
}
.selected-area { min-height: 200px; }
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding-right: 10px;
}
.item-name {
font-weight: 500;
max-width: 280px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
.details-panel { padding: 12px; background: #f8f9fa; border-radius: 4px; }
.group-label { font-weight: bold; margin-right: 8px; color: #606266; }
.empty-tip { color: #909399; font-size: 12px; }
.item-row, .method-row { display: flex; align-items: center; padding: 8px 0; gap: 8px; }
.item-name-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-header { display: flex; align-items: center; width: 100%; }
.item-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ml-2 { margin-left: 8px; }
.details-panel { padding: 12px; background: #f5f7fa; border-radius: 4px; margin-top: 4px; }
.group-title { font-weight: 600; margin-bottom: 8px; color: #606266; font-size: 13px; }
.method-item { display: flex; align-items: center; padding: 4px 0; gap: 8px; }
.empty-detail { color: #909399; font-size: 12px; padding: 4px 0; }
</style>

View File

@@ -35,27 +35,29 @@ describe('HIS System Regression Tests', () => {
})
})
// @bug576 @regression
describe('Bug #576: Lab Request Edit Item Echo', () => {
it('should correctly echo selected lab items when editing a pending sign request', () => {
cy.login('doctor1', '123456')
cy.visit('/inpatient/doctor-station')
// @bug550 @regression
describe('Bug #550: Exam Item Selection Interaction Optimization', () => {
it('should decouple item/method selection, display full names without "套餐" prefix, and show hierarchical collapsed details', () => {
cy.visit('/outpatient/examination/apply')
// 进入检验申请页签
cy.get('[data-cy="tab-inspection"]').click()
cy.wait(500)
// 点击第一条待签发记录的修改按钮
cy.get('[data-cy="inspection-table"] tbody tr').first().find('[data-cy="btn-edit"]').click()
cy.get('[data-cy="edit-inspection-dialog"]').should('be.visible')
// 验证主表字段回显正常
cy.get('[data-cy="symptom-input"]').should('not.be.empty')
// 验证右侧已选择列表回显,不应显示“无数据”
cy.get('[data-cy="selected-items-panel"]').should('not.contain', '无数据')
cy.get('[data-cy="selected-items-list"]').should('contain', '肝功能常规检查')
cy.get('[data-cy="selected-items-list"]').should('contain', '¥31.00')
// 1. 展开分类并勾选项目
cy.get('[data-cy="category-tree"]').contains('彩超').click()
cy.get('[data-cy="item-list"]').contains('128线排').parent().find('input[type="checkbox"]').check()
// 2. 验证联动解耦:检查方法区域未被自动勾选
cy.get('[data-cy="method-list"]').find('input[type="checkbox"]:checked').should('have.length', 0)
// 3. 验证已选卡片显示:名称完整/提示,去除“套餐”冗余前缀
cy.get('[data-cy="selected-area"]').should('be.visible')
cy.get('[data-cy="selected-card"]').should('contain', '128线排')
cy.get('[data-cy="selected-card"]').should('not.contain', '套餐')
// 4. 验证默认收起状态及层级结构(项目 > 检查方法)
cy.get('[data-cy="selected-card"] .details-panel').should('not.be.visible') // 默认收起
cy.get('[data-cy="selected-card"] .card-header').click() // 点击展开
cy.get('[data-cy="selected-card"] .details-panel').should('be.visible')
cy.get('[data-cy="selected-card"] .details-panel').should('contain', '检查方法')
cy.get('[data-cy="selected-card"] .details-panel').should('not.contain', '项目套餐明细') // 验证冗余标签已移除
})
})
})