Browse Source

docs: 增加 Alarms/Media 薄卡片组件设计

抽取 AlarmItem 与 MediaCard 展示组件,页面保留数据与请求。
main
xiaosi 3 weeks ago
parent
commit
4c7ad7dd8b
  1. 207
      docs/superpowers/specs/2026-08-28-alarms-media-card-components-design.md

207
docs/superpowers/specs/2026-08-28-alarms-media-card-components-design.md

@ -0,0 +1,207 @@
# Alarms + Media 薄卡片组件设计
## 背景
TDesign 表单/页签/标准列表迁移与 Devices 真分页已收口。仍有一批**强定制卡列表**沿用原型 `article + prototype.css`
- Alarms:线性 `alarm-item`
- Media:直播/原始视频网格卡
- Monitor:侧栏 `device-card`(树形绑定机、多选)
- Tasks:航线库 `route-grid`
本阶段只做 **Alarms + Media** 的本地薄展示组件,降低页面模板体积,为后续 Monitor 设备卡抽离铺路。
## 目标
1. 抽出 `AlarmItem.vue`、`MediaCard.vue` 两个展示组件。
2. `AlarmsView` / `MediaView` 仅用组件替换 `v-for` 内的 `article` 循环体。
3. **视觉与交互保持现状**:class 仍走 `prototype.css`,不引入 `t-list` / `t-card` 硬套。
4. 数据加载、空态、映射、请求、tab 仍留在页面。
## 非目标
- 不改 Monitor 侧栏 / 地图 / 飞行控制 / LivePlayer
- 不改 Tasks 航线库卡与航线编辑器
- 不迁 CSS 到 scoped(本阶段)
- 不改后端 API、分页策略、业务字段语义
- 不做通用 `BusinessCard` 抽象
## 方案(已选 A)
按视图各抽 **1 个列表项组件**
| 组件 | 用途 |
|------|------|
| `src/components/AlarmItem.vue` | 告警列表单行 |
| `src/components/MediaCard.vue` | 直播卡 / 原始视频卡(`variant` 区分) |
不抽 `AlarmList` / `MediaGrid` 容器层(循环与空态仍在页面,避免无收益透传)。
## 组件契约
### AlarmItem
**Props(展示用,与现映射字段对齐)**
| prop | 类型 | 说明 |
|------|------|------|
| `severity` | string | 严重 / 警告 / 提示 |
| `severityClass` | string | `critical` / `medium` / `low` |
| `title` | string | 告警标题 |
| `device` | string | 设备标识文案 |
| `time` | string | 触发时间文案 |
| `status` | string | 待处理 / 已确认 / 已恢复 |
| `statusClass` | string | 状态样式 class |
**Events**
| event | payload | 说明 |
|-------|---------|------|
| `handle` | — | 点击「处理」;页面侧带上整条 alarm 调 API |
根节点保持:
```html
<article class="alarm-item" :class="severityClass">
```
内部结构与现 `AlarmsView` 模板一致(severity 标签、title/device·time、status、`t-button` 处理)。
### MediaCard
**Props**
| prop | 类型 | 说明 |
|------|------|------|
| `variant` | `'live' \| 'video'` | 直播 / 原始视频 |
| `name` | string | 主标题 |
| `desc` | string | 副文案 |
| `visualClass` | string | 封面背景 class(如 `dock-camera`) |
| `source` | string? | live:画面来源角标 |
| `duration` | string? | video:时长角标 |
**Events**
| event | 何时 |
|-------|------|
| `play` | 点击播放按钮(live / video 共用) |
| `action` | live:更多;video:下载 |
根节点:
```html
<article>
<div class="media-visual" :class="visualClass"></div>
<div class="media-card-copy"></div>
</article>
```
- `variant === 'live'`:LIVE 角标 + `source` + 更多按钮(`#i-more`)
- `variant === 'video'`:`duration` + 下载按钮(`#i-download`)
网格容器 class(`live-media-grid` / `media-grid`)仍在 `MediaView`,不进组件。
## 页面改造
### AlarmsView
```html
<div class="alarm-list">
<AlarmItem
v-for="a in alarms"
:key="a.id"
v-bind="alarmItemProps(a)"
@handle="handle(a)"
/>
<div v-if="!alarms.length" class="table-empty">暂无告警</div>
</div>
```
- `load` / `handle` / 指标 computed / 侧栏 bars 不变
- 可用小函数或直接逐 prop 绑定;**禁止**把 resolve API 塞进组件
### MediaView
```html
<div class="live-media-grid">
<MediaCard
v-for="s in liveStreams"
:key="s.id"
variant="live"
:name="s.name"
:desc="s.desc"
:source="s.source"
:visual-class="s.visualClass"
@play="openLive(s)"
@action="ui.toast('更多操作')"
/>
</div>
<div class="media-grid">
<MediaCard
v-for="v in videos"
:key="v.id"
variant="video"
@play="ui.toast('播放:' + v.name)"
@action="download(v)"
/>
</div>
```
- tabs、load、download、路由 `view` query 不变
## 样式
- 组件 **不加** 会改变视觉的 scoped 新规则
- 继续依赖全局 `prototype.css` 中:
- `.alarm-item` 及相关
- `.live-media-grid` / `.media-grid` / `.media-visual` / `.media-card-copy` / `.live-corner` / `.media-duration`
- 若为消除 Vue 属性继承告警需 `inheritAttrs`,不得改 class 语义
## 文件清单
| 动作 | 路径 |
|------|------|
| 新增 | `src/components/AlarmItem.vue` |
| 新增 | `src/components/MediaCard.vue` |
| 修改 | `src/views/AlarmsView/AlarmsView.vue` |
| 修改 | `src/views/MediaView/MediaView.vue` |
## 实现顺序
1. **A**`AlarmItem` + `AlarmsView` 接入;单独 commit
2. **B**`MediaCard` + `MediaView` 接入;单独 commit
3. **C** — 浏览器冒烟:告警列表/处理按钮;媒体直播卡/视频卡播放与操作
建议 commit message:
- `refactor: 抽取 AlarmItem 告警列表项组件`
- `refactor: 抽取 MediaCard 媒体网格卡组件`
## 验收标准
1. Alarms 页:列表渲染、空态、处理确认流与 resolve 成功刷新仍可用
2. Media 页:直播/视频 tab、卡数量、播放/更多/下载行为与抽离前一致
3. DOM:仍为 `article.alarm-item` / 媒体 `article > .media-visual + .media-card-copy`
4. 无控制台 error;不回归 Monitor / Devices / Tasks
5. 不修改 `prototype.css`(本阶段无必要删除/搬迁)
## 风险与后续
| 风险 | 处理 |
|------|------|
| 漏绑 class 导致样式掉 | 对照现模板逐字段复制;冒烟看截图 |
| emit 丢上下文 | 页面 `@handle="handle(a)"` 闭包带 id |
| 过早抽象 | 明确禁止 BusinessCard;Monitor 另阶段 |
**后续(不在本 spec)**:Monitor `DockDeviceCard`;Tasks `RouteCard`;可选 CSS 迁 scoped。
## 约束
- 工作目录:`/Users/qingyuan/CodeProject/laic-frontend`
- 不改后台
- 不 `git add -A`;按文件精确 add + 中文 commit
- 跳过全量单测;以页面冒烟为准
Loading…
Cancel
Save