feat: 代码片段功能与 Markdown 内嵌片段渲染、文档截图等
This commit is contained in:
422
README.md
422
README.md
@@ -1,101 +1,128 @@
|
||||
<div align="center">
|
||||
|
||||
# 姜十三论坛(jiang13-bbs)
|
||||
|
||||
一个基于 Go + Next.js 的现代社区论坛系统,采用 SSR 直出 + HttpOnly Cookie 认证方案,具备完整的帖子/评论/通知/签到/管理后台功能。
|
||||
一个基于 **Go + Next.js** 构建的现代化社区论坛系统,SSR 直出、HttpOnly Cookie 认证,内置内容社区、代码片段、书库、积分体系、实时群聊与完整管理后台,开箱即用。
|
||||
|
||||
> **许可声明:** 本项目为专有软件(Proprietary),源码可见但不构成开源授权。详见 [LICENSE](./LICENSE)。未经书面许可,不得使用、部署或分发。
|
||||
[](./LICENSE)
|
||||
[](./VERSION)
|
||||
[](https://go.dev/)
|
||||
[](https://nextjs.org/)
|
||||
[](#贡献指南)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
- [项目截图](#项目截图)
|
||||
- [功能特性](#功能特性)
|
||||
- [技术栈](#技术栈)
|
||||
- [快速开始](#快速开始)
|
||||
- [配置说明](#配置说明)
|
||||
- [Docker 部署](#docker-部署)
|
||||
- [项目结构](#项目结构)
|
||||
- [安全设计](#安全设计)
|
||||
- [开发与测试](#开发与测试)
|
||||
- [更新日志](#更新日志)
|
||||
- [贡献指南](#贡献指南)
|
||||
- [许可证](#许可证)
|
||||
- [联系方式](#联系方式)
|
||||
- [赞赏支持](#赞赏支持)
|
||||
|
||||
---
|
||||
|
||||
## 项目截图
|
||||
|
||||
| 首页信息流 | 帖子详情 |
|
||||
| :---: | :---: |
|
||||
|  |  |
|
||||
| 代码片段广场 | 书库在线阅读 |
|
||||
|  |  |
|
||||
| 管理后台仪表盘 | 访问统计分析 |
|
||||
|  |  |
|
||||
|
||||
<!--
|
||||
后台设置类截图(邮件 / 过滤 / 维护 / 安全 / 存储,含移动端与暗色模式):
|
||||
docs/screenshots/settings/
|
||||
-->
|
||||
|
||||
---
|
||||
|
||||
## 功能特性
|
||||
|
||||
### 内容社区
|
||||
|
||||
- 帖子发布 / 编辑 / 删除,支持普通帖、**问答帖**(采纳答案、状态流转)、**投票帖**、**悬赏帖**、**抽奖帖**,以及密码帖与付费解锁内容
|
||||
- Markdown 写作与渲染:Shiki 代码高亮、目录导航、图片灯箱、视频/附件
|
||||
- 楼层化评论:主评论占楼层、子评论不占楼层,最多 10 层嵌套,单次查询拼装评论树,无 N+1
|
||||
- 评论与帖子均提供**编辑历史**、软删除与回收站(恢复 / 彻底删除)
|
||||
- 点赞、收藏、关注、置顶、推荐、锁定,联合唯一索引防止重复互动
|
||||
- 附件可设定积分价格,支持付费下载
|
||||
|
||||
### 积分与成长体系
|
||||
|
||||
- 每日签到 + 连续签到加成,积分余额与完整流水台账
|
||||
- 用户等级体系(经验值自动升级)与成就徽章(手动授予 / 自动通知)
|
||||
- 全站积分排行榜与个人排名
|
||||
|
||||
### 代码片段
|
||||
|
||||
- 独立的代码片段广场:多语言语法高亮、按语言筛选、全站统计
|
||||
- Fork、一键复制计数、片段评论、版本历史、可见性管理
|
||||
|
||||
### 书库 / 文档中心
|
||||
|
||||
- 书籍文档管理,两级章节(章 → 节)结构
|
||||
- 支持 **EPUB 解析导入**、Markdown 单篇 / 批量导入、整库导出与单本导出
|
||||
- 内置在线阅读器,封面、附件下载一应俱全
|
||||
|
||||
### 私信与群聊
|
||||
|
||||
- 一对一私信、多人群聊房间、默认全站大厅
|
||||
- 群成员管理:邀请 / 移出、禁言、角色设置;消息撤回、未读汇总、会话置顶
|
||||
|
||||
### 实时通知
|
||||
|
||||
- 评论、回复、点赞、@、系统通知等多类型站内消息
|
||||
- 未读红点 **SSR 首屏直出**,WebSocket 实时推送,页面回到前台时 HTTP 校准,支持单条 / 全部已读
|
||||
|
||||
### 管理后台
|
||||
|
||||
- 仪表盘与分析概览(Recharts 图表)
|
||||
- 内容审核队列(待审帖子 / 评论,板块管理员仅见授权板块)与内容回收站
|
||||
- 板块管理、版主授权、排序
|
||||
- 用户管理:角色、细粒度权限码、封禁、消息权限、登录日志、登录设备、积分调整
|
||||
- 公告文章、站点单页(CMS)管理
|
||||
- 广告位与赞助商配置(含用户自助购买提交、二维码、验证码)
|
||||
- 友情链接:用户申请、后台审批
|
||||
- 侧边栏可视化布局配置 + 自定义 HTML 小部件
|
||||
- 背景图、品牌 Logo 上传裁剪;全站媒体库盘点
|
||||
- **访问统计**:概览、实时、来源、页面、访客、安全、事件等多维度分析
|
||||
- 旧站数据导入(WordPress / Typecho 等)
|
||||
- 更新时间线:从 Git Commits / Releases 自动生成更新日志
|
||||
- 维护模式、系统诊断、SMTP 邮件配置(凭据加密存储)
|
||||
- 支持 S3 / MinIO 对象存储:文件内容去重、自适应图片变体、WebP 自动转换
|
||||
|
||||
### SEO
|
||||
|
||||
- 全站 SSR / ISR,title、description、OG 等关键内容均在初始 HTML 中
|
||||
- 帖子详情页输出 `DiscussionForumPosting` 类型 JSON-LD
|
||||
- 动态 `sitemap`、`robots`、Canonical 链接
|
||||
|
||||
---
|
||||
|
||||
## 技术栈
|
||||
|
||||
| 层级 | 技术 |
|
||||
|------|------|
|
||||
| 层级 | 技术选型 |
|
||||
|------|----------|
|
||||
| 后端 | Go 1.27 · Gin · GORM · PostgreSQL 17 |
|
||||
| 前端 | Next.js 16 (App Router) · TypeScript · Tailwind CSS v4 |
|
||||
| 认证 | JWT (HttpOnly Cookie) + Refresh Token 轮转 + CSRF 双提交 + Token Version 撤销 |
|
||||
| 部署 | 官方:`deploy/` Docker Compose(Next SSR + Go + Postgres,反代自备);本地开发仅 Compose 起数据库 |
|
||||
|
||||
---
|
||||
|
||||
## 功能概览
|
||||
|
||||
### 用户
|
||||
|
||||
- 注册 / 登录 / 登出(注册即登录,免二次跳转)
|
||||
- 个人资料编辑:昵称、头像、邮箱、个性签名
|
||||
- 修改密码(改密后全端踢下线)
|
||||
- 个人主页:发帖列表、评论列表(分页)、签到积分
|
||||
- 每日签到(积分 + 连续签到天数)
|
||||
|
||||
### 内容
|
||||
|
||||
- 帖子发帖 / 编辑 / 删除(作者本人或管理员)
|
||||
- 帖子类型:普通帖 / 问答帖
|
||||
- 帖子置顶 / 推荐(仅管理员)
|
||||
- 评论楼层制:主评论 = 楼层,子评论不占楼层,最多 10 层嵌套
|
||||
- 楼层分页 + 内存拼装评论树(单次查询,无 N+1)
|
||||
- Markdown 渲染(代码高亮、引用、列表等)
|
||||
- 帖子点赞(联合唯一索引防重复)
|
||||
|
||||
### 通知
|
||||
|
||||
- 站内通知:评论你的帖子、回复你的评论、点赞你的帖子
|
||||
- 未读红点 SSR 直出,实时靠 WebSocket 推送,回前台时 HTTP 校准
|
||||
- 单条标记已读 / 全部已读
|
||||
|
||||
### 管理后台
|
||||
|
||||
- 公告管理(草稿 / 发布、标签预设色)
|
||||
- 仪表盘
|
||||
|
||||
### SEO
|
||||
|
||||
- 全站 SSR/ISR,SEO 关键内容在初始 HTML 中
|
||||
- 帖子详情页输出 `DiscussionForumPosting` 类型 JSON-LD
|
||||
- 动态 `sitemap.ts` + `robots.ts`(由 Next.js 对外提供,后端不重复挂 `/sitemap.xml` / `/robots.txt`)
|
||||
|
||||
### 安全
|
||||
|
||||
- CSP / HSTS / X-Frame-Options: DENY / X-Content-Type-Options / Referrer-Policy
|
||||
- 速率限制:登录 20/min、注册 10/min、发帖新用户 24h 冷静期
|
||||
- Refresh Token 一次性轮转 + 盗用检测(吊销后重放 → 杀全家族)
|
||||
- 生产 HTTPS 启用 `__Host-` Cookie 前缀
|
||||
|
||||
---
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
jiang13-bbs/
|
||||
├── backend/ # Go 后端
|
||||
│ ├── cmd/jiang13/ # 入口 main.go
|
||||
│ ├── config/ # 配置解析(app.ini + 环境变量)
|
||||
│ ├── handler/ # HTTP 处理器
|
||||
│ ├── middleware/ # 认证 / CSRF / 限流 / 安全头
|
||||
│ ├── model/ # GORM 模型 + 数据库初始化
|
||||
│ ├── router/ # 路由注册
|
||||
│ ├── service/ # 业务逻辑层
|
||||
│ ├── app.ini.example # 配置模板
|
||||
│ └── go.mod
|
||||
├── frontend/ # Next.js 前端
|
||||
│ ├── app/ # App Router 页面
|
||||
│ │ ├── settings/ # 账号设置(资料 + 密码)
|
||||
│ │ ├── u/[id]/ # 用户主页
|
||||
│ │ ├── post/[id]/ # 帖子详情
|
||||
│ │ ├── compose/ # 发帖
|
||||
│ │ ├── notifications/ # 通知列表
|
||||
│ │ ├── admin/ # 管理后台
|
||||
│ │ └── ...
|
||||
│ ├── components/ # 复用组件
|
||||
│ ├── lib/ # API 封装 / 工具函数
|
||||
│ ├── middleware.ts # SSR 登录态静默轮转
|
||||
│ ├── next.config.ts # Rewrite 代理 / 图片缓存
|
||||
│ └── .env.example
|
||||
├── deploy/ # 官方运行时(web + api + Postgres,反代自备)
|
||||
├── docker-compose.yml # 仅本地开发 Postgres
|
||||
├── LICENSE # 专有软件许可协议
|
||||
└── .gitignore
|
||||
```
|
||||
| 前端 | Next.js 16(App Router)· React 19 · TypeScript · Tailwind CSS v4 |
|
||||
| 认证 | JWT(HttpOnly Cookie)+ Refresh Token 轮转 + CSRF 双提交 + Token Version 撤销 |
|
||||
| 实时 | WebSocket(gorilla/websocket) |
|
||||
| 存储 | 本地存储 / S3(MinIO),Markdown 引擎 Goldmark,代码高亮 Shiki |
|
||||
| 部署 | Docker Compose:Next SSR + Go API + PostgreSQL(反向代理自备) |
|
||||
|
||||
---
|
||||
|
||||
@@ -104,8 +131,8 @@ jiang13-bbs/
|
||||
### 前置条件
|
||||
|
||||
- Go 1.27+
|
||||
- Node.js 20+ / pnpm 或 npm
|
||||
- PostgreSQL 17(或通过 Docker Compose 启动)
|
||||
- Node.js 20+(npm)
|
||||
- PostgreSQL 17(可通过 Docker Compose 启动)
|
||||
|
||||
### 1. 启动数据库
|
||||
|
||||
@@ -123,9 +150,9 @@ go mod download
|
||||
go run ./cmd/jiang13
|
||||
```
|
||||
|
||||
**工作目录必须是 `backend/`。** 上传文件与 JWT 密钥落在 `backend/data/`(头像 `backend/data/uploads/avatars/`)。不要在仓库根或 `backend/cmd/jiang13/` 执行 `go run`,否则会另建一套 data,数据库里头像 URL 会对不上文件。启动日志应含 `workPath=.../backend` 和 `dataDir=.../backend/data`。需要覆盖时设置 `JIANG13_WORK_PATH` 指向 `backend/`。
|
||||
> **工作目录必须是 `backend/`。** 上传文件与 JWT 密钥落在 `backend/data/`(头像位于 `backend/data/uploads/avatars/`)。在仓库根或 `backend/cmd/jiang13/` 下执行会另建一套 data,导致数据库中的文件 URL 对不上。启动日志应包含 `workPath=.../backend`;需要覆盖时可设置 `JIANG13_WORK_PATH`。
|
||||
|
||||
后端默认监听 `:3001`,首次启动自动执行数据库迁移并写入默认板块。同一时间只跑一个后端进程。
|
||||
后端默认监听 `:3001`,首次启动自动执行数据库迁移并写入默认板块。
|
||||
|
||||
### 3. 启动前端
|
||||
|
||||
@@ -136,13 +163,17 @@ npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
前端默认监听 `:3000`,通过 `next.config.ts` rewrite 将 `/api/*` 代理到后端。
|
||||
前端默认监听 `:3000`,通过 `next.config.ts` 的 rewrite 将 `/api/*` 代理到后端。
|
||||
|
||||
**空数据库首次注册的账号将自动成为站长。**
|
||||
|
||||
> Windows 用户也可直接使用仓库根目录的 `start.bat`(或 `start.sh`)一键启动开发环境,停止使用 `stop.bat` / `stop.sh`。
|
||||
|
||||
---
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 后端(`backend/app.ini`)
|
||||
### 后端 `backend/app.ini`
|
||||
|
||||
```ini
|
||||
[server]
|
||||
@@ -152,108 +183,189 @@ HTTP_PORT = 3001
|
||||
DSN = postgres://postgres:postgres@localhost:5432/jiang13?sslmode=disable
|
||||
|
||||
[security]
|
||||
; 留空则自动生成并持久化到 data/.jwt_secret
|
||||
; 生产环境务必显式指定强随机值
|
||||
; 留空则自动生成并持久化到 data/.jwt_secret;生产环境务必显式指定强随机值
|
||||
JWT_SECRET =
|
||||
; 32 字节随机值的标准 Base64(openssl rand -base64 32),用于加密邮件 / S3 凭据
|
||||
SETTINGS_MASTER_KEY =
|
||||
|
||||
[paths]
|
||||
DATA = data
|
||||
|
||||
[app]
|
||||
DEV_MODE = true
|
||||
SITE_URL = http://localhost:3000
|
||||
CORS_ORIGINS =
|
||||
```
|
||||
|
||||
环境变量优先级高于 app.ini:`HTTP_PORT`、`DB_DSN`、`JWT_SECRET`、`DEV_MODE`。`JIANG13_WORK_PATH` 可强制指定后端根目录(`app.ini` 与 `data/` 所在处)。
|
||||
环境变量优先级高于 `app.ini`:`HTTP_PORT`、`DB_DSN`、`JWT_SECRET`、`SETTINGS_MASTER_KEY`、`DEV_MODE`、`SITE_URL`、`CORS_ORIGINS`、`TRUSTED_PROXIES`。
|
||||
|
||||
### 前端(`frontend/.env.local`)
|
||||
### 前端 `frontend/.env.local`
|
||||
|
||||
```bash
|
||||
# SSR 与 middleware 直连后端(本地开发)
|
||||
# SSR 与 middleware 直连后端
|
||||
NEXT_PUBLIC_API_URL=http://localhost:3001
|
||||
|
||||
# 部署到 Cloudflare Workers 等边缘环境时必须显式配置
|
||||
# 仅服务端可见;生产构建必须显式配置
|
||||
# BACKEND_URL=https://your-backend.example.com
|
||||
|
||||
# 与后端 DEV_MODE 对齐
|
||||
DEV_MODE=true
|
||||
```
|
||||
|
||||
完整环境变量清单见 [.env.example](./.env.example)、[frontend/.env.example](./frontend/.env.example)。
|
||||
|
||||
---
|
||||
|
||||
## Docker 部署
|
||||
|
||||
官方运行时位于 [`deploy/`](./deploy/),一体交付 **Next.js SSR + Go API + PostgreSQL 17**,不含反向代理(TLS 与同源路由由你的 Nginx / Caddy 处理)。
|
||||
|
||||
```bash
|
||||
cd deploy
|
||||
cp .env.example .env
|
||||
# 编辑 .env:POSTGRES_PASSWORD、JWT_SECRET、SITE_URL
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
然后将同一 Host 反向代理到容器:
|
||||
|
||||
- `/` → web `:3000`
|
||||
- `/api/`(含 `/api/ws`)、`/uploads/`、`/health` → api `:3001`
|
||||
|
||||
`GET https://你的域名/health` 返回 `{"status":"ok"}` 即部署成功。
|
||||
|
||||
详细说明、升级与备份命令见 [deploy/README.md](./deploy/README.md),Nginx 配置示例见 [deploy/nginx.example.conf](./deploy/nginx.example.conf),运行时契约见 [deploy/CONTRACT.md](./deploy/CONTRACT.md)。1Panel 面板部署可参考 [docs/deploy-1panel.md](./docs/deploy-1panel.md)。
|
||||
|
||||
---
|
||||
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
jiang13-bbs/
|
||||
├── backend/ # Go 后端
|
||||
│ ├── cmd/jiang13/ # 程序入口
|
||||
│ ├── config/ # 配置解析(app.ini + 环境变量)
|
||||
│ ├── handler/ # HTTP 处理器
|
||||
│ ├── middleware/ # 认证 / CSRF / 限流 / 安全头 / 访问捕获
|
||||
│ ├── model/ # GORM 模型与数据库初始化
|
||||
│ ├── realtime/ # WebSocket Hub
|
||||
│ ├── router/ # 路由注册
|
||||
│ ├── service/ # 业务逻辑层
|
||||
│ ├── markdown/ # Markdown 扩展(隐藏内容等)
|
||||
│ └── app.ini.example
|
||||
├── frontend/ # Next.js 前端
|
||||
│ ├── app/ # App Router 页面(含 admin 后台)
|
||||
│ ├── components/ # 通用组件
|
||||
│ ├── hooks/ # 自定义 Hooks
|
||||
│ ├── lib/ # API 封装与工具函数
|
||||
│ ├── public/ # 静态资源(表情图等)
|
||||
│ ├── middleware.ts # SSR 登录态静默轮转
|
||||
│ └── next.config.ts # Rewrite 代理 / 图片缓存
|
||||
├── deploy/ # 官方运行时(Docker Compose / Dockerfile)
|
||||
├── docs/ # 文档与截图
|
||||
├── docker-compose.yml # 本地开发用(仅 PostgreSQL)
|
||||
├── start.bat / start.sh # 本地一键启动
|
||||
├── VERSION
|
||||
└── LICENSE
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 认证架构
|
||||
## 安全设计
|
||||
|
||||
采用三 Cookie + Token Version 方案,不使用 localStorage 存储 token:
|
||||
采用三 Cookie 方案,令牌不落 localStorage:
|
||||
|
||||
| Cookie | 用途 | 属性 |
|
||||
|--------|------|------|
|
||||
| `j13_token` | Access JWT(15 分钟) | HttpOnly · SameSite=Lax |
|
||||
| `j13_refresh` | Refresh Token(7 天,DB 存储 SHA-256) | HttpOnly · SameSite=Lax · Path=/ |
|
||||
| `j13_refresh` | Refresh Token(7 天,DB 存 SHA-256) | HttpOnly · SameSite=Lax · Path=/ |
|
||||
| `j13_csrf` | CSRF Token(JS 可读) | SameSite=Lax |
|
||||
|
||||
- **SSR 直出登录态:** `middleware.ts` 在页面/RSC 请求前本地解码 access token 的 exp,过期时静默调后端 refresh 轮转,新 cookie 注入请求头供 SSR 使用并透传浏览器。
|
||||
- **客户端续期:** `lib/api.ts` 的 `fetchWithRefresh` 遇到 401 自动调 `/api/auth/refresh` 重试。
|
||||
- **撤销机制:** 改密码 / 封禁 / 管理员强制下线时递增 `User.TokenVersion`,所有旧 JWT 立即失效。
|
||||
- **盗用检测:** Refresh Token 一次性轮转,已吊销 token 重放时撤销该用户全部 refresh token。
|
||||
|
||||
生产 HTTPS 下 cookie 名自动启用 `__Host-` 前缀。
|
||||
|
||||
若本机曾跑过早期构建,浏览器里可能还留着 `Path=/api/auth` 的 `j13_refresh`(HttpOnly,页面脚本删不掉)。打开开发者工具 → Application → Cookies,删掉该条,或对该源执行「清除站点数据」。之后只应存在 `Path=/` 的三枚 cookie。
|
||||
- **SSR 直出登录态**:`middleware.ts` 在渲染前检查 Access Token 过期时间,过期则静默轮转,新 Cookie 同时供 SSR 使用并透传浏览器
|
||||
- **Refresh Token 一次性轮转 + 盗用检测**:已吊销 Token 被重放时,撤销该用户全部 Refresh Token
|
||||
- **Token Version 撤销**:改密 / 封禁 / 强制下线时递增版本号,旧 JWT 立即失效
|
||||
- **速率限制**:登录、注册、发帖(新用户 24h 冷静期)、评论、上传等分级限流,管理员豁免
|
||||
- **安全响应头**:CSP、HSTS、X-Frame-Options: DENY、X-Content-Type-Options、Referrer-Policy
|
||||
- 生产 HTTPS 下 Cookie 自动启用 `__Host-` 前缀,要求前后端必须**同源部署**(不能拆分到子域)
|
||||
|
||||
---
|
||||
|
||||
## 部署
|
||||
|
||||
**官方运行时是 `deploy/docker-compose.yml`(Next SSR + Go + Postgres,不含反代)。** 说明与升级命令见 [deploy/README.md](./deploy/README.md),Nginx 示例见 [deploy/nginx.example.conf](./deploy/nginx.example.conf),契约见 [deploy/CONTRACT.md](./deploy/CONTRACT.md)。
|
||||
|
||||
本地开发仍用仓库根 `start.bat` / `start.sh` 与根目录 `docker-compose.yml`(只起 Postgres)。不要把开发流程改成必须打应用镜像。
|
||||
|
||||
更新应用(镜像已发布时):
|
||||
## 开发与测试
|
||||
|
||||
```bash
|
||||
cd deploy
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
# 后端测试
|
||||
cd backend && go test ./...
|
||||
|
||||
# 前端测试(Node 内置 test runner)
|
||||
cd frontend && npm test
|
||||
|
||||
# 前端代码检查
|
||||
npm run lint
|
||||
```
|
||||
|
||||
后台一键更新、预编译包不在本期。Cloudflare Workers 不是官方运行时。
|
||||
开发约定:
|
||||
|
||||
### 生产环境要点
|
||||
|
||||
1. **官方 Compose:** `DEV_MODE=false`,强随机 `JWT_SECRET` 与 `POSTGRES_PASSWORD`;由你现有的 Nginx/Caddy 提供 HTTPS,并把页面与 `/api`、`/api/ws`、`/uploads` 挂到同一 Host。
|
||||
2. **CORS 与 Canonical:** 设 `SITE_URL` 为对外 origin(不要改 `router.go` 写死域名)。官方 Compose 会同时注入 api 与 web;web 用它生成 Canonical / sitemap,不要填 `http://api:3001`。
|
||||
3. **自管部署:** 仍须同源反代。Workers 前端须保持 `middleware.ts` 文件名(OpenNext 不识别 `proxy.ts`),实时通道由反代承接 `/api/ws`。
|
||||
|
||||
### WebSocket(开发 vs 生产)
|
||||
|
||||
浏览器发起 WebSocket 握手**一定会带 `Origin`**。后端拒绝空 Origin,这只挡住 curl / 脚本探测,**不影响 `npm run dev`,也不影响生产浏览器**。
|
||||
|
||||
**开发环境(`DEV_MODE=true`)**
|
||||
|
||||
- 页面在 `http://localhost:3000`,WS 直连 `ws://localhost:3001/api/ws`(Next.js rewrite 不透传 `Upgrade`)。
|
||||
- 二者端口不同,不是浏览器意义上的同源。后端因此放行 Origin 主机为 `localhost` / `127.0.0.1` 的**任意端口**。
|
||||
- Cookie 不按端口隔离,`:3000` 上的 `j13_token` 会随握手带到 `:3001`。不要把 `DEV_MODE` 改成 `false` 再跑这对端口,否则 Origin `localhost:3000` 对不上 Host `localhost:3001`,握手会被拒。
|
||||
|
||||
**生产环境(`DEV_MODE=false`)**
|
||||
|
||||
- Origin 的 host(含端口)必须与请求 `Host` **完全一致**。请用 Nginx/Caddy 把前端与 `/api/`、`/api/ws` 挂到同一域名,例如 `https://bbs.example.com`。
|
||||
- 反向代理需透传 `Upgrade`、`Connection`,并保留原始 `Host` / `Origin`。
|
||||
- 生产 cookie 使用 `__Host-` 前缀,要求 `Secure`、`Path=/`、**不能设 Domain**。因此 API **不能**放到 `api.example.com` 这类另一子域,否则登录 cookie 与 WS 都会失效。
|
||||
- Cloudflare Workers / OpenNext **不能**透传任意 WebSocket。若前端部署在 Workers,实时通道必须由同源反代(Nginx 等)承接 `/api/ws`,而不是指望 Workers 升级连接。
|
||||
- 可用 `NEXT_PUBLIC_WS_URL` 覆盖前端连线地址;一旦覆盖,Origin 仍须与后端看到的 Host 一致。
|
||||
- Next.js 16 中 `params` / `searchParams` / `cookies()` / `headers()` 均需 `await`
|
||||
- 权限校验只在 Go 后端执行,前端不做判定
|
||||
- 配色仅修改 `frontend/app/globals.css` 中的 CSS 令牌,不在组件内硬编码颜色
|
||||
- 所有公开页面保持 SSR / ISR,SEO 关键内容必须在初始 HTML 中
|
||||
|
||||
---
|
||||
|
||||
## 开发约定
|
||||
## 更新日志
|
||||
|
||||
- **Next.js 16:** `params` / `searchParams` / `cookies()` / `headers()` 必须 `await`。
|
||||
- **SEO:** 所有公开页面 SSR/ISR,SEO 关键内容(title、description、OG、JSON-LD)必须在初始 HTML 中。
|
||||
- **权限:** 权限校验只在 Go 后端执行,前端不做判定。
|
||||
- **配色:** 仅修改 `frontend/app/globals.css` 中的 CSS 令牌,禁止在组件内硬编码颜色。
|
||||
- **无障碍:** 文字对比度 ≥4.5:1,交互控件边界 ≥3:1(WCAG 2.1 AA)。
|
||||
版本发布与部署契约变更记录见 [deploy/CHANGELOG.md](./deploy/CHANGELOG.md),当前版本 **v0.2.9**。
|
||||
|
||||
---
|
||||
|
||||
## 贡献指南
|
||||
|
||||
欢迎提交 Issue 与 Pull Request!
|
||||
|
||||
1. Fork 本仓库并创建特性分支:`git checkout -b feature/your-feature`
|
||||
2. 提交前请确保测试通过:后端 `go test ./...`,前端 `npm test`
|
||||
3. 提交代码并推送分支
|
||||
4. 在 GitHub 上发起 Pull Request,描述清楚改动内容与动机
|
||||
|
||||
- 提交信息建议遵循 [Conventional Commits](https://www.conventionalcommits.org/) 规范(`feat:` / `fix:` / `docs:` 等)
|
||||
- 发现安全问题请**不要**直接提 Issue,发送邮件至 aarbbs@88.com 私下反馈
|
||||
|
||||
---
|
||||
|
||||
## 许可证
|
||||
|
||||
**专有软件(Proprietary)** — Copyright © 2026 姜十三,保留所有权利。
|
||||
本项目基于 [Apache License 2.0](./LICENSE) 开源。
|
||||
|
||||
源码仅可见,未经书面许可不得使用、部署、修改或分发。详见 [LICENSE](./LICENSE)。
|
||||
```
|
||||
Copyright 2026 姜十三
|
||||
|
||||
联系方式:aarbbs@88.com
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 联系方式
|
||||
|
||||
- QQ:97975089
|
||||
|
||||
- 邮箱:97975089@qq.com
|
||||
|
||||
- Issue:[GitHub Issues](https://github.com/aarbbs/jiang13-bbs/issues)
|
||||
|
||||
---
|
||||
|
||||
## 赞赏支持
|
||||
|
||||
如果本项目对你有帮助,欢迎请作者喝杯咖啡 ☕,你的支持是持续维护的动力。
|
||||
|
||||
<p align="center">
|
||||
<img src="docs/images/wechat.png" width="220" alt="微信打赏" />
|
||||
|
||||
<img src="docs/images/zfb.png" width="220" alt="支付宝打赏" />
|
||||
</p>
|
||||
|
||||
<p align="center">微信打赏 | 支付宝打赏</p>
|
||||
|
||||
Reference in New Issue
Block a user