You cannot 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.1 KiB
6.1 KiB
广播系统软件架构文档
1. 架构目标
构建一个基于 Tauri v2 的桌面广播显示系统,满足以下架构目标:
- 支持固定窗口行为(无边框、左上角定位、启动即开)
- 支持 5000px 标尺在任意屏宽下的稳定分段显示
- 支持子元素跨段连续渲染
- 保持模块边界清晰,便于后续扩展(动态数据、渲染升级)
2. 总体架构
采用“宿主层 + 前端应用层 + 渲染域层”的分层结构:
- 宿主层(Tauri Runtime)
- 负责窗口生命周期、屏幕信息读取、系统能力接入
- 前端应用层(Vue Application)
- 负责状态管理、分段计算、组件编排
- 渲染域层(Ruler Rendering Domain)
- 负责刻度绘制、切片映射、子元素裁剪与连续性
架构原则:
- 计算与渲染分离:算法在
composables/services,界面在components/views - 数据驱动:通过状态变化触发渲染,不在组件中写复杂业务判断
- 可替换渲染:先 DOM,后续可平滑迁移到 Canvas
3. 逻辑视图(模块划分)
建议目录结构:
broadcast-client/
src/
main.ts
App.vue
views/
BroadcastView.vue
components/
RulerCanvas.vue
RulerSegment.vue
RulerTicks.vue
SegmentChildren.vue
composables/
useScreenInfo.ts
useSegmentLayout.ts
useRulerTicks.ts
services/
segmentService.ts
childSliceService.ts
models/
ruler.ts
segment.ts
child.ts
utils/
math.ts
src-tauri/
tauri.conf.json
src/
lib.rs
模块职责:
useScreenInfo:读取并维护当前主屏宽度、DPI 信息segmentService:计算段数量、每段映射关系useRulerTicks:生成 10/100 刻度数据childSliceService:计算子元素在每段的可见切片RulerSegment:单段渲染容器(裁剪窗口)SegmentChildren:渲染跨段子元素切片
4. 关键数据模型
type TickType = "minor" | "major";
interface Tick {
x: number;
type: TickType;
label?: string;
}
interface Segment {
index: number;
sourceX: number;
sliceWidth: number;
top: number;
height: number; // 固定 64
}
interface ChildElement {
id: string;
left: number;
width: number;
top: number;
height: number;
zIndex?: number;
className?: string;
}
interface ChildSlice {
childId: string;
segmentIndex: number;
renderLeft: number;
renderTop: number;
renderWidth: number;
renderHeight: number;
clipOffset: number;
}
设计说明:
Segment只描述“段映射”,不关心具体 UI。ChildSlice是“子元素在某段中的投影结果”,用于直接渲染。- 所有坐标统一使用同一逻辑坐标系(以 5000px 主轴为基准)。
5. 运行时流程(时序)
启动流程:
- Tauri 启动并创建窗口(无边框,位置
(0,0))。 - 前端初始化,读取屏幕宽度
screenWidth。 - 计算
segments = ceil(5000 / screenWidth)。 - 生成刻度数据
ticks,构建段列表segmentList。 - 渲染每段:段容器裁剪 + 虚拟标尺偏移显示。
- 若存在子元素,计算
ChildSlice[]并叠加渲染。
更新流程(屏宽变化):
- 监听窗口尺寸/屏幕变化事件。
- 重新计算
segmentList与ChildSlice[]。 - 增量更新视图(避免全量销毁重建)。
6. 关键算法设计
6.1 分段算法
- 输入:
TOTAL_WIDTH=5000,screenWidth,SEGMENT_HEIGHT=64 - 输出:
Segment[] - 复杂度:
O(n),n = segmentCount
核心规则:
segmentCount = ceil(5000 / screenWidth)- 每段
sourceX = i * screenWidth sliceWidth = min(screenWidth, 5000 - sourceX)
6.2 子元素切片算法
- 输入:
ChildElement[],Segment[] - 输出:
ChildSlice[] - 复杂度:
O(m * n)(可按区间优化)
相交判定:
- 仅当子元素区间与段区间重叠时生成切片
- 切片宽度为区间交集长度
- 渲染左偏移为交集起点相对段起点
7. 部署视图
单机本地部署:
- 可执行文件(Tauri 打包产物)
- 前端静态资源内嵌
- 无外部服务依赖
跨平台建议:
- Windows 为主目标平台
- 后续可扩展到 Linux/macOS(保持 API 使用跨平台)
8. 非功能架构设计
8.1 性能
- 预计算与缓存刻度数据
- 分段与切片计算函数纯函数化,便于 memoization
- 控制组件重渲染范围(按段粒度更新)
8.2 可维护性
- 算法层独立文件,配套单元测试
- 组件职责单一,避免“巨型组件”
- 使用 TypeScript 类型约束输入输出
8.3 兼容性
- 适配不同分辨率,屏宽变化自动重算
- 高 DPI 场景下进行像素对齐优化
9. 异常与容错架构
- 屏幕宽度读取失败:降级默认值(如 1920)
- 输入数据异常(负宽度、越界坐标):统一在 service 层校正/裁剪
- 渲染失败保护:关键计算异常时记录日志并回退最小可用视图
10. 安全与边界
当前系统以本地渲染为主,安全关注点较轻,建议:
- 最小化 Tauri 权限配置
- 不暴露不必要的系统 API
- 对未来外部输入(若接入)进行 schema 校验
11. 测试架构
测试分层:
- 单元测试:
segmentService、childSliceService - 组件测试:
RulerSegment、SegmentChildren - 集成测试:启动后窗口行为与全链路渲染
关键断言:
- 分段数量与位置正确
- 末段宽度裁剪正确
- 子元素跨段连续且无视觉跳变
- 大小刻度在每段中对齐正确
12. 可扩展路线
- 渲染升级:DOM -> Canvas/WebGL
- 数据升级:静态子元素 -> 实时广播内容流
- 交互升级:缩放、定位、标记线、主题切换
- 多屏支持:副屏渲染与窗口同步控制
13. 架构决策记录(ADR 简版)
- ADR-001:采用 Tauri v2 作为宿主框架(轻量、跨平台)
- ADR-002:采用 Vue3 + TS 作为前端基础(可维护、类型安全)
- ADR-003:先采用 DOM 裁剪方案(交付快、调试友好),保留 Canvas 替换能力
- ADR-004:分段按屏宽计算并纵向堆叠(严格满足需求中的显示规则)