ZhuLink 是一个去算法推荐的内容聚合社区平台,灵感来源于 Hacker News。
"在浩瀚的互联网中,信息如同散落的竹叶,繁多而难以捕捉。ZhuLink 意为将这些零散的信息汇聚成一片生机勃勃的竹林。"
- 去算法推荐: 依靠用户共识(投票)挑选有价值的内容,拒绝算法控制
- 时间衰减排序: 采用类似 Hacker News 的
(P-1) / (T+2)^G排名算法 - 竹林美学: 清新护眼的绿色主题设计
- 内容发布: 支持 URL 链接和 Markdown 文本两种发布方式
- 节点分类: 按主题节点组织内容,方便浏览和管理
- 无层级评论: 支持 Markdown 的无层级评论
- 投票系统: 点赞/踩功能,影响内容排名
- 收藏功能: 收藏感兴趣的文章,方便后续查看
- 订阅管理: 订阅和管理 RSS/Atom 源
- 分类组织: 自定义分类管理订阅源
- 定时拉取: 每 30 分钟自动拉取所有订阅源的新文章
- 定时清除: 每天凌晨 2 点自动清除发布时间超过 30 天的文章
- 内容推荐: 一键将优质 RSS 文章推荐到社区
- 订阅限制: 基于用户积分的订阅数量限制(1000+ 积分无限制)
- 内容审核: 使用 LLM (Gemini) 自动审核不适宜内容
- 智能摘要: 为文章生成摘要和关键词
- SEO 优化: 自动生成 meta 描述和结构化数据
- 账号注册: 邮箱注册,密码 Bcrypt 加密
- 邮箱激活: 新用户需要邮箱验证激活账号
- 密码找回: 通过邮箱验证码重置密码
- Google OAuth: 支持 Google 账号登录和绑定
- 积分系统: 完善的积分奖惩系统
- 通知中心: 评论回复、点赞、系统通知等
- 个人主页: 展示用户发布的内容和活动
- 异步发送: 邮件发送异步执行,不阻塞用户操作
- 注册激活: 新用户注册后发送激活邮件
- 密码重置: 忘记密码时发送验证码邮件
- 评论通知: 评论被回复时发送上下文通知邮件
- 可选配置: 未配置 SMTP 时自动禁用邮件功能
- 内容管理: 置顶、移动、删除帖子
- 用户管理: 禁言、封禁用户
- 举报系统: 用户举报 + 管理员审核处理
- 管理员权限: 基于角色的权限控制
- Robots.txt: 搜索引擎爬虫指引
- Sitemap.xml: 动态生成站点地图
- Meta 标签: 完整的 SEO meta 标签
- Open Graph: 社交媒体分享优化
- JSON-LD: 结构化数据支持
- HTMX 交互: 无刷新页面更新,提升交互体验
- Alpine.js: 轻量级前端逻辑处理
- 响应式设计: 适配各种屏幕尺寸
- 竹林主题: 精心设计的绿色护眼配色
- 语言: Go 1.25+
- Web 框架: Gin
- ORM: GORM
- 数据库: PostgreSQL
- Session: Cookie-based sessions
- 认证: Bcrypt + Google OAuth 2.0
- 模板引擎: Go Templates (SSR)
- 交互: HTMX
- 脚本: Alpine.js
- 样式: Tailwind CSS
- Markdown: goldmark (解析) + bluemonday (XSS 过滤)
- RSS: gofeed
- 爬虫: go-readability
- 热重载: Air
- 构建: Makefile
- LLM: Google Gemini API
- OAuth: Google OAuth 2.0
- 邮件: Amazon SES / SMTP
- Go 1.21+
- PostgreSQL
- Node.js & npm (用于构建 Tailwind CSS)
git clone https://github.com/wangtwothree/zhulink.git
cd zhulink复制示例配置文件并修改:
cp .env.example .env编辑 .env 文件,配置以下内容:
# 数据库配置
DATABASE_URL="host=localhost user=postgres password=yourpassword dbname=zhulink port=5432 sslmode=disable TimeZone=Asia/Shanghai"
# 服务器配置
PORT=32919
GIN_MODE=release # debug, release, or test
SESSION_SECRET="your-secret-key-change-me"
# 站点配置
SITE_URL="https://zhulink.vip"
# LLM 配置 (可选)
LLM_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai/"
LLM_MODEL="gemini-1.5-flash"
LLM_TOKEN="your-gemini-api-key"
# Google OAuth 配置 (可选)
GOOGLE_CLIENT_ID="your-google-client-id"
GOOGLE_CLIENT_SECRET="your-google-client-secret"
# SMTP 邮件配置 (可选, 使用 Amazon SES 或其他 SMTP 服务)
SMTP_HOST="email-smtp.us-east-1.amazonaws.com"
SMTP_PORT="587"
SMTP_USER="your-smtp-username"
SMTP_PASS="your-smtp-password"
SMTP_FROM="no-reply@yourdomain.com"# Go 依赖
go mod tidy
# 前端构建工具
npm install -D tailwindcss
# 安装 Air (可选,用于热重载)
go install github.com/air-verse/air@latest使用 Make 命令一键启动:
make dev这会同时启动:
- Air (后端热重载)
- Tailwind CSS (监听模式)
访问: http://localhost:32919
# 1. 配置环境变量
cp .env.example .env
nano .env # 修改必要的配置
# 2. 启动服务
docker-compose up -d
# 3. 查看日志
docker-compose logs -f- ✅ 多阶段构建: 优化镜像体积 (< 30MB)
- ✅ 自动化构建: 自动编译 Go 和压缩 CSS
- ✅ 环境变量映射: 宿主机
.env文件直接映射到容器 - ✅ 健康检查: 自动监控服务状态
- ✅ 安全运行: 非 root 用户运行
编辑 .env 文件,配置数据库连接:
# 使用已有的 PostgreSQL 数据库
DATABASE_URL="host=your-db-host user=your-user password=your-password dbname=zhulink port=5432 sslmode=disable TimeZone=Asia/Shanghai"
# 如果数据库在本地
DATABASE_URL="host=host.docker.internal user=postgres password=postgres dbname=zhulink port=5432 sslmode=disable TimeZone=Asia/Shanghai"# 启动开发数据库
docker-compose -f docker-compose.dev.yml up -d
# 本地运行应用
make dev使用部署脚本可以一键完成代码拉取、构建和部署:
# 首次部署
cp .env.example .env
nano .env # 配置数据库等信息
./deploy.sh
# 后续更新
./deploy.sh # 自动拉取最新代码、构建、部署脚本功能:
- ✅ 自动拉取最新代码
- ✅ 备份当前运行版本
- ✅ 构建 Docker 镜像
- ✅ 健康检查
- ✅ 失败自动回滚
- ✅ 清理旧镜像
详细部署文档: 查看 DOCKER_DEPLOY.md
# 构建二进制文件
make build
# 运行
./tmp/mainzhulink/
├── cmd/
│ └── server/ # 程序入口
│ └── main.go # 主程序,路由注册,模板加载
├── internal/
│ ├── db/ # 数据库连接和初始化
│ ├── handlers/ # HTTP 处理器
│ │ ├── auth.go # 登录/注册
│ │ ├── google_oauth.go # Google OAuth
│ │ ├── story.go # 帖子管理
│ │ ├── vote.go # 投票系统
│ │ ├── bookmark.go # 收藏功能
│ │ ├── user.go # 用户管理
│ │ ├── notification.go # 通知中心
│ │ ├── rss.go # RSS 阅读器
│ │ ├── transplant.go # RSS 推荐到社区
│ │ ├── admin.go # 管理员功能
│ │ ├── seo.go # SEO 相关
│ │ └── ...
│ ├── middleware/ # 中间件
│ │ └── auth.go # 用户认证中间件
│ ├── models/ # GORM 数据模型
│ │ ├── user.go # 用户模型
│ │ ├── post.go # 帖子模型
│ │ ├── comment.go # 评论模型
│ │ ├── vote.go # 投票模型
│ │ ├── bookmark.go # 收藏模型
│ │ ├── notification.go # 通知模型
│ │ ├── feed.go # RSS 订阅模型
│ │ ├── report.go # 举报模型
│ │ └── ...
│ ├── router/ # 路由注册
│ ├── services/ # 业务服务
│ │ ├── ranking.go # 排名算法服务
│ │ ├── points.go # 积分系统
│ │ ├── llm.go # LLM 集成
│ │ ├── rss_fetcher.go # RSS 抓取
│ │ └── crawler.go # 网页爬虫
│ └── utils/ # 工具函数
│ ├── hash.go # 密码加密
│ ├── markdown.go # Markdown 渲染
│ └── ...
├── web/
│ ├── assets/ # 源文件
│ │ └── input.css # Tailwind 输入文件
│ ├── static/ # 静态资源
│ │ ├── css/ # 编译后的 CSS
│ │ └── ...
│ └── templates/ # HTML 模板
│ ├── layouts/ # 布局模板
│ ├── includes/ # 公共组件
│ ├── components/ # 可复用组件
│ └── views/ # 页面视图
│ ├── auth/ # 登录/注册
│ ├── story/ # 帖子相关
│ ├── user/ # 用户页面
│ ├── dashboard/ # 个人中心
│ ├── rss/ # RSS 阅读器
│ ├── admin/ # 管理后台
│ └── ...
├── .env.example # 环境变量示例
├── .air.toml # Air 配置
├── tailwind.config.js # Tailwind 配置
├── Makefile # 构建脚本
└── go.mod # Go 模块定义
# 开发模式 (热重载 + CSS 监听)
make dev
# 生产构建 (Go 二进制 + 压缩 CSS)
make build
# 仅编译 CSS (开发模式,监听)
make css-watch
# 仅编译 CSS (生产模式,压缩)
make css-build
# 安装开发工具
make setup
# 清理构建产物
make clean采用加权对数时间衰减算法,确保新内容有机会展示,同时优质内容能够保持较高排名:
Score = (log₁₀(加权互动值 + 1) × 1000) / (小时数 + 24)^1.5
加权互动值计算:
加权互动值 = 点赞×1.0 + 评论×2.0 + 收藏×3.0 + 浏览×0.05 - 点踩×1.5
关键参数:
- 收藏权重最高(3.0),评论次之(2.0),点赞基础(1.0)
- 浏览权重(0.05),1000 次浏览相当于 50 分互动值
- 时间重力系数 1.5,时间基数 24 小时
- 使用对数平滑避免热门内容垄断首页
- 密码加密: 使用 Bcrypt 加密存储
- XSS 防护: Markdown 内容使用 bluemonday 过滤
- CSRF 防护: Session-based 认证
- SQL 注入防护: GORM 参数化查询
- 内容审核: LLM 自动审核不适宜内容
- 硬删除: 删除数据直接从数据库移除
- 级联删除: 删除帖子时自动删除相关评论、投票等
- 事务处理: 关键操作使用数据库事务保证一致性
- RSS 定时任务:
- 每 30 分钟自动拉取所有订阅源的新文章
- 每天凌晨 2 点自动清除发布时间超过 30 天的文章
- 服务启动时立即执行一次拉取
| 操作 | 积分变化 | 说明 |
|---|---|---|
| 发布帖子 | +1 | 每天前 3 篇有积分 |
| 发布评论 | +1 | 每天前 3 条有积分 |
| 帖子获赞 | +1 | 无限制 |
| 帖子被收藏 | +3 | 无限制 |
| 评论获赞 | +1 | 无限制 |
| 每日签到 | +1 | 30% 概率额外获得 1-3 竹笋 |
| 操作 | 积分变化 |
|---|---|
| 帖子被踩 | -3 |
| 帖子取消收藏 | -3 |
| 删除帖子 | -10 |
| 评论被踩 | -3 |
| 删除评论 | -3 |
| 踩了别人 | -1 |
| 内容违规惩罚 | -1 |
| 竹笋数量 | 订阅配额 |
|---|---|
| < 11 | 3 个订阅 |
| 11 - 50 | 10 个订阅 |
| 51 - 200 | 30 个订阅 |
| 201 - 1000 | 100 个订阅 |
| > 1000 | 无限制 |
积分用途:
- 影响 RSS 订阅数量限制(见上表)
- 展示社区贡献度和声望
- 未来可扩展更多权限和功能
- 普通用户: 发帖、评论、投票、收藏
- 管理员: 所有普通用户权限 + 管理功能
- 置顶/取消置顶帖子
- 移动帖子到其他节点
- 删除任意帖子/评论
- 禁言/封禁用户
- 处理用户举报
使用 Docker Compose 部署是最简单和推荐的方式:
# 配置环境变量
cp .env.production.example .env
nano .env
# 启动服务
docker-compose up -d优势:
- 一键部署,无需手动配置环境
- 自动构建优化的镜像 (< 30MB)
- 使用已有的 PostgreSQL 数据库
- 包含健康检查和自动重启
.env文件直接映射到容器
详见: DOCKER_DEPLOY.md
- PostgreSQL 12+
- 至少 512MB RAM
- Go 1.21+ (编译环境)
- 设置
GIN_MODE=release - 使用强随机
SESSION_SECRET - 配置 HTTPS (推荐使用 Nginx 反向代理)
- 配置数据库连接池
- 设置合适的超时时间
- 使用 Redis 缓存热点数据 (可选)
- 配置 CDN 加速静态资源
- 数据库索引优化
- 启用 Gzip 压缩
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
- 遵循 Go 官方代码规范
- 使用
gofmt格式化代码 - 添加必要的注释
- 编写单元测试
MIT License
- 灵感来源: Hacker News
- 排名算法参考: How Hacker News ranking algorithm works
如有问题或建议,欢迎通过以下方式联系:
- GitHub Issues
ZhuLink - 让优质内容自然浮现 🎋