Fix Bug #550: AI修复
This commit is contained in:
@@ -0,0 +1,193 @@
|
|||||||
|
<template>
|
||||||
|
<div class="examination-request-wrapper">
|
||||||
|
<!-- 左侧:检查项目分类 -->
|
||||||
|
<div class="panel category-panel">
|
||||||
|
<div class="panel-title">检查项目分类</div>
|
||||||
|
<el-tree
|
||||||
|
:data="categoryTree"
|
||||||
|
node-key="id"
|
||||||
|
highlight-current
|
||||||
|
@node-click="handleCategoryClick"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中间:检查项目列表 -->
|
||||||
|
<div class="panel item-panel">
|
||||||
|
<div class="panel-title">检查项目</div>
|
||||||
|
<el-checkbox-group v-model="selectedItemIds" @change="onItemSelectChange">
|
||||||
|
<el-checkbox
|
||||||
|
v-for="item in currentItems"
|
||||||
|
:key="item.id"
|
||||||
|
:label="item.id"
|
||||||
|
class="item-checkbox"
|
||||||
|
>
|
||||||
|
{{ formatItemName(item.name) }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 右侧:已选择区域 -->
|
||||||
|
<div class="panel selected-panel">
|
||||||
|
<div class="panel-title">已选择</div>
|
||||||
|
<div class="selected-list">
|
||||||
|
<div v-for="group in selectedGroups" :key="group.itemId" class="selected-group">
|
||||||
|
<!-- 父级:检查项目(支持点击展开/收起) -->
|
||||||
|
<div class="group-header" @click="toggleExpand(group.itemId)">
|
||||||
|
<el-icon class="expand-icon">
|
||||||
|
<ArrowRight v-if="!group.expanded" />
|
||||||
|
<ArrowDown v-else />
|
||||||
|
</el-icon>
|
||||||
|
<el-tooltip :content="group.itemName" placement="top" :show-after="300" :offset="10">
|
||||||
|
<span class="group-name">{{ group.itemName }}</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 子级:检查方法(默认收起,独立勾选) -->
|
||||||
|
<div v-show="group.expanded" class="method-container">
|
||||||
|
<el-checkbox-group v-model="group.selectedMethodIds" @change="onMethodSelectChange(group)">
|
||||||
|
<el-checkbox
|
||||||
|
v-for="method in group.methods"
|
||||||
|
:key="method.id"
|
||||||
|
:label="method.id"
|
||||||
|
>
|
||||||
|
{{ method.name }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-empty v-if="selectedGroups.length === 0" description="暂无已选项目" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { ArrowRight, ArrowDown } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
// 状态定义
|
||||||
|
const categoryTree = ref([])
|
||||||
|
const currentItems = ref([])
|
||||||
|
const selectedItemIds = ref([])
|
||||||
|
const selectedGroups = ref([])
|
||||||
|
|
||||||
|
// 格式化名称:清理冗余“套餐”字样
|
||||||
|
const formatItemName = (name) => {
|
||||||
|
return name ? name.replace(/套餐/g, '').trim() : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分类点击:加载对应项目
|
||||||
|
const handleCategoryClick = (data) => {
|
||||||
|
currentItems.value = data.items || []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 项目勾选变更(核心修复1:解耦联动,不自动勾选检查方法)
|
||||||
|
const onItemSelectChange = (ids) => {
|
||||||
|
// 仅同步已选项目结构,保留原有方法勾选状态或初始化为空
|
||||||
|
const newGroups = ids.map(id => {
|
||||||
|
const existing = selectedGroups.value.find(g => g.itemId === id)
|
||||||
|
if (existing) return existing
|
||||||
|
|
||||||
|
const item = currentItems.value.find(i => i.id === id)
|
||||||
|
return {
|
||||||
|
itemId: id,
|
||||||
|
itemName: formatItemName(item?.name || ''),
|
||||||
|
methods: item?.methods || [], // 关联的检查方法列表
|
||||||
|
selectedMethodIds: [], // 独立维护方法勾选状态
|
||||||
|
expanded: false // 核心修复3:默认收起明细
|
||||||
|
}
|
||||||
|
})
|
||||||
|
selectedGroups.value = newGroups
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法勾选变更(核心修复1:独立处理,不影响父级或其他组)
|
||||||
|
const onMethodSelectChange = (group) => {
|
||||||
|
// 仅触发当前组方法状态更新,业务层可在此处同步至后端或计算费用
|
||||||
|
console.log(`[Examination] 方法独立勾选: ${group.itemId} -> ${group.selectedMethodIds}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 展开/收起控制(核心修复3:支持手动切换明细显示)
|
||||||
|
const toggleExpand = (itemId) => {
|
||||||
|
const group = selectedGroups.value.find(g => g.itemId === itemId)
|
||||||
|
if (group) {
|
||||||
|
group.expanded = !group.expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.examination-request-wrapper {
|
||||||
|
display: flex;
|
||||||
|
gap: 12px;
|
||||||
|
height: 100%;
|
||||||
|
padding: 12px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.panel {
|
||||||
|
flex: 1;
|
||||||
|
border: 1px solid #ebeef5;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.panel-title {
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: #303133;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.category-panel, .item-panel {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.selected-panel {
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
.selected-list {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.selected-group {
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: #fff;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.group-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #ebeef5;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
.group-header:hover {
|
||||||
|
background: #f5f7fa;
|
||||||
|
}
|
||||||
|
.expand-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #909399;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
.group-name {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #303133;
|
||||||
|
}
|
||||||
|
.method-container {
|
||||||
|
padding: 10px 12px 10px 28px;
|
||||||
|
background: #fafbfc;
|
||||||
|
}
|
||||||
|
.item-checkbox {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
49
tests/e2e/specs/bug-regression.spec.ts
Normal file
49
tests/e2e/specs/bug-regression.spec.ts
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
import { test, expect } from '@playwright/test';
|
||||||
|
|
||||||
|
// 原有回归测试用例...
|
||||||
|
test.describe('Existing HIS Regression Tests', () => {
|
||||||
|
test('login and navigate to doctor station', async ({ page }) => {
|
||||||
|
await page.goto('/login');
|
||||||
|
await page.fill('input[name="username"]', 'admin');
|
||||||
|
await page.fill('input[name="password"]', '123456');
|
||||||
|
await page.click('button[type="submit"]');
|
||||||
|
await expect(page).toHaveURL(/.*dashboard.*/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// @bug550 @regression
|
||||||
|
test.describe('Bug #550 Regression: Examination Request Selection Interaction', () => {
|
||||||
|
test('should decouple item/method selection, display full names, and structure details correctly', async ({ page }) => {
|
||||||
|
// 1. 进入门诊医生站-检查申请单
|
||||||
|
await page.goto('/clinic/doctor-station/examination');
|
||||||
|
await page.waitForLoadState('networkidle');
|
||||||
|
|
||||||
|
// 2. 展开“彩超”分类并勾选“128线排”
|
||||||
|
await page.click('text=彩超');
|
||||||
|
await page.waitForSelector('.item-checkbox:has-text("128线排")');
|
||||||
|
await page.check('.item-checkbox:has-text("128线排")');
|
||||||
|
|
||||||
|
// 3. 验证联动解耦:检查方法不应被自动勾选
|
||||||
|
const methodCheckbox = page.locator('.method-container .el-checkbox').first();
|
||||||
|
await expect(methodCheckbox).not.toBeChecked();
|
||||||
|
|
||||||
|
// 4. 验证卡片显示:无“套餐”前缀,支持完整名称提示,宽度自适应
|
||||||
|
const selectedCard = page.locator('.selected-group').first();
|
||||||
|
await expect(selectedCard).toContainText('128线排');
|
||||||
|
await expect(selectedCard).not.toContainText('套餐');
|
||||||
|
|
||||||
|
// 验证悬停提示完整名称
|
||||||
|
await selectedCard.hover();
|
||||||
|
const tooltip = page.locator('.el-tooltip__trigger');
|
||||||
|
await expect(tooltip).toBeVisible();
|
||||||
|
|
||||||
|
// 5. 验证默认收起状态
|
||||||
|
const methodContainer = page.locator('.method-container');
|
||||||
|
await expect(methodContainer).not.toBeVisible();
|
||||||
|
|
||||||
|
// 6. 验证层级结构:点击展开后显示“检查项目 > 检查方法”
|
||||||
|
await page.click('.group-header');
|
||||||
|
await expect(methodContainer).toBeVisible();
|
||||||
|
await expect(page.locator('.method-container .el-checkbox')).toHaveCount(1); // 至少展示关联方法
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user