diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 94f5569..fa6f89b 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -4,6 +4,36 @@
---
+## v1.2.0(2026-10-16)
+
+### ✨ 新增功能
+
+- **常规设置页面**:设置页新增「常规」子页面(位于设置菜单首位),集中管理基础行为:
+ - **关闭行为**:新增「每次询问 / 保持以上选择」单选组(默认「每次询问」)。
+ - *每次询问*:每次关闭都弹出对话框,由用户现场选择处理方式;
+ - *保持以上选择*:记住所选关闭方式并持久生效,之后关闭不再弹窗。
+ - **语言切换**:可直接在设置页切换界面语言,与顶部栏的语言切换保持同步。
+ - 关闭确认对话框同步新增「关闭行为」选项,与常规设置页内容一致,用户可随时再次修改。
+- **磨砂玻璃透明度**:外观设置新增「磨砂玻璃透明度」,可分别调节**卡片透明度**与**弹窗透明度**(0 – 100,数值越大越透明),并提供实时预览,设置持久化保存。
+- **更多窗口背景**:背景图片由 2 张扩充至 9 张(新增「背景三」~「背景九」),可在外观设置中自由挑选。
+- **Frpc 下载页缓存**:下载页新增运行时缓存,应用运行期间**首次进入**才拉取 GitHub 版本列表,之后切换回该页面不再重复请求,避免触发接口限流;需要获取最新列表时手动点击「刷新」即可。
+
+### 🎨 优化
+
+- 新增卡片式单选组组件(`CardRadioGroup`),关闭弹窗与常规设置页复用,统一选项样式与交互。
+- 关闭弹窗内的选项改为临时草稿状态,点击「确定」后才写回设置,避免误触单选框又取消时被改掉配置。
+
+### 🐛 修复
+
+- 修复开发模式下热更新 / 页面重载时系统托盘图标重复叠加的问题:创建托盘前按固定 id 清理残留图标,并在热更新时释放旧实例的监听。
+- 修复暗色主题下普通(非组件库)文本仍显示为浏览器默认黑色的问题,文本颜色现随明暗主题正确切换。
+
+### 🧱 工程
+
+- 应用版本升级至 **v1.2.0**。
+- 路由表新增 `isCache` 元信息,并补充 `RouteMeta` 类型声明(页面标题 `title` 与缓存开关 `isCache`),按需使用 `keep-alive` 缓存页面组件(仅运行时生效,不做持久化)。
+- 更新开发文档相关说明。
+
## v1.1.0(2026-10-14)
### ✨ 新增功能
diff --git a/docs/Frpilot开发提示词.md b/docs/Frpilot开发提示词.md
index 4000bed..ac72100 100644
--- a/docs/Frpilot开发提示词.md
+++ b/docs/Frpilot开发提示词.md
@@ -170,4 +170,12 @@ Layout布局content区域的磨砂玻璃卡片圆角样式我要改动一下:
- 常规设置页面再增加一个语言切换设置,保持跟Header栏同步
-开发过程中使用到的组件尽可能全部使用Antdv库里面的,另外我引入的有tailwindcss原子化组件、auto-import和components依赖可以简化引入,开发之前尽可能先阅读一下package.json,看一下有哪些依赖可以简化代码开发
\ No newline at end of file
+开发过程中使用到的组件尽可能全部使用Antdv库里面的,另外我引入的有tailwindcss原子化组件、auto-import和components依赖可以简化引入,开发之前尽可能先阅读一下package.json,看一下有哪些依赖可以简化代码开发
+
+#### 3.10 Frpc下载页面增加缓存
+
+目前每次进入Frpc下载页面都会重新去获取Frpc的下载列表,在路由表增加一个meta属性用于开关页面是否缓存isCache
+
+- 使用keep-alive缓存页面组件,避免每次进入都会去请求GitHub,避免触发限流
+- 不需要做持久化缓存,只需要在应用运行时生效即可
+- 应用运行时只有在第一次进入Frpc下载页面的时候采取请求GitHub,后面再切换回Frpc下载页面的时候,因为缓存了组件,所以不必再次获取GitHub,需要刷新的时候由用户手动点击刷新按钮
\ No newline at end of file
diff --git a/src/layout/Layout.vue b/src/layout/Layout.vue
index 83a11da..7c4bc26 100644
--- a/src/layout/Layout.vue
+++ b/src/layout/Layout.vue
@@ -9,7 +9,12 @@
-
+
+
+
+
+
+
@@ -31,6 +36,19 @@ import { useUpdateStore } from "@/stores/update"
const router = useRouter()
const updateStore = useUpdateStore()
+/**
+ * 需要 keep-alive 缓存的页面组件名列表(由路由 meta.isCache 决定)。
+ *
+ * keep-alive 通过组件名匹配缓存,故约定:缓存页面的组件名需与路由 name 一致
+ * (页面通过 defineOptions({ name }) 显式声明)。
+ */
+const cachedViews = computed(() =>
+ router
+ .getRoutes()
+ .filter((record) => record.meta.isCache && record.name)
+ .map((record) => String(record.name)),
+)
+
/** 点击标题栏“设置”按钮 → 跳转设置页 */
function goToSetting() {
router.push("/setting")
diff --git a/src/router/router.ts b/src/router/router.ts
index a7dc19a..29bd3c5 100644
--- a/src/router/router.ts
+++ b/src/router/router.ts
@@ -1,6 +1,16 @@
import { createRouter, createWebHistory } from "vue-router";
import { RouteRecordRaw } from "vue-router";
+/** 路由元信息类型扩展 */
+declare module "vue-router" {
+ interface RouteMeta {
+ /** 页面标题(i18n key) */
+ title?: string;
+ /** 是否使用 keep-alive 缓存该页面组件(默认不缓存) */
+ isCache?: boolean;
+ }
+}
+
const routes: RouteRecordRaw[] = [
{
path: "/",
@@ -30,7 +40,8 @@ const routes: RouteRecordRaw[] = [
path: "download",
name: "Download",
component: () => import("@/views/Download.vue"),
- meta: { title: "menu.download" },
+ // 缓存该页面:避免每次进入都请求 GitHub 触发限流,需刷新时由用户手动点击刷新按钮
+ meta: { title: "menu.download", isCache: true },
},
{
path: "setting",
diff --git a/src/views/Download.vue b/src/views/Download.vue
index 34622c6..81eaef4 100644
--- a/src/views/Download.vue
+++ b/src/views/Download.vue
@@ -65,6 +65,9 @@ import { isTauri } from "@/utils/window"
const { t } = useI18n()
+// 组件名需与路由 name 一致,以便被 Layout 的 缓存
+defineOptions({ name: "Download" })
+
const loading = ref(false)
const importing = ref(false)