feat: 管理端板块管理与旧版数据导入,补充部署运营文档
- 新增管理端板块管理页面与后端接口(admin_board) - 新增旧版数据导入:legacyimport 服务、导入面板、importusers 命令行工具 - 聊天用户卡片、板块图标等 UI 组件与界面优化 - 补充 about/公告/1Panel 部署等文档 - gitignore 排除 dist/ 构建产物与 .agents/ 本地工具目录
This commit is contained in:
66
docs/about.md
Normal file
66
docs/about.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 姜十三论坛 介绍
|
||||
|
||||
## 这是什么
|
||||
|
||||
**姜十三论坛(jiang13-bbs)** 是一个现代化的社区论坛系统,致力于提供流畅、安全、高质量的在线讨论体验。它面向需要自建社区的个人与团队,开箱即用,同时具备完整的内容、互动、通知与管理能力。
|
||||
|
||||
## 核心特性
|
||||
|
||||
### 📝 内容创作与讨论
|
||||
- **发帖 / 编辑 / 删除**:支持普通帖与问答帖两种类型,作者与管理员均可管理。
|
||||
- **Markdown 渲染**:完整支持 Markdown 语法,包含代码高亮、引用、列表等,技术内容排版美观。
|
||||
- **楼层化评论**:主评论占楼层、子评论不占楼层,最多 10 层嵌套,讨论层次分明。
|
||||
- **点赞互动**:帖子点赞带防重复机制,让优质内容被看见。
|
||||
- **置顶与推荐**:管理员可对帖子进行置顶、推荐,引导社区焦点。
|
||||
|
||||
### 🔔 实时通知
|
||||
- 评论、回复、点赞等互动实时推送,未读红点随页面首屏直出。
|
||||
- 基于 WebSocket 的实时通道,回前台自动校准,消息不遗漏。
|
||||
- 支持单条 / 全部标记已读。
|
||||
|
||||
### 👤 会员体系
|
||||
- 注册即登录,免二次跳转。
|
||||
- 个人资料:昵称、头像、邮箱、个性签名自由编辑。
|
||||
- 每日签到获取积分,连续签到有加成。
|
||||
- 个人主页聚合你的发帖、评论与签到记录。
|
||||
|
||||
### 🛠️ 管理后台
|
||||
- 仪表盘总览社区数据。
|
||||
- 公告管理:支持草稿与发布,标签预设色,重要信息精准触达。
|
||||
- 用户、内容、设置等全方位管理能力。
|
||||
|
||||
### 🔍 SEO 友好
|
||||
- 全站 SSR / ISR,搜索引擎可见的关键内容都在初始 HTML 中。
|
||||
- 帖子详情输出结构化数据(JSON-LD),利于搜索收录与展示。
|
||||
- 自动生成 sitemap 与 robots。
|
||||
|
||||
### 🔒 安全可靠
|
||||
- HttpOnly Cookie + Refresh Token 一次性轮转认证,令牌不落地浏览器存储。
|
||||
- CSRF 双提交防护、速率限制(登录 / 注册 / 发帖冷静期)。
|
||||
- 完备的安全响应头(CSP / HSTS 等)。
|
||||
- 生产环境强制 HTTPS,使用 `__Host-` 前缀 Cookie。
|
||||
|
||||
## 技术架构
|
||||
|
||||
| 层级 | 技术选型 |
|
||||
|------|----------|
|
||||
| 后端 | Go 1.27 · Gin · GORM · PostgreSQL 17 |
|
||||
| 前端 | Next.js 16 (App Router) · TypeScript · Tailwind CSS v4 |
|
||||
| 认证 | JWT(HttpOnly Cookie)+ Refresh Token 轮转 + CSRF 双提交 + Token Version 撤销 |
|
||||
| 实时 | WebSocket |
|
||||
| 部署 | Docker(Next SSR + Go + Postgres,反代自备) |
|
||||
|
||||
系统采用前后端分离架构,前端负责服务端渲染与交互,后端负责业务逻辑与数据,二者职责清晰、可独立伸缩。
|
||||
|
||||
## 适用场景
|
||||
|
||||
- 个人 / 团队自建社区、技术论坛
|
||||
- 产品用户交流与反馈社区
|
||||
- 兴趣小组、垂直领域讨论站
|
||||
- 需要高质量 SEO 与安全性的内容社区
|
||||
|
||||
## 许可与联系方式
|
||||
|
||||
本项目为**专有软件**,源码可见但不构成开源授权,未经书面许可不得使用、部署或分发。
|
||||
|
||||
联系方式:aarbbs@88.com
|
||||
37
docs/announcement.md
Normal file
37
docs/announcement.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# 姜十三论坛正式上线公告
|
||||
|
||||
各位社区成员:
|
||||
|
||||
经过一段时间的开发与打磨,**姜十三论坛**今天正式与大家见面了!🎉
|
||||
|
||||
这里是一个全新的社区交流空间,我们希望它能成为一个内容优质、氛围友好、体验流畅的讨论家园。无论你是来分享技术、交流想法,还是结识同好,都欢迎在这里扎根。
|
||||
|
||||
## 本站亮点
|
||||
|
||||
- **极致的阅读体验**:全站服务端渲染(SSR),首屏秒开,关键内容对搜索引擎友好。
|
||||
- **Markdown 原生支持**:发帖、评论全面支持 Markdown,代码高亮、引用、列表一应俱全。
|
||||
- **楼层化评论**:主评论按楼层排列,子评论最多嵌套 10 层,讨论结构清晰不混乱。
|
||||
- **实时通知**:评论、回复、点赞第一时间通过站内通知提醒你,不错过任何互动。
|
||||
- **每日签到**:每天签到领积分,连续签到还有额外加成,记录你与社区的陪伴。
|
||||
- **个人主页**:你的发帖、评论、签到积分一目了然,打造属于你的社区名片。
|
||||
- **问答帖子**:遇到问题可以发问答帖,获得解答后标记「采纳」,让好答案沉淀下来。
|
||||
|
||||
## 给新成员的几句话
|
||||
|
||||
1. **第一个注册的账号将自动成为站长**,欢迎你接手管理、建设这个社区。
|
||||
2. 发帖前建议先浏览各板块,遵守社区氛围,友善讨论、理性表达。
|
||||
3. 遇到任何问题或有建议,欢迎在反馈板块留言,或直接联系管理员。
|
||||
|
||||
## 关于安全与隐私
|
||||
|
||||
- 全站采用 HttpOnly Cookie + Refresh Token 轮转认证,不把令牌存进浏览器本地存储,更安全。
|
||||
- 密码修改、账号异常等操作会及时让旧登录失效,保护你的账号安全。
|
||||
- 生产环境强制 HTTPS,登录凭据加密传输。
|
||||
|
||||
---
|
||||
|
||||
社区的好坏,取决于每一位成员。期待与你一起,把姜十三论坛建设成一个有价值、有温度的地方。
|
||||
|
||||
如有问题或建议,可通过邮件联系:aarbbs@88.com
|
||||
|
||||
—— 姜十三论坛 团队
|
||||
183
docs/deploy-1panel.md
Normal file
183
docs/deploy-1panel.md
Normal file
@@ -0,0 +1,183 @@
|
||||
# 姜十三论坛(jiang13-bbs)Docker 部署教程
|
||||
|
||||
> 前置条件:应用镜像(`jiang13-api`、`jiang13-web`)已推送到你的私有镜像仓库。本教程只讲如何在服务器上用 1Panel 部署、反代与运维。
|
||||
>
|
||||
> 项目架构:Next.js 前端(web)+ Go 后端(api)+ PostgreSQL 17,三者为独立容器。
|
||||
|
||||
---
|
||||
|
||||
## 一、镜像说明
|
||||
|
||||
| 服务 | 镜像 | 来源 |
|
||||
|---|---|---|
|
||||
| api | `<你的用户名>/jiang13-api` | 你的私有仓库 |
|
||||
| web | `<你的用户名>/jiang13-web` | 你的私有仓库 |
|
||||
| postgres | `postgres:17-alpine` | Docker Hub 官方公共镜像,直接拉取 |
|
||||
|
||||
> 安全说明:api / web 镜像为多阶段构建产物,**最终镜像不含源码**,密钥运行时注入,不烤进镜像。部署前请确认这两个仓库在 Docker Hub 上已设为 **Private**。
|
||||
|
||||
---
|
||||
|
||||
## 二、1Panel 部署
|
||||
|
||||
### 1. 配置私有仓库认证(关键)
|
||||
私有镜像必须先认证,否则拉取报 `denied`。
|
||||
|
||||
1Panel 左侧 **容器 → 「仓库」标签 → 创建**:
|
||||
- 仓库地址:`docker.io`
|
||||
- 用户名:你的 Docker Hub 用户名
|
||||
- 密码:Docker Hub 密码或 Access Token(推荐 Token)
|
||||
|
||||
### 2. 用编排一键部署
|
||||
**容器 → 「编排」标签 → 创建编排**,名称 `jiang13`,粘贴以下内容:
|
||||
|
||||
```yaml
|
||||
name: jiang13
|
||||
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:17-alpine
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_USER: jiang13
|
||||
POSTGRES_PASSWORD: 改成你的强密码
|
||||
POSTGRES_DB: jiang13
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U jiang13 -d jiang13"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
|
||||
api:
|
||||
image: <你的用户名>/jiang13-api:0.1.0
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
HTTP_PORT: "3001"
|
||||
DEV_MODE: "false"
|
||||
JIANG13_WORK_PATH: /var/lib/jiang13
|
||||
DATA_DIR: /var/lib/jiang13/data
|
||||
DB_DSN: postgres://jiang13:改成上面同一个密码@postgres:5432/jiang13?sslmode=disable
|
||||
JWT_SECRET: ""
|
||||
SITE_URL: https://改成你的域名
|
||||
SETTINGS_MASTER_KEY: ""
|
||||
volumes:
|
||||
- appdata:/var/lib/jiang13/data
|
||||
|
||||
web:
|
||||
image: <你的用户名>/jiang13-web:0.1.0
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
BACKEND_URL: http://api:3001
|
||||
SITE_URL: https://改成你的域名
|
||||
NODE_ENV: production
|
||||
DEV_MODE: "false"
|
||||
PORT: "3000"
|
||||
HOSTNAME: 0.0.0.0
|
||||
ports:
|
||||
- "13000:3000"
|
||||
|
||||
volumes:
|
||||
pgdata:
|
||||
appdata:
|
||||
```
|
||||
|
||||
**只需改 3 处**:
|
||||
1. `POSTGRES_PASSWORD` 的值
|
||||
2. `DB_DSN` 里的密码(**必须与第 1 处完全一致**)
|
||||
3. 两处 `SITE_URL` 的域名
|
||||
|
||||
保存后,在编排列表点 **▶ 启动**。会自动:拉镜像 → 起 postgres → 健康后起 api → 健康后起 web。
|
||||
|
||||
> 容器名固定为 `postgres` / `api`,因为服务间通过容器名互访(`@postgres:5432`、`http://api:3001`)。
|
||||
|
||||
### 3. 验证启动
|
||||
「容器」标签确认三个容器状态:
|
||||
- postgres Up (healthy)
|
||||
- api Up (healthy) ← 健康才说明连库成功
|
||||
- web Up
|
||||
|
||||
接口检查:
|
||||
```bash
|
||||
curl http://127.0.0.1:13000/healthz # web,返回 ok
|
||||
docker exec jiang13-api-1 wget -qO- http://127.0.0.1:3001/health # api
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、Nginx 反向代理 + HTTPS
|
||||
|
||||
`DEV_MODE=false` 启用了 `__Host-` 前缀 cookie,**必须 HTTPS**。
|
||||
|
||||
1Panel **网站 → 创建网站 → 反向代理**:
|
||||
- 目标地址:`http://127.0.0.1:13000`
|
||||
- 申请并开启 SSL(1Panel 可一键 Let's Encrypt)
|
||||
- 域名 DNS 解析到服务器
|
||||
|
||||
访问 `https://你的域名`,空库下**第一个注册的账号自动成为站长(管理员)**。
|
||||
|
||||
---
|
||||
|
||||
## 四、配置说明
|
||||
|
||||
### 环境变量
|
||||
| 变量 | 说明 | 建议 |
|
||||
|---|---|---|
|
||||
| `POSTGRES_PASSWORD` | 数据库密码 | 强密码,与 DB_DSN 一致 |
|
||||
| `DB_DSN` | 后端连库串 | 密码须与上者一致 |
|
||||
| `JWT_SECRET` | 登录 token 签名密钥 | **留空**,自动生成并持久化到 data/.jwt_secret;自填须 ≥32 字符强随机 |
|
||||
| `SETTINGS_MASTER_KEY` | 加密邮件/S3 凭据(32字节Base64) | **留空**=禁用保存凭据功能;需要时用 `openssl rand -base64 32` 生成 |
|
||||
| `SITE_URL` | 对外公开 origin | 前后端一致,与浏览器地址栏完全相同(含 https、无尾斜杠)。运行时读取,可后改重启生效 |
|
||||
|
||||
> `JWT_SECRET` 与 `SETTINGS_MASTER_KEY` **不要填同一个值**(密钥复用是安全大忌,且两者格式/生命周期不同)。
|
||||
|
||||
### 端口被占用怎么办
|
||||
- 容器内端口(3000/3001)写死不能改;只改映射的**宿主机端口**(冒号左边),如 `"13000:3000"`。
|
||||
- 用 Nginx 反代时 **api 无需暴露端口**(web 通过容器名内部访问)。
|
||||
- 查占用:`ss -tlnp | grep -E ':3000|:3001'`
|
||||
|
||||
### 数据卷
|
||||
- `pgdata`:数据库数据
|
||||
- `appdata`:上传文件 / `.jwt_secret`
|
||||
|
||||
删除编排时**不要勾选删除数据卷**,否则数据丢失。若换过数据库密码,需先删除旧 `pgdata` 卷重建(Postgres 只在空数据目录初始化密码)。
|
||||
|
||||
---
|
||||
|
||||
## 五、更新与运维
|
||||
|
||||
### 更新版本
|
||||
修改编排中镜像的 tag(如 `:0.1.0` → `:0.2.0`),或使用 `:latest` 标签后点「重新拉取镜像」再重启容器:
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
```
|
||||
> `:latest` 不会自动更新,需手动重新拉取才生效;建议同时保留版本号标签以便回滚。
|
||||
|
||||
### 常用命令
|
||||
```bash
|
||||
docker compose ps # 查看状态
|
||||
docker compose logs -f # 看日志
|
||||
docker compose logs api --tail 50
|
||||
docker compose down # 停止(保留数据)
|
||||
docker compose down -v # 停止并清空数据(慎用)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、排障速查
|
||||
|
||||
| 现象 | 原因 | 解决 |
|
||||
|---|---|---|
|
||||
| api 反复 restart,日志 `password authentication failed` | 密码不一致 / pgdata 残留旧密码 | 统一两处密码;删 pgdata 卷重建 |
|
||||
| api 日志 `JWT_SECRET 过弱` | 填了 change-me 或过短 | 留空自动生成,或换 ≥32 字符强随机值 |
|
||||
| 拉私有镜像 `denied` | 未配置仓库认证 | 1Panel 仓库里添加 Docker Hub 凭证 |
|
||||
| web 不启动 | 等不到 api healthy | 先把 api 弄健康(解决上面问题) |
|
||||
| 能打开页面但登录异常 | HTTP 下 __Host- cookie 不生效 | 必须走 HTTPS 反代 |
|
||||
Reference in New Issue
Block a user