You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.0 KiB
6.0 KiB
Alarms + Media 薄卡片组件设计
背景
TDesign 表单/页签/标准列表迁移与 Devices 真分页已收口。仍有一批强定制卡列表沿用原型 article + prototype.css:
- Alarms:线性
alarm-item - Media:直播/原始视频网格卡
- Monitor:侧栏
device-card(树形绑定机、多选) - Tasks:航线库
route-grid
本阶段只做 Alarms + Media 的本地薄展示组件,降低页面模板体积,为后续 Monitor 设备卡抽离铺路。
目标
- 抽出
AlarmItem.vue、MediaCard.vue两个展示组件。 AlarmsView/MediaView仅用组件替换v-for内的article循环体。- 视觉与交互保持现状:class 仍走
prototype.css,不引入t-list/t-card硬套。 - 数据加载、空态、映射、请求、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 |
根节点保持:
<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:下载 |
根节点:
<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
<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
<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、路由
viewquery 不变
样式
- 组件 不加 会改变视觉的 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 |
实现顺序
- A —
AlarmItem+AlarmsView接入;单独 commit - B —
MediaCard+MediaView接入;单独 commit - C — 浏览器冒烟:告警列表/处理按钮;媒体直播卡/视频卡播放与操作
建议 commit message:
refactor: 抽取 AlarmItem 告警列表项组件refactor: 抽取 MediaCard 媒体网格卡组件
验收标准
- Alarms 页:列表渲染、空态、处理确认流与 resolve 成功刷新仍可用
- Media 页:直播/视频 tab、卡数量、播放/更多/下载行为与抽离前一致
- DOM:仍为
article.alarm-item/ 媒体article > .media-visual + .media-card-copy - 无控制台 error;不回归 Monitor / Devices / Tasks
- 不修改
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 - 跳过全量单测;以页面冒烟为准