refactor: 项目正式更名为 FrpcPilot,同步更新所有相关标识

本次修改将项目名称从 Frpilot 全面更改为 FrpcPilot,涉及:
- 应用名称、窗口标题、系统托盘提示、GitHub 仓库地址
- 包标识:npm 包名、Rust crate 名称、Tauri identifier
- 本地存储键前缀、数据库文件名、系统托盘 ID
- 文档、国际化文案、配置文件、代码注释等所有关联内容
This commit is contained in:
Yuhang Wu
2026-10-16 15:36:02 +08:00
parent 57b4d7be5a
commit 140c517191
33 changed files with 268 additions and 188 deletions
+1 -1
View File
@@ -132,7 +132,7 @@ jobs:
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with: with:
tagName: v__VERSION__ # 自动替换为 src-tauri/tauri.conf.json(即 package.json)里的版本号 tagName: v__VERSION__ # 自动替换为 src-tauri/tauri.conf.json(即 package.json)里的版本号
releaseName: "Frpilot v__VERSION__" releaseName: "FrpcPilot v__VERSION__"
releaseBody: ${{ steps.changelog.outputs.body }} releaseBody: ${{ steps.changelog.outputs.body }}
releaseDraft: true # 先创建草稿,手动确认后再发布 releaseDraft: true # 先创建草稿,手动确认后再发布
prerelease: false prerelease: false
+187 -135
View File
@@ -1,63 +1,40 @@
# Frpilot <div align="center">
> 一个基于 **Tauri 2 + Vue 3 + TypeScript** 的 [frp](https://github.com/fatedier/frp) 可视化客户端,帮你用图形界面管理 frpc 版本、服务器与隧道,从此告别手写 `frpc.toml`。 # FrpcPilot
Frpilot 已从「应用骨架」成长为可用的一体化客户端:下载 frpc、配置服务器、编排隧道、一键启动并实时查看日志,全部在同一个窗口里完成,并内置应用内自动更新。 **frp 可视化桌面客户端 —— 告别手写 `frpc.toml`**
下载 frpc、配置服务器、编排隧道、一键启动并实时查看日志,全部在同一个窗口里完成。
[![Release](https://img.shields.io/github/v/release/SparksFly91/FrpcPilot?style=flat-square&color=6366f1)](https://github.com/SparksFly91/FrpcPilot/releases)
[![License](https://img.shields.io/github/license/SparksFly91/FrpcPilot?style=flat-square&color=6366f1)](./LICENSE)
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-6366f1?style=flat-square)](#-下载安装)
[![Tauri](https://img.shields.io/badge/Tauri-2-24C8DB?style=flat-square&logo=tauri&logoColor=white)](https://v2.tauri.app/)
[![Vue](https://img.shields.io/badge/Vue-3-42B883?style=flat-square&logo=vuedotjs&logoColor=white)](https://vuejs.org/)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-6366f1?style=flat-square)](https://github.com/SparksFly91/FrpcPilot/pulls)
</div>
--- ---
## ✨ 已实现功能 ## 🏷️ 关于「FrpcPilot」这个名字
### Frpc 版本管理 > **FrpcPilot = Frpc + Pilot**(领航员)
- 在线拉取 Frp 官方版本列表,支持「所有架构 frpc / frps」开关,按平台与架构筛选 - **Frpc** —— 取自 [frp](https://github.com/fatedier/frp) 的客户端组件 `frpc`,也是本项目服务的核心对象;
- 一键下载并自动解压,实时显示下载 / 解压进度与状态 - **Pilot** —— 飞行员 / 领航员。frp 本身足够强大,却总离不开手写 `frpc.toml` 与敲命令启动;FrpcPilot 想做你的「frpc 领航员」,把这些繁琐的配置与命令行统统收进图形界面,带你稳稳起飞。
- 导入本地已有的 `frpc` / `frps`
- 删除已下载版本、复制下载直链
### 服务器管理 一句话:**让 frpc 起飞,你只管掌舵。** ✈️
- frps 服务器的新增 / 编辑 / 删除 ---
- 服务器地址、端口、鉴权 Token、传输协议、TLS 开关、备注
- 置顶与排序;启用开关(**同一时间仅允许启用一台**服务器)
### 隧道管理 ## 📖 项目简介
- 覆盖 **TCP / UDP / HTTP / HTTPS / STCP / XTCP / SUDP / TCPMUX** 等代理类型 **FrpcPilot** 是一个基于 **Tauri 2 + Vue 3 + TypeScript** 的 [frp](https://github.com/fatedier/frp) 图形化客户端。它把原本需要手工编辑 `frpc.toml` 的繁琐流程,变成「点几下就能跑起来」:在线下载 frpc、管理 frps 服务器与隧道、一键启动内网穿透,并实时回显运行日志。
- 本地 IP / 端口、远程端口、自定义域名、子域名、URL 前缀
- 高级配置:密钥、加密、压缩、带宽限制、Proxy Protocol、健康检查、负载均衡
- 启用 / 置顶 / 排序
### 一键启动与实时日志 得益于 Tauri 的轻量内核,应用体积小、内存占用低;后端使用 Rust + SQLite 本地持久化,数据完全保存在你自己的电脑上,不经过任何第三方服务。
- 仪表盘选择 frpc 版本后「一键启动 / 停止」 > 当前版本 **v1.2.1**,已支持 Windows / macOS(Apple Silicon)/ Linux 三平台,并内置应用内自动更新。
- 自动依据所选版本、已启用的服务器与隧道生成 `frpc.toml` 并拉起独立进程
- 通过 `frpc-log` / `frpc-exit` 事件实时回显运行日志与进程退出信息
### 仪表盘
- 系统信息:主机名 / 系统 / 架构 / IP 地址
- 服务器与隧道数量统计
- 侧边栏常驻 CPU 占用、内存占用与运行状态指示点(🟢 运行正常 · 🔴 运行异常 · 🟡 未启动)
### 应用内自动更新
- 启动时静默检查,支持手动检查更新
- 更新弹窗以 **Markdown** 渲染更新说明,展示下载进度
- 支持「忽略该版本」、一键更新,安装完成后自动重启
### 关于页面
- 项目介绍、技术栈标签、使用流程指引
- 开源地址一键跳转、当前版本信息与「检查更新」入口
### 界面与体验
- **自定义标题栏**:Windows / macOS 双套方案,窗口可拖拽移动;顶部栏集成语言 / 主题 / 检查更新 / GitHub / 设置与窗口控制按钮
- **macOS 特化**:还原原生红绿灯,隐藏冗余的最小化 / 关闭按钮,禁用 macOS 下不需要的最大化
- **明暗主题**:跟随切换,Tailwind 暗色变体与 Ant Design Vue 暗色算法同步,选择持久化
- **悬浮磨砂玻璃**:侧边栏、内容区与卡片统一为圆角 + `backdrop-filter` 半透明面板
- **国际化**:内置简体中文 / English,语言选择持久化,Ant Design Vue 组件语言包联动
--- ---
@@ -71,29 +48,105 @@ Frpilot 已从「应用骨架」成长为可用的一体化客户端:下载 fr
| --- | --- | | --- | --- |
| ![隧道列表](docs/snipastes/隧道列表.webp) | ![Frpc 下载](docs/snipastes/frpc下载.webp) | | ![隧道列表](docs/snipastes/隧道列表.webp) | ![Frpc 下载](docs/snipastes/frpc下载.webp) |
| 设置 · 外观 | 设置 · 关于 | | 设置 · 常规 | 设置 · 外观 |
| --- | --- | | --- | --- |
| ![外观设置](docs/snipastes/设置.webp) | ![关于](docs/snipastes/关于.webp) | | ![常规设置](docs/snipastes/设置·常规.webp) | ![外观设置](docs/snipastes/设置.webp) |
<p align="center">
<img src="docs/snipastes/关于.webp" alt="关于" width="49%" />
</p>
---
## ✨ 功能特性
### 📊 仪表盘
- 一屏总览:服务器数量、隧道数量,以及主机名 / 系统 / 架构 / IP 地址等系统信息
- 选择 frpc 版本后「**一键启动 / 停止**」,运行状态实时联动
- **实时日志**:通过事件流回显 frpc 运行日志(保留最近 500 行,支持一键清空)
- 侧边栏常驻 **CPU / 内存占用** 与运行状态指示(🟢 运行正常 · 🔴 运行异常 · 🟡 未启动)
### 🖥️ 服务器管理
- frps 服务器的新增 / 编辑 / 删除
- 支持服务器地址、端口、鉴权 Token、传输协议、TLS 开关与备注
- 置顶与排序;启用开关(**同一时间仅允许启用一台**服务器)
### 🔀 隧道管理
- 覆盖 **TCP / UDP / HTTP / HTTPS / STCP / XTCP / SUDP / TCPMUX** 等代理类型
- 本地 IP / 端口、远程端口、自定义域名、子域名、URL 前缀
- 高级配置:密钥、加密、压缩、带宽限制、Proxy Protocol、健康检查、负载均衡
- 统一管理启用 / 置顶 / 排序
### 📦 Frpc 下载管理
- 在线拉取 frp 官方版本列表,按平台与架构筛选,支持「所有架构 frpc / frps」开关
- 一键下载并自动解压,实时显示下载 / 解压进度与状态(支持镜像加速)
- 导入本地已有的 `frpc` / `frps`,删除已下载版本、复制下载直链
- **页面级缓存**:应用运行期间仅首次进入时拉取版本列表,避免重复请求触发限流,需要更新时手动点击「刷新」
### 🚀 一键启动与进程管理
- 依据所选版本、已启用的服务器与隧道,自动生成 `frpc.toml` 并拉起独立进程
- 通过 `frpc-log` / `frpc-exit` 事件实时推送日志与进程退出信息
- 应用退出时自动结束 frpc 子进程,避免残留后台进程
### 🗂️ 系统托盘
- 常驻托盘菜单:**显示窗口 / 启动穿透 / 停止穿透 / 退出**
- 左键单击直达主窗口,右键展开菜单;菜单随运行状态与界面语言自动联动
- 「退出」会先停止正在运行的穿透,再退出整个应用
### 🔔 关闭行为
- 关闭窗口时可选「**最小化到系统托盘**」或「**直接退出**」
- 支持「每次询问」与「保持以上选择」两种策略,也可在「设置 - 常规」中随时修改
### 🎨 界面与体验
- **自定义标题栏**:Windows / macOS 双套方案,窗口可拖拽移动;macOS 还原原生红绿灯
- **明暗主题**:一键切换,Tailwind 暗色变体与 Ant Design Vue 暗色算法同步
- **磨砂玻璃视觉**:侧边栏、内容区与卡片统一为圆角 + `backdrop-filter` 半透明面板,透明度可调
- **窗口背景**:内置 9 张背景图,可自由挑选,保持原始比例自适应
- **国际化**:内置简体中文 / English,语言选择持久化并与组件库语言包联动
### 🔄 应用内自动更新
- 启动时静默检查更新,支持手动检查
- 更新弹窗以 **Markdown** 渲染更新说明并展示下载进度
- 支持「忽略该版本」、一键更新,安装完成后自动重启
### ⚙️ 设置中心
- **常规**:关闭行为、应用语言
- **外观**:主题模式、背景图片、磨砂玻璃透明度(卡片 / 弹窗,实时预览)
- **关于**:项目介绍、技术栈、使用流程、开源地址与版本信息
---
## 📥 下载安装
前往 [**Releases**](https://github.com/SparksFly91/FrpcPilot/releases/latest) 下载对应平台的安装包:
| 平台 | 安装包 |
| --- | --- |
| Windows | `.exe`(NSIS 安装程序) |
| macOS(Apple Silicon) | `.dmg` / `.app` |
| Linux | `.deb` / `.AppImage` |
装好后打开应用即可,后续版本会在应用内自动检查并更新。
--- ---
## 🧱 技术栈 ## 🧱 技术栈
| 分类 | 选型 | | 分类 | 选型 |
| ---------- | --------------------------------------------------------------------- | | --- | --- |
| 桌面框架 | [Tauri 2](https://v2.tauri.app/)(Rust 后端) | | 桌面框架 | [Tauri 2](https://v2.tauri.app/)(Rust 后端) |
| 前端框架 | Vue 3(`<script setup>`)+ TypeScript | | 前端框架 | Vue 3(`<script setup>`)+ TypeScript |
| 构建工具 | Vite 8 | | 构建工具 | Vite 8 |
| UI 组件库 | Ant Design Vue 4 + `@ant-design/icons-vue` | | UI 组件库 | Ant Design Vue 4 + `@ant-design/icons-vue` |
| 样式 | Tailwind CSS 4(原子化)+ SCSS | | 样式 | Tailwind CSS 4(原子化)+ SCSS |
| 状态管理 | Pinia | | 状态管理 | Pinia |
| 路由 | Vue Router | | 路由 | Vue Router |
| 国际化 | Vue I18n 11 | | 国际化 | Vue I18n 11 |
| Markdown | `markdown-it`(更新日志渲染) | | Markdown | `markdown-it`(更新日志渲染) |
| 工具库 | `@vueuse/core` | | 工具库 | `@vueuse/core` · `dayjs` |
| 后端 | Rust:`sqlx` + SQLite、`reqwest`(下载)、`sysinfo`(系统采集) | | 后端 | Rust:`sqlx` + SQLite、`reqwest`(下载)、`sysinfo`(系统采集)、`tokio` |
| 插件 | `updater` / `process` / `dialog` / `opener` / `store` / `prevent-default` | | Tauri 插件 | `updater` / `process` / `dialog` / `opener` / `store` / `prevent-default` |
| 自动化 | `unplugin-auto-import`、`unplugin-vue-components`(Antd 按需自动导入) | | 工程化 | `unplugin-auto-import`、`unplugin-vue-components`(按需自动导入)、`tauri-helper`(命令注册) |
--- ---
@@ -102,68 +155,77 @@ Frpilot 已从「应用骨架」成长为可用的一体化客户端:下载 fr
- **Node.js** ≥ 20(推荐 20 / 22 LTS) - **Node.js** ≥ 20(推荐 20 / 22 LTS)
- **pnpm** ≥ 9(项目使用 pnpm,含 `pnpm-lock.yaml`) - **pnpm** ≥ 9(项目使用 pnpm,含 `pnpm-lock.yaml`)
- **Rust** 稳定版工具链(`rustup`,建议 ≥ 1.90) - **Rust** 稳定版工具链(`rustup`,建议 ≥ 1.90)
- **系统依赖**:请参考 [Tauri 前置依赖](https://v2.tauri.app/start/prerequisites/)(Windows 需 WebView2 与 MSVC 构建工具;macOS 需 Xcode Command Line Tools;Linux 需 `webkit2gtk` 等) - **系统依赖**:请参考 [Tauri 前置依赖](https://v2.tauri.app/start/prerequisites/)
- Windows:WebView2 + MSVC 构建工具
- macOS:Xcode Command Line Tools
- Linux:`webkit2gtk`、`libayatana-appindicator`、`librsvg` 等
--- ---
## 🚀 快速开始 ## 🚀 快速开始
```bash ```bash
# 1. 安装依赖 # 1. 克隆仓库
pnpm install git clone https://github.com/SparksFly91/FrpcPilot.git
cd FrpcPilot
# 2. 仅启动前端(浏览器调试,窗口 / 命令类操作会安全空转) # 2. 安装依赖
pnpm dev pnpm install
# 3. 启动完整桌面应用(推荐,含 Rust 后端) # 3. 启动完整桌面应用(推荐,含 Rust 后端)
pnpm tauri dev pnpm tauri dev
# 或者:仅启动前端(浏览器调试,窗口 / 命令类操作会安全空转)
pnpm dev
``` ```
### 常用脚本 ### 常用脚本
| 命令 | 说明 | | 命令 | 说明 |
| ------------------ | ------------------------------------------------------ | | --- | --- |
| `pnpm dev` | 启动 Vite 开发服务器(端口 `1420`) | | `pnpm dev` | 启动 Vite 开发服务器(端口 `1420`) |
| `pnpm tauri dev` | 启动 Tauri 桌面开发环境(自动拉起前端) | | `pnpm tauri dev` | 启动 Tauri 桌面开发环境(自动拉起前端) |
| `pnpm build` | 类型检查(`vue-tsc --noEmit`)+ 构建前端产物到 `dist/` | | `pnpm build` | 类型检查(`vue-tsc --noEmit`)+ 构建前端产物到 `dist/` |
| `pnpm preview` | 预览前端构建产物 | | `pnpm preview` | 预览前端构建产物 |
| `pnpm tauri build` | 打包生成各平台安装包 | | `pnpm tauri build` | 打包生成各平台安装包 |
> ⚠️ `pnpm dev` 的端口固定为 `1420` 且 `strictPort: true`,占用时会直接报错退出。 > ⚠️ `pnpm dev` 端口固定为 `1420` 且 `strictPort: true`,被占用时会直接报错退出。
--- ---
## 📁 项目结构 ## 📁 项目结构
``` ```
Frpilot/ FrpcPilot/
├── src/ # 前端(Vue 3 + TypeScript) ├── src/ # 前端(Vue 3 + TypeScript)
│ ├── api/ # Tauri 命令封装(frp / server / tunnel / system / updater) │ ├── api/ # Tauri 命令封装(frp / server / tunnel / system / updater)
│ ├── assets/main.css # Tailwind 入口 + 全局样式(磨砂玻璃 / Markdown / 弹窗) │ ├── assets/ # Tailwind 入口 + 全局样式(磨砂玻璃 / Markdown / 弹窗)与背景图
│ ├── components/ # 通用组件 │ ├── components/ # 通用组件
│ │ ├── frp/FrpCard.vue │ │ ├── frp / server / tunnel # 业务卡片与表单弹窗
│ │ ├── server/ServerCard.vue · ServerFormModal.vue │ │ ├── CardRadioGroup.vue # 卡片式单选组(关闭弹窗 / 设置页复用)
│ │ ├── tunnel/TunnelCard.vue · TunnelFormModal.vue │ │ ├── CloseConfirmModal.vue # 关闭确认弹窗
│ │ ├── WindowsTitleBar.vue · MacTitleBar.vue · TitleBarActions.vue
│ │ ├── UpdateModal.vue # 更新弹窗(Markdown 更新日志 + 进度) │ │ ├── UpdateModal.vue # 更新弹窗(Markdown 更新日志 + 进度)
│ │ └── MarkdownBlock.vue # Markdown 渲染 │ │ ├── MarkdownBlock.vue # Markdown 渲染
│ ├── composables/ # usePlatform · useSystemStats │ │ └── WindowsTitleBar / MacTitleBar / TitleBarActions.vue
│ ├── composables/ # usePlatform · useSystemStats · useTray
│ ├── config/backgrounds.ts # 内置窗口背景图 │ ├── config/backgrounds.ts # 内置窗口背景图
│ ├── i18n/ # 国际化(zh-CN / en-US) │ ├── i18n/ # 国际化(zh-CN / en-US)
│ ├── layout/ # 主布局 + 标题栏 + 侧边栏 │ ├── layout/ # 主布局 + 标题栏 + 侧边栏
│ ├── router/router.ts # 路由表 │ ├── router/router.ts # 路由表(含 meta.isCache 页面缓存开关)
│ ├── stores/ # app · frpc · update(Pinia) │ ├── stores/ # app · frpc · update · window(Pinia)
│ ├── types/ # 自动生成的类型声明与领域类型 │ ├── types/ # 自动生成的类型声明与领域类型
│ ├── utils/ # window(窗口控制)· markdown(渲染) │ ├── utils/ # window(窗口控制)· markdown(渲染)
│ └── views/ # 页面(仪表盘 / 服务器 / 隧道 / 下载 / 设置) │ └── views/ # 页面:仪表盘 / 服务器 / 隧道 / 下载 / 设置
│ └── setting/ # 常规 · 外观 · 关于
├── src-tauri/ # 后端(Rust) ├── src-tauri/ # 后端(Rust)
│ ├── src/ │ ├── src/
│ │ ├── commands/ # Tauri 命令(frp / runner / server / system / tunnel) │ │ ├── commands/ # Tauri 命令(frp / runner / server / system / tunnel)
│ │ ├── services/ # 数据库 / frpc.toml 生成 / 进程管理 / 系统采集 │ │ ├── services/ # 数据库(SQLite) / frpc.toml 生成 / 进程管理 / 系统采集
│ │ ├── models.rs # ApiResponse / PageResult 等通用模型 │ │ ├── models.rs # 通用数据模型
│ │ └── lib.rs # 应用入口与命令注册 │ │ └── lib.rs # 应用入口与命令注册
│ ├── capabilities/default.json # 权限声明(窗口控制 / updater / process 等) │ ├── capabilities/default.json # 权限声明(窗口 / updater / process 等)
│ └── tauri.conf.json # Tauri 配置(无边框窗口 1100×720) │ ├── tauri.conf.json # Tauri 主配置(无边框窗口 1100×720)
│ └── tauri.macos.conf.json # macOS 平台覆盖配置(透明圆角窗口)
├── docs/ ├── docs/
│ ├── CHANGELOG.md # 版本更新日志(发布流程会读取) │ ├── CHANGELOG.md # 版本更新日志(发布流程会读取)
│ └── snipastes/ # 界面截图 │ └── snipastes/ # 界面截图
@@ -184,26 +246,13 @@ Frpilot/
- Vue / Vue Router / Pinia / `@vueuse/core` 的 API(如 `ref`、`computed`、`watch`、`useDark`、`useStorage`) - Vue / Vue Router / Pinia / `@vueuse/core` 的 API(如 `ref`、`computed`、`watch`、`useDark`、`useStorage`)
- Ant Design Vue 组件(模板中直接写 `<a-button>`、`<a-menu>` 等)与图标 - Ant Design Vue 组件(模板中直接写 `<a-button>`、`<a-menu>` 等)与图标
- 类型声明自动生成在 `src/types/auto-imports.d.ts`、`src/types/components.d.ts` - 类型声明自动生成在 `src/types/auto-imports.d.ts`、`src/types/components.d.ts`
- `vue-i18n` 的 `useI18n` **未**加入自动导入,需手动 `import { useI18n } from "vue-i18n"`。
> `vue-i18n` 的 `useI18n` 未加入自动导入,需手动 `import { useI18n } from 'vue-i18n'`。
### 新增 / 修改文案(i18n) ### 新增 / 修改文案(i18n)
1. 到 `src/i18n/locales/zh-CN.json` 与 `en-US.json` 中按相同层级添加 key(两份文件需保持一致)。 1. 在 `src/i18n/locales/zh-CN.json` 与 `en-US.json` 中按相同层级添加 key(两份文件需保持一致)。
2. 组件内使用: 2. 组件内使用 `const { t } = useI18n()`,模板中写 `{{ t("menu.dashboard") }}`。
3. 新增语言:在 `src/i18n/locales/` 添加 JSON,并在 `src/i18n/index.ts` 的 `messages` 与 `languageOptions` 中注册。
```vue
<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` 中注册。
### 新增侧边栏菜单项与页面 ### 新增侧边栏菜单项与页面
@@ -212,34 +261,24 @@ const { t } = useI18n()
3. 在 `src/layout/aside/Aside.vue` 的 `menuItems` 中追加一项(`key` = 路由路径)。 3. 在 `src/layout/aside/Aside.vue` 的 `menuItems` 中追加一项(`key` = 路由路径)。
4. 在语言包中补充对应 `menu.*` 文案。 4. 在语言包中补充对应 `menu.*` 文案。
### 明暗主题 > 若希望页面在切换路由后保留状态(如避免重复请求),在该路由的 `meta` 中设置 `isCache: true`,并在页面组件上用 `defineOptions({ name })` 声明与路由 `name` 一致的组件名。
- 主题状态在 `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/stores/app.ts`(`isDark` / `toggleDark`),由 `useDark` 在 `<html>` 上切换 `.dark` 类名并持久化;Ant Design Vue 主题通过 `a-config-provider` 的 `theme.algorithm` 联动。
- `src/assets/main.css` 中的 `.glass-panel`(面板)与 `.glass-card`(卡片)为通用毛玻璃样式,直接加类名即可(已含暗色适配与透明度变量)。
`src/assets/main.css` 中的 `.glass-panel`(面板)与 `.glass-card`(卡片)为通用毛玻璃样式,直接加类名即可(已含暗色适配)。
### Markdown 渲染
更新日志、说明类富文本统一使用 `src/components/MarkdownBlock.vue`(内部调用 `src/utils/markdown.ts` 的 `renderMarkdown`)。渲染关闭了原始 HTML,并把链接点击接管到系统浏览器打开。
### 窗口控制与权限 ### 窗口控制与权限
- 前端封装:`src/utils/window.ts`(`minimizeWindow` / `toggleMaximizeWindow` / `closeWindow` / `startDragging` 等),在非 Tauri 环境(浏览器)下自动空转。 - 前端封装:`src/utils/window.ts`(`minimizeWindow` / `toggleMaximizeWindow` / `closeWindow` / `startDragging` 等),在非 Tauri 环境(浏览器)下自动空转。
- 自定义标题栏依赖无边框窗口(`src-tauri/tauri.conf.json` 中 `decorations: false`),拖拽区域通过 `data-tauri-drag-region` 实现。 - 自定义标题栏依赖无边框窗口(`decorations: false`),拖拽通过 `data-tauri-drag-region` 实现。
- **窗口圆角(8px)**:Windows 11 由系统 DWM 自动裁切;macOS 的无边框窗口系统不会裁圆角,因此: - **窗口圆角(8px)**:Windows 11 由系统 DWM 自动裁切;macOS 无边框窗口需在 `tauri.macos.conf.json` 中设 `transparent: true`,并在样式上由 `#app` 裁出圆角。
- `src-tauri/tauri.macos.conf.json` 中把窗口设为 `transparent: true`(**Tauri 2.12.1+ 无需再开启 `macOSPrivateApi`**); - ⚠️ 平台配置按 **JSON Merge Patch** 合并且**数组整体替换**,`tauri.macos.conf.json` 需完整重复 `app.windows` 字段;修改基础窗口参数时记得同步。
- `src/assets/main.css` 中在 `html.is-macos` 下把背景从 `<html>` 移到 `#app`,由 `#app` 裁出 8px 圆角,并让 `html`/`body` 透明以透出桌面; - 相关权限在 `src-tauri/capabilities/default.json` 中声明。**新增窗口 / 插件 API 调用时需同步补充对应权限**,否则会报 `not allowed`。
- `src/main.ts` 在挂载前根据 UA 给 `<html>` 打上 `is-macos` 标记。
- ⚠️ 平台配置文件按 **JSON Merge Patch** 合并,且**数组整体替换**,因此 `tauri.macos.conf.json` 里必须完整重复 `app.windows` 的字段;**修改基础配置的窗口参数时,记得同步这份文件**。
- 相关权限在 `src-tauri/capabilities/default.json` 中声明(`core:window:*`、`updater:default`、`process:default` 等)。**新增窗口 / 插件 API 调用时需同步补充对应权限**,否则会报 `not allowed` 错误。
### 发布与自动更新 ### 发布与自动更新
- 版本号取自 `package.json` 的 `version`(`src-tauri/tauri.conf.json` 引用之),`src-tauri/Cargo.toml` 保持一致。 - 版本号取自 `package.json` 的 `version`(`src-tauri/tauri.conf.json` 引用之)。
- 推送 `v*` tag 会触发 `.github/workflows/release.yml`:构建 **Windows x64 / macOS Apple Silicon / Linux x64** 产物,签名生成更新产物与 `latest.json`,并自动从 `docs/CHANGELOG.md` 提取对应版本说明作为 Release 正文。 - 推送 `v*` tag 会触发 `.github/workflows/release.yml`:构建 **Windows x64 / macOS Apple Silicon / Linux x64** 产物,签名生成更新产物与 `latest.json`,并自动从 `docs/CHANGELOG.md` 提取对应版本说明作为 Release 正文。
- 发布前请在 `docs/CHANGELOG.md` 中补上 `## v<版本号>` 段落。 - 发布前请在 `docs/CHANGELOG.md` 中补上 `## v<版本号>` 段落。
@@ -247,12 +286,25 @@ const { t } = useI18n()
## 🗺️ 路线图 ## 🗺️ 路线图
- frpc 配置文件的导入 / 导出与校验 - [x] 系统托盘与关闭到托盘
- frps 服务端信息的集中管理与状态检测 - [ ] 开机自启
- 日志持久化与导出 - [ ] 主题跟随系统
- 系统托盘 / 开机自启 / 关闭到托盘 - [ ] frpc 配置文件的导入 / 导出与校验
- 主题跟随系统 - [ ] frps 服务端信息的集中管理与状态检测
- 更多语言与自定义背景 - [ ] 日志持久化与导出
- [ ] 更多语言与更多内置背景
---
## 🤝 参与贡献
欢迎提交 Issue 与 Pull Request!
- 提交前请确保 `pnpm build`(类型检查 + 前端构建)通过。
- 遵循现有代码风格与目录结构;涉及新功能时请同步补充 i18n 中英文文案。
- Bug 反馈建议附上操作系统、应用版本与复现步骤。
如果 FrpcPilot 对你有帮助,欢迎点一个 ⭐ **Star** 支持一下~
--- ---
@@ -270,4 +322,4 @@ const { t } = useI18n()
## 📄 License ## 📄 License
本项目基于 [Apache License 2.0](LICENSE) 开源。 本项目基于 [Apache License 2.0](./LICENSE) 开源。
+19 -1
View File
@@ -1,9 +1,27 @@
# 更新日志 # 更新日志
本文件记录 Frpilot 各版本的更新内容。 本文件记录 FrpcPilot 各版本的更新内容。
--- ---
## v1.2.1(2026-10-16)
### 🔄 项目更名
- 项目正式更名为 **FrpcPilot**:应用名称、安装包与可执行文件名、窗口标题、系统托盘提示、GitHub 仓库地址等全部由 `Frpilot` 更新为 `FrpcPilot`。
- 构建与包标识同步调整:npm 包名改为 `frpcpilot`,Rust crate 改为 `frpcpilot` / `frpcpilot_lib`,Tauri `identifier` 改为 `FrpcPilot`。
- 本地标识同步调整:本地存储键前缀改为 `frpcpilot:`,系统托盘 id 改为 `frpcpilot-tray`,数据库文件改为 `frpcpilot.db`。
- ⚠️ 由于 Tauri `identifier` 变更,应用数据目录随之变化,升级到本版本后需要**重新配置服务器与隧道**等本地数据。
### 📝 文档
- 重写 README,面向 GitHub 重新组织:新增项目徽章、项目简介、**「FrpcPilot」名称由来的介绍**、界面预览、下载安装、功能特性、开发指南与参与贡献等章节。
- 更新界面截图,并新增「设置 · 常规」页面预览。
### 🧱 工程
- 应用版本升级至 **v1.2.1**。
## v1.2.0(2026-10-16) ## v1.2.0(2026-10-16)
### ✨ 新增功能 ### ✨ 新增功能
@@ -1,4 +1,4 @@
# Frpilot开发提示词 # FrpcPilot开发提示词
## 背景 ## 背景
@@ -16,7 +16,7 @@
- 在locales目录中写多语言翻译json文件,初步支持中文和英文 - 在locales目录中写多语言翻译json文件,初步支持中文和英文
2. TitleBar页面开发 2. TitleBar页面开发
- 开发不同操作系统类型的自定义titlebar - 开发不同操作系统类型的自定义titlebar
- Windows系统的TitleBar最左侧显示Frpilot标题,右侧显示语言切换、明暗切换、设置、最小化、关闭,按照顺序展示; - Windows系统的TitleBar最左侧显示FrpcPilot标题,右侧显示语言切换、明暗切换、设置、最小化、关闭,按照顺序展示;
- Mac系统的TitleBar最左侧显示红绿灯操作,右侧显示语言切换、明暗切换、设置、最小化、关闭,按照顺序展示; - Mac系统的TitleBar最左侧显示红绿灯操作,右侧显示语言切换、明暗切换、设置、最小化、关闭,按照顺序展示;
3. Layout页面布局开发 3. Layout页面布局开发
- Aside侧边栏开发,在Aside.vue文件里面编写,左侧菜单初步暂定为仪表盘、服务器、隧道列表、Frpc下载 - Aside侧边栏开发,在Aside.vue文件里面编写,左侧菜单初步暂定为仪表盘、服务器、隧道列表、Frpc下载
@@ -179,3 +179,13 @@ Layout布局content区域的磨砂玻璃卡片圆角样式我要改动一下:
- 使用keep-alive缓存页面组件,避免每次进入都会去请求GitHub,避免触发限流 - 使用keep-alive缓存页面组件,避免每次进入都会去请求GitHub,避免触发限流
- 不需要做持久化缓存,只需要在应用运行时生效即可 - 不需要做持久化缓存,只需要在应用运行时生效即可
- 应用运行时只有在第一次进入Frpc下载页面的时候采取请求GitHub,后面再切换回Frpc下载页面的时候,因为缓存了组件,所以不必再次获取GitHub,需要刷新的时候由用户手动点击刷新按钮 - 应用运行时只有在第一次进入Frpc下载页面的时候采取请求GitHub,后面再切换回Frpc下载页面的时候,因为缓存了组件,所以不必再次获取GitHub,需要刷新的时候由用户手动点击刷新按钮
### 4. 修改
#### 4.1 项目名称修改
- 项目名称修改成了FrpcPilot,软件包构建相关的名称也改成这个
- 界面标题栏相关的也修改成FrpcPilot
- 其他与项目名称有关的也修改一下
先扫描一下有哪些需要修改的,列一个清单出来,经过我的确认之后再开始修改
Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 63 KiB

+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Frpilot</title> <title>FrpcPilot</title>
</head> </head>
<body> <body>
+2 -2
View File
@@ -1,7 +1,7 @@
{ {
"name": "frpilot", "name": "frpcpilot",
"private": true, "private": true,
"version": "1.2.0", "version": "1.2.1",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
+1 -1
View File
@@ -1267,7 +1267,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "frpilot" name = "frpcpilot"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"chrono", "chrono",
+2 -2
View File
@@ -1,5 +1,5 @@
[package] [package]
name = "frpilot" name = "frpcpilot"
version = "0.1.0" version = "0.1.0"
description = "一个基于 Tauri 2 + Vue 3 + TypeScript 的 [frp](https://github.com/fatedier/frp) 可视化客户端,帮助用户快速配置 frpc 版本、服务器与隧道。" description = "一个基于 Tauri 2 + Vue 3 + TypeScript 的 [frp](https://github.com/fatedier/frp) 可视化客户端,帮助用户快速配置 frpc 版本、服务器与隧道。"
authors = ["SparksFly"] authors = ["SparksFly"]
@@ -11,7 +11,7 @@ edition = "2024"
# The `_lib` suffix may seem redundant but it is necessary # The `_lib` suffix may seem redundant but it is necessary
# to make the lib name unique and wouldn't conflict with the bin name. # to make the lib name unique and wouldn't conflict with the bin name.
# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 # This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
name = "frpilot_lib" name = "frpcpilot_lib"
crate-type = ["staticlib", "cdylib", "rlib"] crate-type = ["staticlib", "cdylib", "rlib"]
[workspace] [workspace]
+1 -1
View File
@@ -29,7 +29,7 @@ macro_rules! frp_fields {
fn http_client() -> Result<reqwest::Client, reqwest::Error> { fn http_client() -> Result<reqwest::Client, reqwest::Error> {
reqwest::Client::builder() reqwest::Client::builder()
.user_agent("Frpilot/0.1 (+https://github.com/fatedier/frp)") .user_agent("FrpcPilot/0.1 (+https://github.com/fatedier/frp)")
.connect_timeout(Duration::from_secs(15)) .connect_timeout(Duration::from_secs(15))
.build() .build()
} }
+1 -1
View File
@@ -2,5 +2,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
fn main() { fn main() {
frpilot_lib::run() frpcpilot_lib::run()
} }
+1 -1
View File
@@ -329,7 +329,7 @@ pub struct FrpcLogEvent {
pub time: Option<String>, pub time: Option<String>,
/// 日志级别:INFO / WARN / ERROR / DEBUG / TRACE /// 日志级别:INFO / WARN / ERROR / DEBUG / TRACE
pub level: String, pub level: String,
/// 来源:stdout / stderr / system(system 为 Frpilot 自身补充的日志) /// 来源:stdout / stderr / system(system 为 FrpcPilot 自身补充的日志)
pub source: String, pub source: String,
/// 日志内容 /// 日志内容
pub message: String, pub message: String,
+2 -2
View File
@@ -12,9 +12,9 @@ use crate::models::{Server, Tunnel};
pub fn generate_frpc_config(server: &Server, tunnels: &[Tunnel]) -> String { pub fn generate_frpc_config(server: &Server, tunnels: &[Tunnel]) -> String {
let mut out = String::new(); let mut out = String::new();
out.push_str("# 该文件由 Frpilot 自动生成,请勿手动修改(重新启动 Frpc 会覆盖此文件)\n\n"); out.push_str("# 该文件由 FrpcPilot 自动生成,请勿手动修改(重新启动 Frpc 会覆盖此文件)\n\n");
// 日志:输出到控制台,由 Frpilot 采集并实时展示 // 日志:输出到控制台,由 FrpcPilot 采集并实时展示
// 关闭 ANSI 颜色,避免日志中混入 `\x1b[1;34m` 之类的转义码 // 关闭 ANSI 颜色,避免日志中混入 `\x1b[1;34m` 之类的转义码
out.push_str("log.to = \"console\"\n"); out.push_str("log.to = \"console\"\n");
out.push_str("log.level = \"info\"\n"); out.push_str("log.level = \"info\"\n");
+1 -1
View File
@@ -5,7 +5,7 @@ pub async fn init_pool(app: &AppHandle) -> Result<SqlitePool, sqlx::Error> {
// 数据库文件路径 // 数据库文件路径
let app_dir = app.path().app_data_dir().expect("无法获取APP数据目录"); let app_dir = app.path().app_data_dir().expect("无法获取APP数据目录");
std::fs::create_dir_all(&app_dir).unwrap(); std::fs::create_dir_all(&app_dir).unwrap();
let db_path = app_dir.join("frpilot.db"); let db_path = app_dir.join("frpcpilot.db");
// 初始化数据库连接池 // 初始化数据库连接池
let options = SqliteConnectOptions::new() let options = SqliteConnectOptions::new()
.filename(&db_path) .filename(&db_path)
+1 -1
View File
@@ -1,7 +1,7 @@
//! Frpc 进程管理。 //! Frpc 进程管理。
//! //!
//! 通过 `std::process::Command` 直接拉起 frpc 可执行文件(**刻意绕开 plugin-shell**): //! 通过 `std::process::Command` 直接拉起 frpc 可执行文件(**刻意绕开 plugin-shell**):
//! - frpc 与主进程互相独立,frpc 异常退出不会影响 Frpilot 本体; //! - frpc 与主进程互相独立,frpc 异常退出不会影响 FrpcPilot 本体;
//! - Windows 下使用 `CREATE_NO_WINDOW` 启动,避免弹出黑色控制台窗口; //! - Windows 下使用 `CREATE_NO_WINDOW` 启动,避免弹出黑色控制台窗口;
//! - stdout / stderr 通过管道读取,按行解析后以 `frpc-log` 事件实时推送给前端; //! - stdout / stderr 通过管道读取,按行解析后以 `frpc-log` 事件实时推送给前端;
//! - 后台守护线程轮询子进程状态,退出时推送 `frpc-exit` 事件。 //! - 后台守护线程轮询子进程状态,退出时推送 `frpc-exit` 事件。
+5 -5
View File
@@ -1,8 +1,8 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Frpilot", "productName": "FrpcPilot",
"version": "../package.json", "version": "../package.json",
"identifier": "Frpilot", "identifier": "FrpcPilot",
"build": { "build": {
"beforeDevCommand": "pnpm dev", "beforeDevCommand": "pnpm dev",
"devUrl": "http://localhost:1420", "devUrl": "http://localhost:1420",
@@ -12,7 +12,7 @@
"app": { "app": {
"windows": [ "windows": [
{ {
"title": "Frpilot", "title": "FrpcPilot",
"width": 1100, "width": 1100,
"height": 720, "height": 720,
"minWidth": 900, "minWidth": 900,
@@ -42,8 +42,8 @@
"active": true, "active": true,
"dialog": false, "dialog": false,
"endpoints": [ "endpoints": [
"https://ghproxy.net/https://github.com/SparksFly91/Frpilot/releases/latest/download/latest.json", "https://ghproxy.net/https://github.com/SparksFly91/FrpcPilot/releases/latest/download/latest.json",
"https://github.com/SparksFly91/Frpilot/releases/latest/download/latest.json" "https://github.com/SparksFly91/FrpcPilot/releases/latest/download/latest.json"
], ],
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU0REVGMTREODFFOTI2MUEKUldRYUp1bUJUZkhlNU1qRmlPQm5xSmdQd24waFltVmNtTjlUallYVmdva1VGNkp5bTVGcVlsZUgK" "pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU0REVGMTREODFFOTI2MUEKUldRYUp1bUJUZkhlNU1qRmlPQm5xSmdQd24waFltVmNtTjlUallYVmdva1VGNkp5bTVGcVlsZUgK"
} }
+1 -1
View File
@@ -3,7 +3,7 @@
"app": { "app": {
"windows": [ "windows": [
{ {
"title": "Frpilot", "title": "FrpcPilot",
"width": 1100, "width": 1100,
"height": 720, "height": 720,
"minWidth": 900, "minWidth": 900,
+1 -1
View File
@@ -2,7 +2,7 @@ import type { Update } from "@tauri-apps/plugin-updater"
import { isTauri } from "@/utils/window" import { isTauri } from "@/utils/window"
/** 项目 GitHub 仓库地址(与 tauri.conf.json 中 updater 端点保持一致) */ /** 项目 GitHub 仓库地址(与 tauri.conf.json 中 updater 端点保持一致) */
export const PROJECT_GITHUB_URL = "https://github.com/SparksFly91/Frpilot" export const PROJECT_GITHUB_URL = "https://github.com/SparksFly91/FrpcPilot"
/** /**
* 检查是否有可用更新。 * 检查是否有可用更新。
+1 -1
View File
@@ -9,7 +9,7 @@
alt="" alt=""
draggable="false" draggable="false"
/> />
<span class="text-sm font-semibold tracking-wide">Frpilot</span> <span class="text-sm font-semibold tracking-wide">FrpcPilot</span>
</div> </div>
<!-- 右侧:语言 / 主题 / 设置 / 最小化 / 关闭(macOS 下隐藏最小化与关闭) --> <!-- 右侧:语言 / 主题 / 设置 / 最小化 / 关闭(macOS 下隐藏最小化与关闭) -->
+2 -2
View File
@@ -6,7 +6,7 @@ import { useWindowStore } from "@/stores/window"
import { isTauri } from "@/utils/window" import { isTauri } from "@/utils/window"
/** 托盘图标固定 id(便于热更新 / 重载时清理残留的旧图标) */ /** 托盘图标固定 id(便于热更新 / 重载时清理残留的旧图标) */
const TRAY_ID = "frpilot-tray" const TRAY_ID = "frpcpilot-tray"
/** 是否已初始化,避免重复创建托盘 */ /** 是否已初始化,避免重复创建托盘 */
let initialized = false let initialized = false
@@ -125,7 +125,7 @@ async function createTray() {
await TrayIcon.new({ await TrayIcon.new({
id: TRAY_ID, id: TRAY_ID,
icon: icon ?? undefined, icon: icon ?? undefined,
tooltip: "Frpilot", tooltip: "FrpcPilot",
menu, menu,
// 左键点击直接显示窗口,右键才弹出菜单 // 左键点击直接显示窗口,右键才弹出菜单
showMenuOnLeftClick: false, showMenuOnLeftClick: false,
+7 -7
View File
@@ -1,6 +1,6 @@
{ {
"app": { "app": {
"name": "Frpilot", "name": "FrpcPilot",
"description": "A visual client for frpc" "description": "A visual client for frpc"
}, },
"titlebar": { "titlebar": {
@@ -35,11 +35,11 @@
"quit": "Quit" "quit": "Quit"
}, },
"closeDialog": { "closeDialog": {
"title": "Close Frpilot", "title": "Close FrpcPilot",
"tray": "Minimize to system tray", "tray": "Minimize to system tray",
"trayDesc": "Keep Frpilot running in the background; reopen it from the system tray", "trayDesc": "Keep FrpcPilot running in the background; reopen it from the system tray",
"exit": "Quit directly", "exit": "Quit directly",
"exitDesc": "Stop the tunnel and exit Frpilot completely", "exitDesc": "Stop the tunnel and exit FrpcPilot completely",
"behavior": "Close behavior", "behavior": "Close behavior",
"ask": "Ask every time", "ask": "Ask every time",
"askDesc": "Show this dialog on every close and let you choose", "askDesc": "Show this dialog on every close and let you choose",
@@ -69,7 +69,7 @@
"clear": "Clear", "clear": "Clear",
"mock": "Mock data", "mock": "Mock data",
"logEmpty": "No logs yet. Live logs will appear here once Frpc starts.", "logEmpty": "No logs yet. Live logs will appear here once Frpc starts.",
"logReady": "Frpilot is ready. Waiting for Frpc to start.", "logReady": "FrpcPilot is ready. Waiting for Frpc to start.",
"logStarted": "Frpc {version} started", "logStarted": "Frpc {version} started",
"logStopped": "Frpc stopped", "logStopped": "Frpc stopped",
"logStartFailed": "Failed to start Frpc: {message}" "logStartFailed": "Failed to start Frpc: {message}"
@@ -255,10 +255,10 @@
} }
}, },
"about": { "about": {
"title": "About Frpilot", "title": "About FrpcPilot",
"subtitle": "A lightweight, friendly visual client for frp", "subtitle": "A lightweight, friendly visual client for frp",
"introTitle": "Introduction", "introTitle": "Introduction",
"intro": "Frpilot is a visual client for frp built with Tauri 2 + Vue 3 + TypeScript. Manage frpc versions, servers and tunnels through a friendly GUI — and say goodbye to hand-writing frpc.toml.", "intro": "FrpcPilot is a visual client for frp built with Tauri 2 + Vue 3 + TypeScript. Manage frpc versions, servers and tunnels through a friendly GUI — and say goodbye to hand-writing frpc.toml.",
"flowTitle": "How to use", "flowTitle": "How to use",
"flow": { "flow": {
"step1Title": "Download frpc", "step1Title": "Download frpc",
+7 -7
View File
@@ -1,6 +1,6 @@
{ {
"app": { "app": {
"name": "Frpilot", "name": "FrpcPilot",
"description": "Frpc 可视化客户端" "description": "Frpc 可视化客户端"
}, },
"titlebar": { "titlebar": {
@@ -35,11 +35,11 @@
"quit": "退出" "quit": "退出"
}, },
"closeDialog": { "closeDialog": {
"title": "关闭 Frpilot", "title": "关闭 FrpcPilot",
"tray": "最小化到系统托盘", "tray": "最小化到系统托盘",
"trayDesc": "保持 Frpilot 在后台运行,可从系统托盘随时打开", "trayDesc": "保持 FrpcPilot 在后台运行,可从系统托盘随时打开",
"exit": "直接退出", "exit": "直接退出",
"exitDesc": "停止穿透并完全退出 Frpilot", "exitDesc": "停止穿透并完全退出 FrpcPilot",
"behavior": "关闭行为", "behavior": "关闭行为",
"ask": "每次询问", "ask": "每次询问",
"askDesc": "每次关闭都弹出此对话框,由你选择关闭方式", "askDesc": "每次关闭都弹出此对话框,由你选择关闭方式",
@@ -69,7 +69,7 @@
"clear": "清空", "clear": "清空",
"mock": "模拟数据", "mock": "模拟数据",
"logEmpty": "暂无日志,启动 Frpc 后将在此显示实时日志", "logEmpty": "暂无日志,启动 Frpc 后将在此显示实时日志",
"logReady": "Frpilot 已就绪,等待启动 Frpc", "logReady": "FrpcPilot 已就绪,等待启动 Frpc",
"logStarted": "已启动 Frpc {version}", "logStarted": "已启动 Frpc {version}",
"logStopped": "已停止 Frpc", "logStopped": "已停止 Frpc",
"logStartFailed": "启动 Frpc 失败:{message}" "logStartFailed": "启动 Frpc 失败:{message}"
@@ -255,10 +255,10 @@
} }
}, },
"about": { "about": {
"title": "关于 Frpilot", "title": "关于 FrpcPilot",
"subtitle": "轻量、顺手的 frp 可视化桌面客户端", "subtitle": "轻量、顺手的 frp 可视化桌面客户端",
"introTitle": "项目介绍", "introTitle": "项目介绍",
"intro": "Frpilot 是一个基于 Tauri 2 + Vue 3 + TypeScript 打造的 frp 可视化客户端,帮你用图形界面管理 frpc 版本、服务器与隧道,从此告别手写 frpc.toml。", "intro": "FrpcPilot 是一个基于 Tauri 2 + Vue 3 + TypeScript 打造的 frp 可视化客户端,帮你用图形界面管理 frpc 版本、服务器与隧道,从此告别手写 frpc.toml。",
"flowTitle": "使用流程", "flowTitle": "使用流程",
"flow": { "flow": {
"step1Title": "下载 frpc", "step1Title": "下载 frpc",
+5 -5
View File
@@ -16,11 +16,11 @@ export type RunStatus = "running" | "error" | "stopped"
*/ */
export const useAppStore = defineStore("app", () => { export const useAppStore = defineStore("app", () => {
// 语言(持久化到 localStorage) // 语言(持久化到 localStorage)
const language = useStorage<Language>("frpilot:language", "zh-CN") const language = useStorage<Language>("frpcpilot:language", "zh-CN")
// 明暗主题:useDark 会在 <html> 上切换 .dark 类名 // 明暗主题:useDark 会在 <html> 上切换 .dark 类名
const isDark = useDark({ const isDark = useDark({
storageKey: "frpilot:theme", storageKey: "frpcpilot:theme",
selector: "html", selector: "html",
attribute: "class", attribute: "class",
valueDark: "dark", valueDark: "dark",
@@ -29,7 +29,7 @@ export const useAppStore = defineStore("app", () => {
const toggleDark = useToggle(isDark) const toggleDark = useToggle(isDark)
// 窗口背景图片(持久化) // 窗口背景图片(持久化)
const background = useStorage<BackgroundKey>("frpilot:background", DEFAULT_BACKGROUND) const background = useStorage<BackgroundKey>("frpcpilot:background", DEFAULT_BACKGROUND)
const backgroundUrl = computed(() => getBackgroundUrl(background.value)) const backgroundUrl = computed(() => getBackgroundUrl(background.value))
// 把背景图同步到 <html>(整窗背景,避免元素高度误差造成的上下留白) // 把背景图同步到 <html>(整窗背景,避免元素高度误差造成的上下留白)
@@ -46,8 +46,8 @@ export const useAppStore = defineStore("app", () => {
}) })
// 磨砂玻璃透明度(0 - 100,数值越大越透明,持久化) // 磨砂玻璃透明度(0 - 100,数值越大越透明,持久化)
const cardTransparency = useStorage<number>("frpilot:card-transparency", 55) const cardTransparency = useStorage<number>("frpcpilot:card-transparency", 55)
const modalTransparency = useStorage<number>("frpilot:modal-transparency", 38) const modalTransparency = useStorage<number>("frpcpilot:modal-transparency", 38)
/** 透明度百分比 → 背景 alpha(越大越透明,alpha 越小;并做范围兜底) */ /** 透明度百分比 → 背景 alpha(越大越透明,alpha 越小;并做范围兜底) */
function alphaFromTransparency(value: number) { function alphaFromTransparency(value: number) {
+1 -1
View File
@@ -20,7 +20,7 @@ export interface UpdateInfo {
*/ */
export const useUpdateStore = defineStore("update", () => { export const useUpdateStore = defineStore("update", () => {
/** 用户选择「忽略该版本」后持久化的版本号,静默检查时不再提示 */ /** 用户选择「忽略该版本」后持久化的版本号,静默检查时不再提示 */
const ignoredVersion = useStorage<string>("frpilot:ignored-update", "") const ignoredVersion = useStorage<string>("frpcpilot:ignored-update", "")
const checking = ref(false) const checking = ref(false)
const installing = ref(false) const installing = ref(false)
+2 -2
View File
@@ -24,9 +24,9 @@ export const useWindowStore = defineStore("window", () => {
/** 关闭确认对话框是否打开 */ /** 关闭确认对话框是否打开 */
const closeConfirmOpen = ref(false) const closeConfirmOpen = ref(false)
/** 记住的关闭方式(弹窗默认选中项;「保持以上选择」时直接生效,持久化) */ /** 记住的关闭方式(弹窗默认选中项;「保持以上选择」时直接生效,持久化) */
const closeChoice = useStorage<CloseChoice>("frpilot:close-choice", "tray") const closeChoice = useStorage<CloseChoice>("frpcpilot:close-choice", "tray")
/** 关闭行为:每次询问 / 保持以上选择(持久化,默认每次询问) */ /** 关闭行为:每次询问 / 保持以上选择(持久化,默认每次询问) */
const closeBehavior = useStorage<CloseBehavior>("frpilot:close-behavior", "ask") const closeBehavior = useStorage<CloseBehavior>("frpcpilot:close-behavior", "ask")
/** 是否正在退出(停止穿透 + 退出软件) */ /** 是否正在退出(停止穿透 + 退出软件) */
const quitting = ref(false) const quitting = ref(false)
+2 -2
View File
@@ -72,9 +72,9 @@ const loading = ref(false)
const importing = ref(false) const importing = ref(false)
/** 是否展示所有架构的 Frpc */ /** 是否展示所有架构的 Frpc */
const showAllArchFrpc = useStorage("frpilot:frp:allArchFrpc", false) const showAllArchFrpc = useStorage("frpcpilot:frp:allArchFrpc", false)
/** 是否作为 frp 下载器展示所有架构的 Frps */ /** 是否作为 frp 下载器展示所有架构的 Frps */
const showAllArchFrps = useStorage("frpilot:frp:allArchFrps", false) const showAllArchFrps = useStorage("frpcpilot:frp:allArchFrps", false)
/** 后端返回的全部发行包(含所有架构) */ /** 后端返回的全部发行包(含所有架构) */
const allReleases = ref<FrpRelease[]>([]) const allReleases = ref<FrpRelease[]>([])
+1 -1
View File
@@ -29,7 +29,7 @@
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<GithubOutlined class="text-2xl" /> <GithubOutlined class="text-2xl" />
<div class="min-w-0 flex-1"> <div class="min-w-0 flex-1">
<div class="truncate text-sm font-medium">SparksFly91 / Frpilot</div> <div class="truncate text-sm font-medium">SparksFly91 / FrpcPilot</div>
<div class="truncate text-xs opacity-60">{{ PROJECT_GITHUB_URL }}</div> <div class="truncate text-xs opacity-60">{{ PROJECT_GITHUB_URL }}</div>
</div> </div>
<a-button type="primary" size="small" :icon="h(LinkOutlined)" @click="onOpenRepo"> <a-button type="primary" size="small" :icon="h(LinkOutlined)" @click="onOpenRepo">