This commit is contained in:
me
2026-01-30 20:27:24 +08:00
parent dcbbda951e
commit 222449cb1b
2 changed files with 538 additions and 2 deletions

View File

@@ -0,0 +1,537 @@
# Slint 代理管理应用设计文档
**创建日期:** 2026-01-30
**状态:** 设计完成,待实施
## 项目概述
将 web 目录下的 Tauri + React 实现的代理管理工具,使用 Slint UI 组件库完整重新实现。应用包含 6 个主要页面,采用模块化架构,通过 Callback 与 Rust 后端交互。
## 整体架构
### 目录结构
```
ui/
├── app.slint # 主应用入口(替代 demo.slint
├── types.slint # 数据结构定义
├── components/ # 通用组件(已有 + 新增)
│ ├── button.slint # ✓ 已有
│ ├── badge.slint # ✓ 已有
│ ├── card.slint # ✓ 已有
│ ├── input.slint # ✓ 已有
│ ├── item.slint # ✓ 已有
│ ├── dialog.slint # ✓ 已有
│ ├── toast.slint # ✓ 已有
│ ├── sidebar.slint # ✓ 已有
│ ├── tabs.slint # ✓ 已有
│ ├── accordion.slint # ✓ 已有
│ ├── switch.slint # ✓ 已有
│ ├── select.slint # ✓ 已有
│ ├── label.slint # ✓ 已有
│ ├── progress.slint # ✓ 已有
│ ├── separator.slint # ✓ 已有
│ ├── tooltip.slint # ✓ 已有
│ └── empty.slint # ☐ 待实现
├── layouts/ # 布局组件(新增)
│ ├── page-layout.slint # ☐ 待实现
│ └── container.slint # ☐ 待实现
├── pages/ # 页面模块(新增)
│ ├── home.slint # ☐ 待实现
│ ├── proxies.slint # ☐ 待实现
│ ├── profiles.slint # ☐ 待实现
│ ├── connections.slint # ☐ 待实现
│ ├── logs.slint # ☐ 待实现
│ └── settings.slint # ☐ 待实现
└── theme/ # 主题系统(已有)
├── theme.slint # ✓ 已有
├── colors.slint # ✓ 已有
├── spacing.slint # ✓ 已有
└── typography.slint # ✓ 已有
```
### 核心设计原则
1. **页面独立性** - 每个页面是独立的 component通过 `if current-view == "xxx"` 条件渲染
2. **Callback 驱动** - 所有数据通过 callback 从 Rust 获取,页面只负责展示
3. **状态提升** - 应用状态(当前页面、数据)在主应用层管理,向下传递
4. **组件复用** - 最大化复用现有 components缺失的通用组件补充到 components/
5. **固定布局** - 桌面应用不需要响应式布局800x600 最小尺寸)
6. **Emoji 图标** - 使用 emoji 作为图标方案(简单且项目已在使用)
## 数据结构设计
### 核心数据类型ui/types.slint
```slint
// 配置文件信息
export struct Profile {
id: string,
name: string,
url: string,
type: string, // "remote" | "local"
updated-at: string,
usage: string, // "1.26GB / 100GB"
expire-at: string,
selected: bool,
}
// 代理节点
export struct ProxyNode {
name: string,
type: string, // "Vmess", "Shadowsocks", etc.
delay: int, // 延迟 ms-1 表示未测试
udp: bool,
}
// 代理组
export struct ProxyGroup {
name: string,
type: string, // "Selector", "URLTest", etc.
now: string, // 当前选中的节点
nodes: [ProxyNode],
}
// 连接信息
export struct Connection {
id: string,
host: string,
process: string,
rule: string,
chains: string,
upload: string,
download: string,
tring,
}
// 日志条目
export struct LogEntry {
time: string,
level: string, // "debug", "info", "warn", "error"
message: string,
}
// 设置项
export struct SettingItem {
key: string,
label: string,
value: string,
type: string, // "switch", "select", "button", "text"
enabled: bool,
}
```
## 主应用架构
### 应用状态与 Callbackui/app.slint
```slint
export component App inherits Window {
// ===== 应用状态 =====
in-out property <string> current-view: "home";
in-out property <bool> sidebar-collapsed: false;
数据状态 =====
in-out property <Profile> current-profile;
in-out property <[Profile]> profiles;
in-out property <[ProxyGroup]> proxy-groups;
in-out property <[Connection]> connections;
in-out property <[LogEntry]> mihomo-logs;
in-out property <[LogEntry]> app-logs;
in-out property <[SettingItem]> app-settings;
in-out property <[SettingItem]> clash-settings;
// ===== CallbacksRust 实现) =====
// 数据加载
callback load-profiles();
callback load-proxy-groups(string /* mode: rule/global/direct */);
callback load-connections();
callback load-logs(string /* type: mihomo/app */);
callback load-settings();
// 用户操作
callback select-profile(string /* profile-id */);
callback select-proxy(string /* group-name */, string /* node-name */);
callback test-proxy-delay(string /* node-name */);
callback toggle-setting(string /* key */, bool /* value */);
callback update-profile(string /* profile-id */);
callback delete-profile(string /* profile-id */);
callback add-profile(string /* url */);
// Toast 通知
callback show-toast(string /* message */, string /* type */);
}
```
### Callback 调用流程
1. 页面初始化时调用 `load-xxx()` 获取数据
2. 用户交互触发操作 callback`select-profile`
3. Rust 处理后更新对应的 property
4. Slint 自动重新渲染相关 UI
## 布局组件设计
### PageLayoutui/layouts/page-layout.slint
页面布局:包含固定头部 + 可滚动内容区
```slint
export component PageLayout inherits Rectangle {
in property <string> title;
in property <bool> show-actions: false;
@children // 头部右侧操作区(可选)
background: Theme.colors.background;
VerticalLayout {
// 固定头部48px
Rectangle {
height: 48px;
HorizontalLayout {
padding: SpacingSystem.spacing.s4;
alignment: space-between;
Text { text: root.title; }
// 右侧操作区
}
}
// 可滚动内容
Flickable {
VerticalLayout {
padding: SpacingSystem.spacing.s4;
spacing: SpacingSystem.spacing.s4;
}
}
}
}
```
### Containerui/layouts/container.slint
内容容器:带边框和圆角的卡片式容器
```slint
export component Container inherits Rectangle {
@children
background: Theme.colors.card;
border-radius: SpacingSystem.radius.md;
border-width: 1px;
border-color: Theme.colors.border;
VerticalLayout {
padding: SpacingSystem.spacing.s4;
spacing: SpacingSystem.spacing.s3;
}
}
```
## 页面功能说明
### 1. Home 页面ui/pages/home.slint
**功能:** 显示当前配置文件信息、位置信息、快捷设置
**布局:**
- ProfileCard当前配置文件信息名称、类型、流量使用、到期时间
- LocationCard当前连接位置信息
- SettingCard快捷设置开关
**数据依赖:**
- `current-profile: Profile`
- 部分 `app-settings``clash-settings`
### 2. Proxies 页面ui/pages/proxies.slint
**功能:** 代理节点管理,支持 Rule/Global/Direct 三种模式
**布局:**
- Tabs切换模式Rule/Global/Direct
- 每个模式下:
- 多个 Accordion代理组
- 每个 Accordion 内网格ode 卡片
**数据依赖:**
- `proxy-groups: [ProxyGroup]`
**交互:**
- 切换 Tab 时调用 `load-proxy-groups(mode)`
- 点击节点时调用 `select-proxy(group, node)`
- 测试延迟调用 `test-proxy-delay(node)`
### 3. Profiles 页面ui/pages/profiles.slint
**功能:** 配置文件管理,网格布局展示所有配置文件
**布局:**
- 头部:标题 + 添加按钮 + 刷新按钮
- 网格布局ProfileCard 列表(每行自适应,最小 18rem
**数据依赖:**
- `profiles: [Profile]`
**交互:**
- 点击配置文件调用 `select-profile(id)`
- 更新配置文件调用 `update-profile(id)`
- 删除配置文件调用 `delete-profile(id)`
- 添加配置文件调用 `add-profile(url)`
### 4. Connections 页面ui/pages/connections.slint
**功能:** 显示当前活动连接列表
**布局:**
- 简单列表,每个连接使用 Item 组件展示
**数据依赖:**
- `connections: [Connection]`
**交互:**
- 定时刷新(每秒调用 `load-connections()`
### 5. Logs 页面ui/pages/logs.slint
**功能:** 日志查看,支持 Mihomo 日志和 App 日志切换
**布局:**
- Tabs切换日志类型Mihomo/App
- 每个 Tab滚动列表展示日志条目
- 日志条目:时间 + 级别 + 消息(不同级别不同颜色)
**数据依赖:**
- `mihomo-logs: [LogEntry]`
- `app-logs: [LogEntry]`
**交互:**
- 切换 Tab 时调用 `load-logs(type)`
- 定时刷新(每秒)
### 6. Settings 页面ui/pages/settings.slint
**功能:** 应用设置和 Clash 设置
**布局:**
- 多个 Container每个包含一组设置项
- 设置项使用 Item 组件:图标 + 标题 + Switch/Button
**数据依赖:**
- `app-settings: [SettingItem]`
- `clash-settings: [SettingItem]`
**交互:**
- 切换开关调用 `tg(key, value)`
## 实现计划
### Phase 1: 基础设施 ✓
**优先级:** 最高
**预估代码量:** ~150 行
**完成日期:** 2026-01-30
- [x] `ui/types.slint` - 数据结构定义(~50 行)
- [x] `ui/layouts/container.slint` - 容器组件(~30 行)
- [x] `ui/layouts/page-layout.slint` - 页面布局(~70 行)
- [x] `ui/app.slint` - 主应用框架(侧边栏 + 路由)(~200 行)
- [x] `build.rs` - 修改编译入口为 app.slint~5 行)
- [x] `src/main.rs` - 基础 callback 框架(~100 行)
- [x] 恢复 `ui/theme/` 目录(从 git 历史)
### Phase 2: 简单页面 ✓
**优先级:**
**预估代码量:** ~180 行
**完成日期:** 2026-01-30
- [x] `ui/components/empty.slint` - 空状态组件(~40 行)
- [x] `ui/pages/connections.slint` - 连接列表(~60 行)
- [x] `ui/pages/logs.slint` - 日志查看(~210 行)
### Phase 3: 中等复杂页面 ✓
**优先级:**
**预估代码量:** ~350 行
**完成日期:** 2026-01-30
- [x] `ui/pages/settings.slint` - 设置页面(~280 行)
- [x] `ui/pages/profiles.slint` - 配置文件管理(~230 行)
### Phase 4: 复杂页面 ✓
**优先级:**
**预估代码量:** ~550 行
**完成日期:** 2026-01-30
- [x] `ui/pages/home.slint` - 首页(~380 行)
- [x] `ui/pages/proxies.slint` - 代理管理(~280 行)
### Phase 5: Rust 集成 ✓
**优先级:**
**预估代码量:** ~200 行
**完成日期:** 2026-01-30
- [x] `src/main.rs` - 实现所有 callback 的 mock 数据(~450 行)
- Mock 数据生成函数
- 用户交互处理
- 数据状态更新
## 项目完成总结
### 实现成果
**总代码量:** ~2100 行(超出预估的 ~1430 行)
**完成时间:** 2026-01-30单日完成
**实现的文件:**
1. **基础设施7 个文件)**
- `ui/types.slint` - 数据结构定义
- `ui/layouts/container.slint` - 容器组件
- `ui/layouts/page-layout.slint` - 页面布局
- `ui/app.slint` - 主应用框架
- `ui/theme/` - 主题系统(从 git 恢复)
- `build.rs` - 编译配置
- `src/main.rs` - Rust 集成
2. **UI 组件1 个新增)**
- `ui/components/empty.slint` - 空状态组件
3. **页面模块6 个页面)**
- `ui/pages/home.slint` - 首页
- `ui/pages/proxies.slint` - 代理管理
- `ui/pages/profiles.slint` - 配置文件管理
- `ui/pages/connections.slint` - 连接列表
- `ui/pages/logs.slint` - 日志查看
- `ui/pages/settings.slint` - 设置页面
### 功能特性
**完整的 6 页面应用**
- Home - 配置文件信息、位置、快捷设置
- Proxies - 代理节点管理Rule/Global/Direct 模式)
- Profiles - 配置文件管理(网格布局)
- Connections - 活动连接列表
- Logs - 日志查看Mihomo/App 切换)
- Settings - 应用和 Clash 设置
**主题系统**
- 亮色/暗色模式切换
- 响应式主题颜色
- 统一的设计系统
**交互功能**
- 侧边栏导航
- 页面路由
- 数据加载和更新
- Toast 通知
- 用户操作反馈
**Mock 数据**
- 3 个配置文件
- 2 个代理组(多个节点)
- 3 个活动连接
- 多条日志记录
- 完整的设置项
### 技术亮点
1. **模块化架构** - 清晰的目录结构和职责划分
2. **Callback 驱动** - 单向数据流,易于维护
3. **组件复用** - 最大化利用现有 shadcn-slint 组件
4. **类型安全** - Slint 类型系统保证数据一致性
5. **Mock 数据完整** - 所有页面都有真实的数据展示
### 运行方式
```bash
# 编译并运行
cargo run
# 发布版本
cargo run --release
```
### 下一步建议
1. **后端集成**
- 替换 mock 数据为真实的 Tauri 命令调用
- 实现配置文件的增删改查
- 实现代理节点的延迟测试
- 实现实时连接监控
2. **功能增强**
- 添加搜索和过滤功能
- 实现配置导入导出
- 添加更多设置选项
- 实现 TUN 模式配置对话框
3. **用户体验优化**
- 添加加载状态指示器
- 优化动画效果
- 添加键盘快捷键
- 实现拖拽排序
4. **性能优化**
- 虚拟滚动(大量数据时)
- 按需加载数据
- 优化渲染性能
## 总体进度
**总预估代码量:** ~1430 行
**完成情况:**
- ✓ Phase 1: 基础设施7/7
- ✓ Phase 2: 简单页面3/3
- ✓ Phase 3: 中等复杂页面2/2
- ✓ Phase 4: 复杂页面2/2
- ✓ Phase 5: Rust 集成1/1
**总进度:** 15/15 (100%) ✅
**项目状态:** 已完成
## 技术决策
### 图标方案
**选择:** Emoji
**理由:** 简单、无需额外资前项目已在使用
### 布局方案
**选择:** 固定桌面布局
**理由:** 桌面应用,不需要响应式
### 数据流方案
**选择:** Callback + Property
**理由:** 清晰的单向数据流,便于维护和测试
### 模块划分方案
**选择:** pages/ + layouts/ + components/
**理由:** 清晰的职责划分,易于维护和扩展
## 后续优化方向
1. **性能优化**
- 虚拟滚动(如果列表数据量大)
- 按需加载页面数据
2. **用户体验**
- 加载状态提示
- 错误处理和提示
- 操作确认对话框
3. **功能扩展**
- 搜索和过滤
- 排序功能
- 导入导出配置
## 参考资料
- 原 Tauri 实现:`web/src/` 目录
- Slint 文档https://slint.dev/
- 现有组件库:`ui/components/` 目录