diff --git a/docs/site-posts/01-welcome.md b/docs/site-posts/01-welcome.md
deleted file mode 100644
index 55b7c3d..0000000
--- a/docs/site-posts/01-welcome.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# 欢迎来到本站
-
-> 建议标题:欢迎来到本站
-> 建议标签:`站务` `介绍`
-> 建议操作:置顶(可选精华)
-
----
-
-你好,欢迎加入本站。
-
-这里运行的是开源论坛程序 **姜十三论坛(Jiang13 Forum)**。
-它面向小圈子、团队与同好社群,目标很简单:
-
-**能聊 · 好看 · 好装**
-
----
-
-## 这是什么
-
-姜十三论坛不是「大而全」的社区平台,而是一个轻量、现代化的论坛:
-
-- 有板块、帖子、楼层回复,讨论能沉淀、能追溯
-- 界面清爽,信息密度适中,桌面与手机都好用
-- 单个程序即可部署,数据在自己手里
-
-技术上,它是一个 **Go 单二进制**:前端页面内嵌,数据库用内置 **SQLite**。
-拷到服务器、启动、注册——就可以开始用。
-
----
-
-## 谁适合用
-
-| 场景 | 说明 |
-| --- | --- |
-| 团队 / 工作室 | 需求讨论、进度同步、知识沉淀 |
-| 兴趣小圈子 | 同好交流、作品分享、活动组织 |
-| 项目配套社区 | 可与 Gitea 等工具做 SSO 联动 |
-| 个人站长 | 单机可跑,无需云数据库与一堆微服务 |
-
-如果你需要的是百万级公网社区、复杂插件生态或企业级工单流,它可能不是最优选。
-如果你要的是 **小而美、自己能装、自己能管**,就对了。
-
----
-
-## 本板块说明
-
-「站务公告」只发布:
-
-- 本站介绍与使用指引
-- 规则与站务通知
-- 与姜十三论坛相关的说明
-
-日常聊天、提问、分享,请到其他讨论板块。
-
-有问题可联系管理员。祝你在这里聊得愉快。
diff --git a/docs/site-posts/02-getting-started.md b/docs/site-posts/02-getting-started.md
deleted file mode 100644
index 5e69684..0000000
--- a/docs/site-posts/02-getting-started.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# 三分钟上手本站
-
-> 建议标题:三分钟上手本站
-> 建议标签:`站务` `指南`
-> 建议操作:普通发布
-
----
-
-这篇给你一条最短路径:从注册到发第一帖,再到(如果是管理员)进入后台。
-
----
-
-## 1. 注册与登录
-
-1. 打开注册页,填写用户名、邮箱与密码。
-2. 若站点已配置邮件服务,可能需要邮箱验证码。
-3. **第一个注册的用户会自动成为管理员**,无需额外安装向导。
-
-登录后,右上角会出现头像与私信入口。
-
----
-
-## 2. 认识首页
-
-首页通常是三栏布局:
-
-| 区域 | 内容 |
-| --- | --- |
-| 左侧 | 板块导航、常用入口 |
-| 中间 | 帖子列表(Feed) |
-| 右侧 | 热门帖、最新评论等动态 |
-
-中间列表可按 **最新发帖 / 最新回复 / 热门** 切换。
-支持浅色 / 暗色主题,偏好会记住。
-
-手机上侧栏会收起,不影响浏览与发帖。
-
----
-
-## 3. 发帖与回复
-
-1. 点击「发帖」。
-2. 选择板块,填写标题、标签(可选)与正文。
-3. 正文支持富文本:分段、格式、图片上传等。
-4. 发布后可在帖内回复;评论是 **楼层式** 的,可回复、引用、@。
-
-帖子支持点赞与收藏。公开主页上可以看到你的基本资料与动态。
-
----
-
-## 4. 个人入口
-
-点击头像菜单,常见入口包括:
-
-- **个人主页**:别人看到的你
-- **账号设置**:昵称、签名、头像、密码
-- **站内私信**:与站内用户往来
-- **我的收藏**:收藏过的帖子
-
----
-
-## 5. 管理后台(仅管理员)
-
-访问路径:`/admin`
-
-常见能力:
-
-- 板块、帖子、评论、举报、用户、媒体
-- 系统设置(品牌、限流、敏感词、邮件、OIDC、存储等)
-- 数据库备份
-
-配置怎么分:
-
-| 类型 | 在哪里改 |
-| --- | --- |
-| 端口、数据目录、JWT | 服务器上的 `app.ini`(改后重启) |
-| OIDC、邮件、对象存储、品牌文案等 | 管理后台「系统设置」(保存即生效) |
-
----
-
-## 接下来做什么
-
-1. 逛一遍现有板块
-2. 发第一篇帖,或回一楼
-3. 需要时再进后台微调站点设置
-
-聊起来就对了。
diff --git a/docs/site-posts/03-features.md b/docs/site-posts/03-features.md
deleted file mode 100644
index 028a820..0000000
--- a/docs/site-posts/03-features.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# 功能速览
-
-> 建议标题:功能速览
-> 建议标签:`站务` `功能`
-> 建议操作:普通发布
-
----
-
-姜十三论坛刻意把功能收在「小圈子真正用得到」的范围内。
-下面按前台、互动、管理三块速览。
-
----
-
-## 前台浏览
-
-- 三栏布局,桌面与移动端自适应
-- Feed 排序:最新发帖 / 最新回复 / 热门
-- 虚拟滚动,长列表也更流畅
-- 浅色 / 暗色主题,偏好可记住
-- 板块图标与主题色可自定义
-
----
-
-## 发帖与讨论
-
-- TipTap 富文本编辑器
-- 标题、标签、板块选择
-- 正文图片上传
-- 楼层评论:回复、引用、@
-- 点赞、收藏
-- 帖子置顶、精华
-- 编辑修订历史(可对比差异)
-- 可配置普通用户的编辑时限
-
----
-
-## 社交与个人
-
-- 公开用户主页
-- 站内私信(会话式)
-- 账号资料:昵称、签名、头像
-
----
-
-## 管理后台
-
-统一在 `/admin`,与前台同一套 React 体验:
-
-| 模块 | 能做什么 |
-| --- | --- |
-| 仪表盘 | 概览站点状态 |
-| 板块 | 创建 / 编辑 / 排序 / 外观 |
-| 帖子 | 审核、置顶、精华、锁定、回收站 |
-| 评论 | 审核与管理 |
-| 举报 | 处理用户举报 |
-| 用户 | 禁言等管理操作 |
-| 媒体 | 查看与清理上传文件 |
-| 设置 | 品牌、限流、敏感词、邮件、OIDC、存储等 |
-| 备份 | SQLite 一键备份 |
-
----
-
-## 可选能力
-
-这些不是「装完就必须开」的,按需在后台启用:
-
-- 邮件验证码注册
-- OIDC Provider(可给 Gitea 等站点做登录源)
-- Gitea 公开仓库同步到「开源码桶」
-- 本地磁盘或 S3 兼容对象存储
-
----
-
-## 权限模型
-
-只有两种角色:
-
-- **普通用户**
-- **管理员**
-
-第一个注册用户自动成为管理员。
-小圈子场景够用,不堆复杂角色矩阵。
-
----
-
-## 开发状态
-
-项目仍在积极开发中,核心体验已经可用。
-完整规划见仓库中的 `ROADMAP.md`。欢迎反馈与共建。
diff --git a/docs/site-posts/04-deployment.md b/docs/site-posts/04-deployment.md
deleted file mode 100644
index f41dac9..0000000
--- a/docs/site-posts/04-deployment.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# 为什么是单文件部署
-
-> 建议标题:为什么是单文件部署
-> 建议标签:`站务` `部署` `技术`
-> 建议操作:按需发布(给关心自建的人看)
-
----
-
-姜十三论坛最硬核的卖点之一,是部署路径极短。
-
-不是「理论上可以打包」,而是日常用法就是:
-
-1. 编译得到一个二进制
-2. 放到目录里运行
-3. 自动生成 `app.ini`
-4. 浏览器注册,第一个账号即管理员
-
----
-
-## 它解决什么问题
-
-传统论坛方案常常落在两端:
-
-- **很重**:功能全,但部署与运维成本高
-- **很碎**:聊天工具 / 文档工具方便,却缺少「发帖—回复—沉淀」的社区节奏
-
-小圈子真正需要的往往是中间态:
-
-- 有论坛结构,讨论可追溯
-- 界面清爽,用起来顺手
-- 部署简单到一个人能搞定
-- 数据清楚、备份好懂
-
-单文件部署,就是为最后两点服务的。
-
----
-
-## 具体意味着什么
-
-| 能力 | 说明 |
-| --- | --- |
-| 单二进制 | 前端静态资源已内嵌,不必单独部署一套前端目录 |
-| 内置 SQLite | 零外部数据库,数据落在本地目录 |
-| 精简 `app.ini` | 主要管端口、数据目录、JWT 等进程级配置 |
-| 后台热配置 | OIDC、邮件、存储、品牌等在管理后台修改,保存即生效 |
-| 系统服务 | 内置 Linux systemd / Windows Service 安装与启停 |
-| 跨平台 | Windows / Linux / macOS 均可编译与运行 |
-
-备份也直观:数据目录里的数据库、上传文件、配置,结构清晰,拷贝即可留存。
-
----
-
-## 配置怎么分工
-
-| 改什么 | 去哪里 |
-| --- | --- |
-| HTTP 端口、数据目录、JWT | `app.ini`(修改后重启进程 / 服务) |
-| 站点品牌、OIDC、邮件、对象存储、限流、敏感词 | 管理后台 → 系统设置 |
-
-这样既保留「改文件就能控进程」的可控性,又避免把所有业务项都塞进配置文件。
-
----
-
-## 一句话总结
-
-**姜十三论坛** = 小圈子该有的论坛能力 × 清新好用的界面 × 真正能单文件带走的部署方式。
-
-源码与说明见项目仓库。许可证:MIT。
diff --git a/docs/site-posts/README.md b/docs/site-posts/README.md
index fe4ca77..3f7ed3d 100644
--- a/docs/site-posts/README.md
+++ b/docs/site-posts/README.md
@@ -1,7 +1,5 @@
# 站务公告 · 发帖素材
-本目录提供「站务公告」板块的建板参数,以及可直接复制到论坛的介绍文章(Markdown)。
-
## 板块设置
| 项 | 建议值 |
@@ -9,21 +7,22 @@
| 名称 | 站务公告 |
| 描述 | 本站说明与姜十三论坛介绍。请勿灌水。 |
| 图标 | `megaphone` |
-| 色标 | 建议第 0 或 1 槽(稳重、好辨认) |
-| 排序 | `0`(尽量靠前) |
+| 色标 | 建议第 0 或 1 槽 |
+| 排序 | `0` |
-## 文章与标签
+## 主文(必发)
-| 文件 | 建议标题 | 标签 | 操作 |
+| 文件 | 标题 | 标签 | 操作 |
| --- | --- | --- | --- |
-| [01-welcome.md](./01-welcome.md) | 欢迎来到本站 | `站务` `介绍` | **置顶**(可选精华) |
-| [02-getting-started.md](./02-getting-started.md) | 三分钟上手本站 | `站务` `指南` | 普通发布 |
-| [03-features.md](./03-features.md) | 功能速览 | `站务` `功能` | 普通发布 |
-| [04-deployment.md](./04-deployment.md) | 为什么是单文件部署 | `站务` `部署` `技术` | 按需发布 |
+| [about-jiang13.md](./about-jiang13.md) | 关于本站 · 姜十三论坛 | `站务` `介绍` | **置顶**(可选精华) |
-## 发布建议
+把原先分篇的「上手 / 功能 / 部署」三帖 **删除**,避免与长文重复。
-1. 先建板块,再按上表顺序发帖。
-2. 每篇复制「标题 / 标签 / 正文」三块;正文从 `---` 后的正文区开始粘贴。
-3. 若编辑器是富文本:粘贴后检查标题层级与列表是否正常。
-4. 本板块仅发站务与介绍;日常讨论放到其他板块。
+## 可选短文
+
+若站务区希望不止一篇,见 [optional.md](./optional.md):
+
+- [community-guidelines.md](./community-guidelines.md) — 发帖约定
+- [feedback.md](./feedback.md) — 反馈与建议
+
+复制正文时:从各文件第一个 `---` **之后**开始粘贴。
diff --git a/docs/site-posts/about-jiang13.md b/docs/site-posts/about-jiang13.md
new file mode 100644
index 0000000..170cab6
--- /dev/null
+++ b/docs/site-posts/about-jiang13.md
@@ -0,0 +1,185 @@
+# 关于本站 · 姜十三论坛
+
+> 建议标题:关于本站 · 姜十三论坛
+> 建议标签:`站务` `介绍`
+> 建议操作:置顶(可选精华)
+
+---
+
+你好,欢迎加入本站。
+
+这里运行的是开源论坛 **姜十三论坛(Jiang13 Forum)**——面向小圈子、团队与同好社群,目标很明确:
+
+**能聊 · 好看 · 好装**
+
+下文介绍它是什么、怎么上手、有哪些能力,以及为何采用单文件部署。读完即可开始发帖;细节可随时回来查阅。
+
+---
+
+## 一、它是什么
+
+姜十三论坛不是大而全的社区平台,而是一款轻量、现代化的论坛软件。
+
+它做好一件事:给「几人到几百人」的内部交流,一个干净、顺手、数据在自己手里的地方。
+
+- 有板块、帖子、楼层回复,讨论能沉淀、能追溯
+- 界面清爽,信息密度适中,桌面与手机都好用
+- 单个程序即可部署,备份路径清晰
+
+技术上,它是一个 **Go 单二进制**:前端页面内嵌,数据库用内置 **SQLite**。拷到服务器、启动、注册——就可以用。
+
+### 谁适合用
+
+| 场景 | 说明 |
+| --- | --- |
+| 团队 / 工作室 | 需求讨论、进度同步、知识沉淀 |
+| 兴趣小圈子 | 同好交流、作品分享、活动组织 |
+| 项目配套社区 | 可与 Gitea 等做 SSO 联动 |
+| 个人站长 | 单机可跑,无需云数据库与一堆微服务 |
+
+若你需要百万级公网社区、复杂插件生态或企业级工单流,它可能不是最优选。
+若你要的是 **小而美、自己能装、自己能管**,就对了。
+
+### 本板块说明
+
+「站务公告」只发站务与介绍类内容。日常聊天、提问、分享,请到其他讨论板块。
+
+---
+
+## 二、三分钟上手
+
+### 注册与登录
+
+1. 打开注册页,填写用户名、邮箱与密码。
+2. 若已开启邮件服务,可能需要邮箱验证码。
+3. **第一个注册用户自动成为管理员**,无需安装向导。
+
+登录后,右上角会出现头像与私信入口。
+
+### 认识首页
+
+| 区域 | 内容 |
+| --- | --- |
+| 左侧 | 板块导航、常用入口 |
+| 中间 | 帖子列表(Feed) |
+| 右侧 | 热门帖、最新评论等 |
+
+列表可按 **最新发帖 / 最新回复 / 热门** 切换。
+支持浅色 / 暗色主题,偏好会记住。手机上侧栏会收起,不影响浏览与发帖。
+
+### 发帖与回复
+
+点「发帖」→ 选板块 → 写标题、标签(可选)与正文。
+正文支持富文本与图片上传。评论是 **楼层式** 的,可回复、引用、@。
+
+帖子可点赞、收藏;公开主页可展示你的资料与动态。
+
+### 个人入口
+
+头像菜单常见项:个人主页、账号设置、站内私信、我的收藏。
+
+### 管理后台(仅管理员)
+
+访问 `/admin`:板块、帖子、评论、举报、用户、媒体、系统设置,以及备份等。
+
+| 改什么 | 去哪里 |
+| --- | --- |
+| 端口、数据目录、JWT | 服务器上的 `app.ini`(改后重启) |
+| 品牌、OIDC、邮件、对象存储、限流、敏感词等 | 后台「系统设置」(保存即生效) |
+
+逛完板块,发第一帖或回一楼——聊起来就对了。
+
+---
+
+## 三、功能速览
+
+功能刻意收在「小圈子真正用得到」的范围内。
+
+### 浏览与发帖
+
+- 三栏布局,桌面 / 移动自适应
+- Feed 排序与虚拟滚动
+- 浅色 / 暗色主题;板块图标与主题色可配
+- TipTap 富文本、标签、正文图片
+- 楼层评论:回复、引用、@
+- 点赞、收藏;置顶 / 精华
+- 编辑修订历史(可对比差异)
+- 可配置普通用户的编辑时限
+
+### 社交与个人
+
+- 公开用户主页
+- 会话式站内私信
+- 昵称、签名、头像等资料
+
+### 管理后台
+
+与前台同一套 React 体验,统一在 `/admin`:
+
+| 模块 | 能力 |
+| --- | --- |
+| 仪表盘 | 站点概览 |
+| 板块 | 创建、编辑、排序、外观 |
+| 帖子 | 审核、置顶、精华、锁定、回收站 |
+| 评论 / 举报 | 审核与处理 |
+| 用户 | 禁言等 |
+| 媒体 | 查看与清理上传 |
+| 设置 | 品牌、限流、敏感词、邮件、OIDC、存储等 |
+| 备份 | SQLite 一键备份 |
+
+### 可选能力
+
+按需在后台开启,不是装完就必须用:
+
+- 邮件验证码注册
+- OIDC Provider(可作 Gitea 等登录源)
+- Gitea 公开仓库同步到「开源码桶」
+- 本地磁盘或 S3 兼容对象存储
+
+### 权限
+
+只有两种角色:**普通用户** / **管理员**。
+第一个注册用户即管理员。小圈子够用,不堆角色矩阵。
+
+项目仍在积极开发。完整规划见仓库 `ROADMAP.md`,欢迎反馈与共建。
+
+---
+
+## 四、为什么是单文件部署
+
+最硬核的一点,是部署路径极短——不是「理论上能打包」,而是日常用法就是:
+
+1. 编译得到一个二进制
+2. 放到目录里运行
+3. 自动生成 `app.ini`
+4. 浏览器注册,第一个账号即管理员
+
+### 它补哪块空缺
+
+论坛方案常落在两端:很重(功能全、运维贵),或很碎(聊天 / 文档方便,却缺少发帖沉淀)。
+小圈子往往需要中间态:有论坛结构、界面顺手、一个人能装、备份好懂。单文件部署,就是为后两点服务的。
+
+### 具体意味着什么
+
+| 能力 | 说明 |
+| --- | --- |
+| 单二进制 | 前端已内嵌,不必单独部署前端目录 |
+| 内置 SQLite | 零外部数据库,数据在本地目录 |
+| 精简 `app.ini` | 主要管端口、数据目录、JWT |
+| 后台热配置 | OIDC、邮件、存储、品牌等保存即生效 |
+| 系统服务 | 内置 Linux systemd / Windows Service |
+| 跨平台 | Windows / Linux / macOS 均可编译运行 |
+
+备份也直观:数据库、上传、配置结构清晰,拷贝即可留存。
+
+进程级项改 `app.ini` 后重启;业务项在管理后台改。既保留「改文件控进程」的可控性,又避免把所有开关塞进配置文件。
+
+---
+
+## 写在最后
+
+**姜十三论坛** = 小圈子该有的论坛能力 × 清新界面 × 真正能单文件带走的部署。
+
+源码与说明见项目仓库。许可证:MIT。
+
+有问题可联系管理员。祝你在这里聊得愉快。
diff --git a/docs/site-posts/community-guidelines.md b/docs/site-posts/community-guidelines.md
new file mode 100644
index 0000000..28dd27c
--- /dev/null
+++ b/docs/site-posts/community-guidelines.md
@@ -0,0 +1,30 @@
+# 本站发帖约定
+
+> 建议标题:本站发帖约定
+> 建议标签:`站务` `公约`
+> 建议操作:普通发布(可选)
+
+---
+
+本站是小圈子论坛,约定尽量少、好遵守。
+
+## 请这样做
+
+- 选对板块再发;不确定就发到综合讨论类板块
+- 标题写清楚在说什么,方便后人搜索
+- 讨论对事不对人;引用、回复尽量指向具体楼层
+- 分享链接时简单说明来源与用途
+
+## 请避免
+
+- 在「站务公告」灌水、闲聊(请到其他板块)
+- 无意义刷屏、重复灌帖
+- 人身攻击、骚扰、泄露他人隐私
+- 明显的广告、引流(除非板块明确允许)
+
+## 管理说明
+
+管理员可能会:移动板块、编辑标题、锁定、删除或禁言。
+有争议可私信管理员说明情况。
+
+一句话:**把讨论留给值得留下的内容。**
diff --git a/docs/site-posts/feedback.md b/docs/site-posts/feedback.md
new file mode 100644
index 0000000..231769d
--- /dev/null
+++ b/docs/site-posts/feedback.md
@@ -0,0 +1,26 @@
+# 反馈与建议
+
+> 建议标题:反馈与建议
+> 建议标签:`站务` `反馈`
+> 建议操作:普通发布(可选)
+
+---
+
+本站程序是开源的 **姜十三论坛**,仍在积极开发。欢迎反馈。
+
+## 站内怎么说
+
+- **功能建议 / 体验吐槽**:开新帖,尽量写清场景与期望
+- **疑似缺陷**:说明步骤、浏览器、是否可复现;有截图更好
+- **站务问题**(注册、权限、内容处理):私信管理员
+
+## 开发仓库(可选)
+
+若你也参与程序本身:
+
+- 查路线图、提 Issue / PR:见项目仓库
+- 许可证:MIT
+
+站内讨论与仓库 Issue 不必重复提交;选一处说清楚即可。
+
+感谢一起把小圈子聊好。
diff --git a/docs/site-posts/optional.md b/docs/site-posts/optional.md
new file mode 100644
index 0000000..78ac0f1
--- /dev/null
+++ b/docs/site-posts/optional.md
@@ -0,0 +1,10 @@
+# 可选短文(不与介绍长文重复)
+
+长文 [`about-jiang13.md`](./about-jiang13.md) 置顶后,原先分篇的「上手 / 功能 / 部署」建议 **直接删除**。
+
+若希望「站务公告」里还有几篇配套短帖,可用下面两篇(按需发,不必全发)。
+
+| 文件 | 标题 | 标签 | 说明 |
+| --- | --- | --- | --- |
+| [community-guidelines.md](./community-guidelines.md) | 本站发帖约定 | `站务` `公约` | 轻量规则,避免灌水 |
+| [feedback.md](./feedback.md) | 反馈与建议 | `站务` `反馈` | 引导提问题、提想法 |
diff --git a/embed_static/embed.go b/embed_static/embed.go
index 5a0501c..aad0da8 100644
--- a/embed_static/embed.go
+++ b/embed_static/embed.go
@@ -32,7 +32,12 @@ func SetSPABrandingJSON(fn func() []byte) {
// SetupEmbed 配置内嵌资源:React SPA 静态资源
func SetupEmbed(r *gin.Engine) error {
if sub, err := fs.Sub(staticFS, "static/spa/assets"); err == nil {
- r.GET("/assets/*filepath", gin.WrapH(http.StripPrefix("/assets", http.FileServer(http.FS(sub)))))
+ fileServer := http.StripPrefix("/assets", http.FileServer(http.FS(sub)))
+ r.GET("/assets/*filepath", func(c *gin.Context) {
+ // hashed 资源可长期缓存;发版后文件名变更,旧 URL 自然 404
+ c.Header("Cache-Control", "public, max-age=31536000, immutable")
+ fileServer.ServeHTTP(c.Writer, c.Request)
+ })
}
return nil
}
diff --git a/embed_static/spa_meta.go b/embed_static/spa_meta.go
index c534ac9..a682aa3 100644
--- a/embed_static/spa_meta.go
+++ b/embed_static/spa_meta.go
@@ -37,6 +37,8 @@ func ServeSPAWithMeta(c *gin.Context, meta *SPAPageMeta) {
return
}
data = applySPAPageMeta(data, meta)
+ // 入口 HTML 禁止长期缓存,否则发版后仍引用旧 chunk 哈希
+ c.Header("Cache-Control", "no-cache")
c.Data(status, "text/html; charset=utf-8", data)
}
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index d1f4904..48dfd68 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,4 +1,4 @@
-import { lazy, Suspense } from 'react';
+import { Suspense } from 'react';
import {
createBrowserRouter,
createRoutesFromElements,
@@ -12,33 +12,36 @@ import { ThemeProvider } from './hooks/useTheme';
import MainLayout from './layouts/MainLayout';
import AdminLayout from './layouts/AdminLayout';
import ErrorBoundary from './components/ErrorBoundary';
+import AppRouteError from './components/AppRouteError';
import PageLoader from './components/PageLoader';
import AuthPageFallback from './components/AuthPageFallback';
import { Toaster } from './components/ui/sonner';
+import PullToRefresh from './components/PullToRefresh';
+import { lazyWithRetry } from './utils/lazyWithRetry';
-const HomePage = lazy(() => import('./pages/HomePage'));
-const PostDetailPage = lazy(() => import('./pages/PostDetailPage'));
-const LoginPage = lazy(() => import('./pages/LoginPage'));
-const RegisterPage = lazy(() => import('./pages/RegisterPage'));
-const ComposePage = lazy(() => import('./pages/ComposePage'));
-const BoardsManagePage = lazy(() => import('./pages/BoardsManagePage'));
-const ProfilePage = lazy(() => import('./pages/ProfilePage'));
-const UserProfilePage = lazy(() => import('./pages/UserProfilePage'));
-const FavoritesPage = lazy(() => import('./pages/FavoritesPage'));
-const MessagesPage = lazy(() => import('./pages/MessagesPage'));
-const ProjectsPage = lazy(() => import('./pages/ProjectsPage'));
-const AdminDashboardPage = lazy(() => import('./pages/admin/AdminDashboardPage'));
-const AdminPostsPage = lazy(() => import('./pages/admin/AdminPostsPage'));
-const AdminCommentsPage = lazy(() => import('./pages/admin/AdminCommentsPage'));
-const AdminReportsPage = lazy(() => import('./pages/admin/AdminReportsPage'));
-const AdminUsersPage = lazy(() => import('./pages/admin/AdminUsersPage'));
-const AdminMediaPage = lazy(() => import('./pages/admin/AdminMediaPage'));
-const AdminSettingsPage = lazy(() => import('./pages/admin/AdminSettingsPage'));
-const NotFoundPage = lazy(() => import('./pages/NotFoundPage'));
+const HomePage = lazyWithRetry(() => import('./pages/HomePage'));
+const PostDetailPage = lazyWithRetry(() => import('./pages/PostDetailPage'));
+const LoginPage = lazyWithRetry(() => import('./pages/LoginPage'));
+const RegisterPage = lazyWithRetry(() => import('./pages/RegisterPage'));
+const ComposePage = lazyWithRetry(() => import('./pages/ComposePage'));
+const BoardsManagePage = lazyWithRetry(() => import('./pages/BoardsManagePage'));
+const ProfilePage = lazyWithRetry(() => import('./pages/ProfilePage'));
+const UserProfilePage = lazyWithRetry(() => import('./pages/UserProfilePage'));
+const FavoritesPage = lazyWithRetry(() => import('./pages/FavoritesPage'));
+const MessagesPage = lazyWithRetry(() => import('./pages/MessagesPage'));
+const ProjectsPage = lazyWithRetry(() => import('./pages/ProjectsPage'));
+const AdminDashboardPage = lazyWithRetry(() => import('./pages/admin/AdminDashboardPage'));
+const AdminPostsPage = lazyWithRetry(() => import('./pages/admin/AdminPostsPage'));
+const AdminCommentsPage = lazyWithRetry(() => import('./pages/admin/AdminCommentsPage'));
+const AdminReportsPage = lazyWithRetry(() => import('./pages/admin/AdminReportsPage'));
+const AdminUsersPage = lazyWithRetry(() => import('./pages/admin/AdminUsersPage'));
+const AdminMediaPage = lazyWithRetry(() => import('./pages/admin/AdminMediaPage'));
+const AdminSettingsPage = lazyWithRetry(() => import('./pages/admin/AdminSettingsPage'));
+const NotFoundPage = lazyWithRetry(() => import('./pages/NotFoundPage'));
const router = createBrowserRouter(
createRoutesFromElements(
- <>
+
检测到程序已更新,正在自动刷新以加载最新版本…
+{errorMessage(error)}
+检测到程序已更新,正在自动刷新以加载最新版本…
+