| src/components/NotificationCenter.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/Dashboard.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| tests/refinement.ui.test.mjs | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/components/NotificationCenter.vue
@@ -4,7 +4,6 @@ import { useExceptions } from '@/stores/exceptions' import { getUserInfo } from '@/api/auth' import { useTodos, clearTodos } from '@/stores/todos' import { useTests } from '@/stores/tests' interface NotificationItem { id: string @@ -12,7 +11,7 @@ detail: string time: string path: string type: 'exception' | 'todo' | 'test' type: 'exception' | 'todo' } const READ_KEY = 'battery_detection_read_notifications_v1' @@ -31,7 +30,6 @@ } onMounted(refreshTodos) watch(visible, value => { if (value) void refreshTodos() }) const { records: tests } = useTests() function loadReadIds() { try { @@ -51,10 +49,6 @@ ...todos.value.filter(item => item.status === '待处理').map(item => ({ id: `todo-${item.id}`, title: '待办任务提醒', detail: `${item.content} · 负责人 ${item.owner}`, time: item.createdAt, path: '/todo-list', type: 'todo' as const, })), ...tests.value.filter(item => item.status === '待测试').map(item => ({ id: `test-${item.id}`, title: '测试等待执行', detail: `${item.name} · ${item.batteryGroup} · ${item.batteryCount} 个电池`, time: item.createdAt, path: `/test-list/${item.id}/console`, type: 'test' as const, })), ].sort((a, b) => b.time.localeCompare(a.time)).slice(0, 20)) @@ -76,7 +70,7 @@ } function typeLabel(type: NotificationItem['type']) { return type === 'exception' ? '异常' : type === 'todo' ? '待办' : '测试' return type === 'exception' ? '异常' : '待办' } </script> @@ -92,7 +86,7 @@ <el-alert v-if="todoError" :title="todoError" type="error" :closable="false" /> <div v-if="notifications.length" class="notification-list"> <button v-for="item in notifications" :key="item.id" type="button" class="notification-item" :class="[{ unread: !readIds.has(item.id) }, item.type]" @click="openNotification(item)"> <span class="type-icon"><el-icon><Warning v-if="item.type === 'exception'" /><List v-else-if="item.type === 'todo'" /><Monitor v-else /></el-icon></span> <span class="type-icon"><el-icon><Warning v-if="item.type === 'exception'" /><List v-else /></el-icon></span> <span class="notification-content"><span class="notification-meta"><b>{{ typeLabel(item.type) }}</b><time>{{ item.time }}</time></span><strong>{{ item.title }}</strong><small>{{ item.detail }}</small></span> <i v-if="!readIds.has(item.id)" class="unread-dot" aria-hidden="true"></i> </button> src/views/Dashboard.vue
@@ -7,7 +7,7 @@ import { GridComponent, TooltipComponent } from 'echarts/components' import VChart from 'vue-echarts' import type { DashboardTest } from '@/api/dashboard' import { useDashboard } from '@/stores/dashboard' import { useDashboard, clearDashboard } from '@/stores/dashboard' import { getUserInfo } from '@/api/auth' import { getCurrentUser } from '@/utils/auth' import { useTodos, clearTodos } from '@/stores/todos' @@ -29,7 +29,7 @@ const main = results[0]; const todos = results[1] if (main.status === 'rejected') dashboardError.value = main.reason instanceof Error ? main.reason.message : '首页数据加载失败' if (todos.status === 'rejected') todoError.value = todos.reason instanceof Error ? todos.reason.message : '待办加载失败' } catch (error) { clearTodos(); dashboardError.value = error instanceof Error ? error.message : '首页加载失败' } } catch (error) { clearTodos(); clearDashboard(); dashboardError.value = error instanceof Error ? error.message : '首页加载失败' } finally { loading.value = false } } onMounted(loadPage) tests/refinement.ui.test.mjs
@@ -54,6 +54,12 @@ await expect(page.locator('.todo-panel')).toContainText('本人待办') await expect(page.locator('.cabinet-panel')).toContainText('在线') await expect(page.locator('.dashboard')).not.toContainText('P1') await expect(page.locator('.notification-badge')).toHaveText('1') await page.getByRole('button',{name:'消息通知',exact:true}).click() await expect(page.locator('.notification-list')).toContainText('本人待办') await expect(page.locator('.notification-list')).not.toContainText('测试等待执行') await page.keyboard.press('Escape') await expect(page.locator('.notification-drawer')).not.toBeVisible() await page.screenshot({path:resolve(artifacts,'dashboard-desktop.png'),fullPage:true}) dashboardFails=true await page.getByRole('button',{name:'刷新',exact:true}).click()