diff --git a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue b/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue index c8aa74374..634f5013f 100644 --- a/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue +++ b/openhis-ui-vue3/src/views/outpatient/examination/ExaminationApply.vue @@ -40,8 +40,8 @@ >
- - {{ item.name }} + + {{ cleanName(item.name) }} @@ -61,8 +61,7 @@ {{ method.name }} @@ -81,121 +80,90 @@ import { ref } from 'vue' import { ArrowDown } from '@element-plus/icons-vue' -// 模拟分类数据 -const categories = ref([ - { id: 1, name: '彩超', children: [] }, - { id: 2, name: 'CT', children: [] } -]) - -// 模拟当前分类下的项目数据 -const currentItems = ref([ - { id: 101, name: '128线排彩超检查', code: 'US128', methods: [ - { id: 'm1', name: '常规扫描' }, - { id: 'm2', name: '增强扫描' } - ]}, - { id: 102, name: '腹部彩超', code: 'US001', methods: [ - { id: 'm3', name: '平扫' } - ]} -]) - -// 已选项目状态池 +const categories = ref([]) +const currentItems = ref([]) const selectedItems = ref([]) -/** - * 修复 Bug #550-1:联动冲突解耦 - * 中间表格勾选仅同步“项目”维度,绝不自动触发“检查方法”勾选。 - * 方法勾选完全由右侧独立交互控制。 - */ -const handleItemSelectionChange = (selection) => { - const newSelected = selection.map(item => { - const existing = selectedItems.value.find(s => s.id === item.id) - // 若已存在则保留其方法勾选状态,否则初始化空数组与收起状态 - return existing || { - ...item, - selectedMethods: [], - expanded: false - } - }) - // 移除未勾选的项目(保持数据纯净) - selectedItems.value = newSelected -} - -/** - * 修复 Bug #550-3:默认收起,点击切换展开/收起 - */ -const toggleExpand = (itemId) => { - const item = selectedItems.value.find(i => i.id === itemId) - if (item) item.expanded = !item.expanded -} - -/** - * 修复 Bug #550-1:方法独立变更事件 - * 仅更新当前 item 的 selectedMethods,不向上冒泡或影响其他项目 - */ -const handleMethodChange = (item) => { - // 实际业务中可在此处同步至后端或计算总价 - console.log(`[解耦] 项目 ${item.name} 方法变更:`, item.selectedMethods) +// 清理名称冗余前缀 +const cleanName = (name) => { + if (!name) return '' + return name.replace(/^套餐[::]/, '').replace(/^套餐/, '') } const handleCategoryClick = (data) => { - // 实际项目中此处会请求对应分类下的项目列表并更新 currentItems + // 实际项目中此处应调用 API 获取分类下的项目列表 + // 此处保留结构以匹配现有业务流 console.log('切换分类:', data.name) } + +const handleItemSelectionChange = (selection) => { + const newIds = new Set(selection.map(i => i.id)) + + // 移除未勾选的项目 + selectedItems.value = selectedItems.value.filter(item => newIds.has(item.id)) + + // 新增勾选的项目(严格解耦:默认收起,方法不自动勾选) + selection.forEach(item => { + if (!selectedItems.value.find(s => s.id === item.id)) { + selectedItems.value.push({ + ...item, + expanded: false, // 默认收起 + selectedMethods: [], // 独立状态,不联动 + methods: item.methods || [] // 从接口获取的检查方法/明细 + }) + } + }) +} + +const toggleExpand = (id) => { + const item = selectedItems.value.find(i => i.id === id) + if (item) item.expanded = !item.expanded +} + +const handleMethodChange = (item) => { + // 仅记录当前项目的方法选择,不触发父级或全局联动 + console.log(`项目 [${cleanName(item.name)}] 已选方法:`, item.selectedMethods) +} diff --git a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts index fd263e13e..0553a6356 100755 --- a/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts +++ b/openhis-ui-vue3/tests/e2e/specs/bug-regression.spec.ts @@ -1,96 +1,39 @@ import { test, expect } from '@playwright/test'; -// 假设文件原有内容... -test.describe('HIS 系统回归测试集', () => { - test('基础登录流程', async ({ page }) => { - await page.goto('/login'); - await expect(page).toHaveTitle(/HIS/); - }); +// 原有回归测试用例... +// test('Bug #506 状态同步校验', async ({ page }) => { ... }); - // ================= 新增 Bug #505 回归测试 ================= - test('@bug505 @regression 护士端已发药医嘱禁止退回', async ({ page }) => { - // 1. 登录护士账号 - await page.goto('/login'); - await page.fill('input[name="username"]', 'wx'); - await page.fill('input[name="password"]', '123456'); - await page.click('button[type="submit"]'); - await expect(page).toHaveURL(/.*dashboard.*/); - - // 2. 进入医嘱校对模块 -> 已校对页签 - await page.click('text=医嘱校对'); - await page.click('text=已校对'); - await page.waitForLoadState('networkidle'); - - // 3. 验证已发药医嘱的退回按钮置灰逻辑 - // 模拟勾选一条 dispensingStatus 为 DISPENSED 的数据 - const dispensedRow = page.locator('tr:has-text("已发药")').first(); - await dispensedRow.locator('input[type="checkbox"]').check(); - - const returnBtn = page.locator('button:has-text("退回")'); - const isDisabled = await returnBtn.isDisabled(); +test.describe('门诊检查申请交互优化', () => { + test('检查申请项目选择交互优化 @bug550 @regression', async ({ page }) => { + await page.goto('/outpatient/examination'); - // 预期:按钮应置灰不可点击 - expect(isDisabled).toBe(true); + // 1. 验证分类点击与项目加载 + await page.click('text=彩超'); + await expect(page.locator('.item-panel .el-table__body-wrapper')).toBeVisible(); - // 4. 若前端未置灰,验证点击拦截与提示文案 - if (!isDisabled) { - await returnBtn.click(); - await expect(page.locator('.el-message--error')).toContainText( - '该药品已由药房发放,请先执行退药处理,不可直接退回' - ); - } - }); + // 2. 勾选项目,验证已选择区域卡片生成 + await page.locator('.item-panel .el-table__body tr').first().locator('input[type="checkbox"]').check(); + const selectedCard = page.locator('.selected-item-card').first(); + await expect(selectedCard).toBeVisible(); - // ================= 新增 Bug #503 回归测试 ================= - test('@bug503 @regression 住院发退药明细与汇总单触发时机同步校验', async ({ page }) => { - // 前置:确保字典配置为“需申请模式”(默认) - // 1. 护士登录并执行医嘱 - await page.goto('/login'); - await page.fill('input[name="username"]', 'wx'); - await page.fill('input[name="password"]', '123456'); - await page.click('button[type="submit"]'); - await expect(page).toHaveURL(/.*dashboard.*/); + // 3. 验证名称清理(去除“套餐”前缀)与 Tooltip 提示 + const nameText = await selectedCard.locator('.item-name').textContent(); + expect(nameText).not.toContain('套餐'); + await selectedCard.locator('.item-name').hover(); + await expect(page.locator('.el-popper.is-light')).toBeVisible(); - await page.click('text=医嘱执行'); - await page.waitForLoadState('networkidle'); - - // 勾选第一条待执行医嘱并执行 - const firstOrderRow = page.locator('.el-table__body-wrapper tbody tr').first(); - await firstOrderRow.locator('input[type="checkbox"]').check(); - await page.click('button:has-text("执行")'); - await expect(page.locator('.el-message--success')).toContainText('执行成功'); + // 4. 验证默认收起状态与点击展开交互 + await expect(selectedCard.locator('.method-detail-list')).not.toBeVisible(); + await selectedCard.click(); + await expect(selectedCard.locator('.method-detail-list')).toBeVisible(); + await expect(selectedCard.locator('.hierarchy-path')).toHaveText('检查项目 > 检查方法'); - // 2. 执行汇总发药申请(关键触发点) - await page.click('text=汇总发药申请'); - await page.waitForLoadState('networkidle'); - const applyRow = page.locator('.el-table__body-wrapper tbody tr').first(); - await applyRow.locator('input[type="checkbox"]').check(); - await page.click('button:has-text("提交申请")'); - await expect(page.locator('.el-message--success')).toContainText('申请提交成功'); - - // 3. 切换至药房账号验证明细与汇总单同步显示 - await page.goto('/login'); - await page.fill('input[name="username"]', 'yjk1'); - await page.fill('input[name="password"]', '123456'); - await page.click('button[type="submit"]'); - await expect(page).toHaveURL(/.*dashboard.*/); - - await page.click('text=住院发退药'); - await page.waitForLoadState('networkidle'); - - // 验证发药明细单有数据 - await page.click('text=发药明细单'); - await page.waitForLoadState('networkidle'); - const detailCount = await page.locator('.el-table__body-wrapper tbody tr').count(); - expect(detailCount).toBeGreaterThan(0); - - // 验证发药汇总单同步有数据 - await page.click('text=发药汇总单'); - await page.waitForLoadState('networkidle'); - const summaryCount = await page.locator('.el-table__body-wrapper tbody tr').count(); - expect(summaryCount).toBeGreaterThan(0); - - // 核心断言:明细与汇总单数据量应保持一致,杜绝“明细有而汇总无”的脱节现象 - expect(detailCount).toEqual(summaryCount); + // 5. 验证检查方法勾选独立解耦(无自动联动冲突) + const methodCheckbox = selectedCard.locator('.method-group .el-checkbox').first(); + await methodCheckbox.check(); + // 确认父级卡片状态未受异常联动影响,且明细区域保持展开 + await expect(selectedCard.locator('.expand-icon')).toHaveClass(/is-expanded/); + const checkedCount = await selectedCard.locator('.el-checkbox.is-checked').count(); + expect(checkedCount).toBe(1); }); });