5fea53aff11bd0d749a5b328d8d05f1fcc5279d2
- 新增 SQLite 服务器表结构及 Rust 后端 CRUD 命令 - 新增前端 API 接口、类型定义及国际化文案 - 新增服务器卡片组件及表单弹窗组件 - 实现服务器列表展示、新增、编辑、删除、置顶、启用等功能 - 处理启用服务器互斥逻辑及前端表单校验
Frpilot
一个基于 Tauri 2 + Vue 3 + TypeScript 的 frp 可视化客户端,帮助用户快速配置 frpc 版本、服务器与隧道。
Frpilot 目前处于早期开发阶段,已完成应用骨架(自定义标题栏、多语言、明暗主题、磨砂玻璃布局)。
✨ 功能特性
已实现
- i18n 国际化:内置简体中文 / English,语言选择持久化,Ant Design Vue 组件库语言包联动
- 自定义标题栏:按操作系统自动切换
- Windows:左侧
Frpilot标题,右侧「语言 / 明暗 / 设置 / 最小化 / 关闭」 - macOS:左侧红绿灯(关闭 / 最小化 / 最大化),右侧同上一组按钮
- Windows:左侧
- 明暗主题:基于
@vueuse/core的useDark,Tailwinddark:变体 + Ant Design Vue 暗色算法联动,选择持久化 - 悬浮磨砂玻璃布局:侧边栏(Aside)与内容区(Content)均为圆角 +
backdrop-filter毛玻璃面板 - 侧边栏菜单:仪表盘 / 服务器 / 隧道列表 / Frpc 下载
- 底部系统信息:CPU 占用、内存占用(百分比 + 进度条)、运行状态指示点
- 🟢 运行正常 · 🔴 运行异常 · 🟡 未启动
规划中
- frpc 版本管理与下载
- 服务器(frps)连接配置管理
- 隧道配置的增删改查与启停
- 配置文件的导入 / 导出与校验
🧱 技术栈
| 分类 | 选型 |
|---|---|
| 桌面框架 | Tauri 2(Rust 后端) |
| 前端框架 | Vue 3(<script setup>)+ TypeScript |
| 构建工具 | Vite 8 |
| UI 组件库 | Ant Design Vue 4 + @ant-design/icons-vue |
| 样式 | Tailwind CSS 4(原子化)+ SCSS |
| 状态管理 | Pinia |
| 路由 | Vue Router |
| 国际化 | Vue I18n 11 |
| 工具库 | @vueuse/core |
| 自动化 | unplugin-auto-import、unplugin-vue-components(Antd 按需自动导入) |
📦 环境要求
- Node.js ≥ 18(推荐 20 / 22 LTS)
- pnpm ≥ 9(项目使用 pnpm,含
pnpm-lock.yaml) - Rust 稳定版工具链(
rustup) - 系统依赖:请参考 Tauri 前置依赖(Windows 需 WebView2 与 MSVC 构建工具;macOS 需 Xcode Command Line Tools;Linux 需
webkit2gtk等)
🚀 快速开始
# 1. 安装依赖
pnpm install
# 2. 仅启动前端(浏览器调试,窗口控制类操作会安全空转)
pnpm dev
# 3. 启动完整桌面应用(推荐,含 Rust 后端)
pnpm tauri dev
常用脚本
| 命令 | 说明 |
|---|---|
pnpm dev |
启动 Vite 开发服务器(端口 1420) |
pnpm tauri dev |
启动 Tauri 桌面开发环境(自动拉起前端) |
pnpm build |
类型检查(vue-tsc --noEmit)+ 构建前端产物到 dist/ |
pnpm preview |
预览前端构建产物 |
pnpm tauri build |
打包生成各平台安装包 |
⚠️
pnpm dev的端口固定为1420且strictPort: true,占用时会直接报错退出。
📁 项目结构
Frpilot/
├── src/
│ ├── api/ # 接口封装(预留)
│ ├── assets/
│ │ └── main.css # Tailwind 入口 + 全局样式(.glass-panel / dark 变体)
│ ├── components/ # 通用组件
│ │ ├── TitleBarActions.vue # 标题栏右侧按钮组(语言/主题/设置/最小化/关闭)
│ │ ├── WindowsTitleBar.vue # Windows 自定义标题栏
│ │ └── MacTitleBar.vue # macOS 自定义标题栏(红绿灯)
│ ├── composables/
│ │ ├── usePlatform.ts # 操作系统类型判断
│ │ └── useSystemStats.ts # CPU / 内存占用采集
│ ├── i18n/
│ │ ├── index.ts # createI18n 初始化
│ │ └── locales/
│ │ ├── zh-CN.json # 中文语言包
│ │ └── en-US.json # 英文语言包
│ ├── layout/
│ │ ├── Layout.vue # 整体布局(背景 + Header + Aside + Content)
│ │ ├── aside/Aside.vue # 侧边栏(菜单 + 系统信息)
│ │ └── header/Header.vue # 顶部栏(按系统加载 TitleBar)
│ ├── router/router.ts # 路由表
│ ├── stores/app.ts # 全局状态:语言 / 主题 / 运行状态
│ ├── types/ # 自动生成的类型声明
│ ├── utils/window.ts # Tauri 窗口控制封装
│ ├── views/ # 页面(仪表盘 / 服务器 / 隧道 / 下载)
│ ├── App.vue # ConfigProvider(语言 + 主题)
│ └── main.ts # 应用入口
├── src-tauri/ # Rust 后端
│ ├── src/lib.rs # 命令注册入口
│ ├── capabilities/default.json# 权限声明(窗口控制等)
│ └── tauri.conf.json # Tauri 配置(无边框窗口 1100×720)
├── docs/
├── index.html
├── vite.config.ts # 别名 / 自动导入 / Tailwind 插件
└── package.json
🛠️ 开发指南
别名与自动导入
@指向src/- 自动导入已开启,以下内容无需手动 import:
- Vue / Vue Router / Pinia /
@vueuse/core的 API(如ref、computed、watch、useDark、useStorage) - Ant Design Vue 组件(模板中直接写
<a-button>、<a-menu>等)与图标 - 类型声明自动生成在
src/types/auto-imports.d.ts、src/types/components.d.ts
- Vue / Vue Router / Pinia /
vue-i18n的useI18n未加入自动导入,需手动import { useI18n } from 'vue-i18n'。
新增 / 修改文案(i18n)
- 到
src/i18n/locales/zh-CN.json与en-US.json中按相同层级添加 key(两份文件需保持一致)。 - 组件内使用:
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
<template>
<span>{{ t('menu.dashboard') }}</span>
</template>
新增语言:在 src/i18n/locales/ 添加 JSON,并在 src/i18n/index.ts 的 messages 与 languageOptions 中注册。
新增侧边栏菜单项与页面
- 在
src/views/新建页面组件。 - 在
src/router/router.ts的Layout子路由中注册(路径需以/开头,与菜单key一致)。 - 在
src/layout/aside/Aside.vue的menuItems中追加一项(key= 路由路径)。 - 在语言包中补充对应
menu.*文案。
明暗主题
- 主题状态在
src/stores/app.ts(isDark/toggleDark),由useDark在<html>上切换.dark类名并持久化。 - Tailwind 使用 class 策略:在
src/assets/main.css中已声明@custom-variant dark。 - Ant Design Vue 主题在
src/App.vue中通过a-config-provider的theme.algorithm联动。
玻璃拟态样式
src/assets/main.css 中的 .glass-panel 为通用毛玻璃面板,直接给元素加 class="glass-panel" 即可(已含暗色适配)。
接入真实的 CPU / 内存占用
src/composables/useSystemStats.ts 会优先调用 Tauri 命令 get_system_info,在命令不存在时回退到模拟数据。接入真实数据只需在 Rust 端实现该命令:
// src-tauri/src/lib.rs
#[tauri::command]
fn get_system_info() -> serde_json::Value {
// 返回 { "cpu": f64, "memory": f64 },单位为百分比
serde_json::json!({ "cpu": 12.0, "memory": 45.0 })
}
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![get_system_info])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
前端会自动切换为真实数据(isMock 会变为 false)。
运行状态指示点
运行状态由 src/stores/app.ts 的 runStatus 控制,取值:
type RunStatus = 'running' | 'error' | 'stopped' // 🟢 | 🔴 | 🟡
后续接入 frpc 进程状态时,更新该字段即可。
窗口控制与权限
- 前端封装:
src/utils/window.ts(minimizeWindow/toggleMaximizeWindow/closeWindow/startDragging),在非 Tauri 环境(浏览器)下自动空转。 - 自定义标题栏依赖无边框窗口(
src-tauri/tauri.conf.json中decorations: false),拖拽区域通过data-tauri-drag-region实现。 - 相关权限在
src-tauri/capabilities/default.json中声明(core:window:allow-minimize、allow-close、allow-toggle-maximize、allow-start-dragging等)。新增窗口 API 调用时需同步补充对应权限,否则会报not allowed错误。
📚 参考链接
📄 License
License 待定(待补充)。
Description
frp 可视化桌面客户端 —— 告别手写 frpc.toml。下载 frpc、配置服务器、编排隧道、一键启动并实时查看日志,全部在同一个窗口里完成。
8.2 MiB
Languages
Vue
37.6%
Rust
37.2%
TypeScript
20.6%
CSS
3.5%
HTML
1.1%