VPS补货监控 — 商家产品库存监控 + Telegram 推送
前台公开浏览 + 后台登录管理。轻量级库存监控系统,支持自动检测 VPS/独服库存变化并通过 Telegram 推送通知。
架构概览
前台(公开) 后台(需登录)
/ → 首页 /admin → 管理仪表盘
/plans → 产品列表 /admin/merchants → 商家管理
/plans/:slug → 产品详情 /admin/products → 产品管理(含编辑)
/plans/:id → 兼容旧链接 /admin/aff-links → Aff 链接管理
(301→slug) /admin/channels → TG 频道配置
/admin/tasks → 监控任务 & 检测
/admin/settings → 系统设置(TG Token 等)
/admin/login → 登录页
/admin/logout → 退出登录
技术栈
| 组件 | 选型 | 说明 |
|---|---|---|
| 运行时 | Node.js 18+ | 部署到 Debian 13 兼容 |
| Web 框架 | Express 4 | 最省心的 Node 后台框架 |
| 模板引擎 | EJS | 服务端渲染,无需构建步骤 |
| 数据库 | SQLite (better-sqlite3) | 单文件、零配置 |
| 认证 | express-session | 轻量 session 登录 |
| 配置 | dotenv | .env 文件管理 |
项目结构
aff-monitor/
├── db/
│ ├── init.js # 建表 + 种子数据
│ ├── migrate-add-product-fields.js # 迁移 001: 产品扩展字段
│ ├── migrate-002-checker-fields.js # 迁移 002: 检测相关字段
│ ├── migrate-003-public-fields.js # 迁移 003: 前台展示字段
│ ├── migrate-004-pid-slug.js # 迁移 004: PID & Slug 字段
│ ├── migrate-005-aff-code.js # 迁移 005: Aff Code 字段
│ ├── migrate-006-settings.js # 迁移 006: Settings 表 & generated_aff_url
│ └── monitor.sqlite # 数据库文件 (运行后生成)
├── scripts/
│ └── run-task.js # CLI: 手动执行/列出任务
├── src/
│ ├── app.js # Express 入口(含 session + 路由挂载)
│ ├── db.js # 数据库单例
│ ├── routes/
│ │ ├── public.js # 前台公开路由(首页/产品列表/详情)
│ │ ├── auth.js # 登录/登出路由
│ │ ├── admin.js # 后台仪表盘
│ │ ├── merchants.js # 商家 CRUD
│ │ ├── products.js # 产品 CRUD + 编辑
│ │ ├── channels.js # TG 频道 CRUD
│ │ ├── affLinks.js # Aff 链接 CRUD
│ │ ├── tasks.js # 监控任务 + 检测 + 推送 + 调度
│ │ └── settings.js # 系统设置(TG Token 等)
│ ├── utils/
│ │ ├── checker.js # 库存检测器
│ │ ├── telegram.js # Telegram Bot 推送
│ │ ├── taskRunner.js # 任务执行器
│ │ ├── scheduler.js # 轻量调度器
│ │ ├── pushTemplate.js # 推送消息模板
│ │ ├── pidHelper.js # PID & Slug 自动生成/解析
│ │ ├── affHelper.js # Aff 链接解析/生成
│ │ └── settings.js # 系统设置工具(DB优先,.env兜底)
│ ├── views/
│ │ ├── login.ejs # 登录页
│ │ ├── admin/ # 后台模板
│ │ │ ├── index.ejs # 仪表盘
│ │ │ ├── merchants.ejs # 商家管理
│ │ │ ├── products.ejs # 产品管理
│ │ │ ├── product-edit.ejs # 产品编辑
│ │ │ ├── channels.ejs # 频道配置
│ │ │ ├── affLinks.ejs # Aff 链接
│ │ │ ├── tasks.ejs # 监控任务
│ │ │ └── settings.ejs # 系统设置
│ │ ├── public/ # 前台模板
│ │ │ ├── home.ejs # 首页
│ │ │ ├── plans.ejs # 产品列表
│ │ │ ├── detail.ejs # 产品详情
│ │ │ └── 404.ejs # 404 页面
│ │ └── partials/
│ │ ├── admin-header.ejs # 后台导航
│ │ ├── public-header.ejs # 前台导航
│ │ └── footer.ejs # 统一页脚
│ └── public/ # 静态资源
├── .env.example
├── .gitignore
├── package.json
└── README.md
环境变量
| 变量 | 必填 | 默认值 | 说明 |
|---|---|---|---|
PORT |
否 | 3900 |
Web 服务端口 |
DB_PATH |
否 | db/monitor.sqlite |
SQLite 数据库路径 |
ADMIN_USERNAME |
否 | admin |
后台登录用户名 |
ADMIN_PASSWORD |
否 | admin |
后台登录密码 |
SESSION_SECRET |
建议设置 | 内置默认值 | Session 签名密钥,生产环境请换成随机长字符串 |
TG_BOT_TOKEN |
推送时必填 | - | Telegram Bot Token(可在后台「系统设置」页面配置,数据库优先) |
TG_DEFAULT_CHANNEL_ID |
否 | - | 默认推送频道的 chat_id(可在后台「系统设置」页面配置) |
MONITOR_INTERVAL |
否 | 300 |
调度器检测间隔(秒) |
SCHEDULER_ENABLED |
否 | false |
启动时是否自动开启调度器 |
配置优先级:TG_BOT_TOKEN、TG_DEFAULT_CHANNEL_ID、SITE_NAME、SITE_TG_URL 等配置项,优先从数据库
settings表读取,数据库没有则回退到 .env 文件。推荐在后台「系统设置」页面直接配置。
本地启动
# 1. 安装依赖
cd aff-monitor
npm install
# 2. 复制环境变量(首次)
cp .env.example .env
# 编辑 .env,至少设置 ADMIN_PASSWORD 和 SESSION_SECRET
# 3. 初始化数据库 + 运行迁移
npm run db:init
npm run db:migrate
# 4. 启动
npm run dev # 开发模式 (--watch 自动重载)
# 或
npm start # 生产模式
# 5. 打开
# 前台:http://localhost:3900
# 后台:http://localhost:3900/admin/login
前台功能
- 首页
/:Landing Page 风格,Hero 区展示品牌、刷新状态、Telegram 频道入口;产品卡片流展示推荐和最新产品,移动端友好设计 - 产品列表
/plans:按商家、地区筛选,支持关键词搜索 - 产品详情
/plans/:slug:查看产品配置、价格、购买链接、同商家其他产品(也兼容/plans/:id,自动 301 重定向到 slug)
前台只展示 is_public = 1 的产品。
产品 PID & Slug
每个产品有三个标识字段:
| 字段 | 说明 | 示例 |
|---|---|---|
internal_pid |
系统内部编号,自动生成,不可改 | VPS-000001 |
provider_pid |
商家产品 ID,从购买链接自动解析 | 28(来自 pid=28) |
slug |
前台友好 URL,自动生成,可手改 | gomami-hkgpulsemini |
自动解析规则
当用户填写购买链接(buy_url)时,系统自动从 URL 中解析 provider_pid:
- 高优先级参数:
pid、product、product_id、plan、plan_id、package、package_id - 谨慎参数:
id(仅当 URL 路径含 product/plan/cart/aff/billing 等关键词时才识别) - 路径模式:
/product/28、/plan/28
示例:https://console.po0.com/aff.php?aff=5&pid=28 → provider_pid = 28
Aff 链接自动生成
系统支持用户设置自己的 aff 标识,自动生成最终推广链接。
工作流程
- 录入产品时填写基础购买链接(
buy_url)和你的 aff 值(aff_code) - 系统自动生成最终 aff 链接:
buy_url+aff_param=aff_code - 生成的链接会自动出现在产品管理页和 Aff 链接页
三种使用方式
| 方式 | 操作 | 效果 |
|---|---|---|
| 直接粘贴 aff 链接 | buy_url 填 https://example.com/aff.php?aff=5&pid=28 |
自动识别 aff_code=5,provider_pid=28 |
| 分开填写 | buy_url 填干净链接,aff 值填 5 |
自动生成完整 aff 链接 |
| 批量生成 | 在 Aff 链接页点"批量生成" | 为所有有 aff_code 但没有 aff_link 的产品一键生成 |
字段说明
| 字段 | 说明 | 示例 |
|---|---|---|
aff_code |
你的 aff 标识值 | 5 |
aff_param |
aff 参数名(默认 aff) |
aff、ref、affiliate |
支持识别的 aff 参数名:aff、affid、aff_id、ref、refid、ref_id、referral、partner、affiliate
系统设置(后台)
访问 /admin/settings 可在网页中配置:
- TG_BOT_TOKEN:Telegram Bot Token(用于推送消息)
- TG_DEFAULT_CHANNEL_ID:默认推送频道 ID
- SITE_NAME:站点名称
- DEFAULT_AFF_CODE:新产品默认 aff 值
配置保存到数据库 settings 表,优先级高于 .env 文件。页面支持:
- 保存配置
- 测试 Telegram 连接(发送测试消息到指定频道)
推送链接优先级
补货推送时,系统按以下优先级选择链接:
- 产品生成的 Aff 链接(
products.generated_aff_url,由 buy_url + aff_code 自动生成) - Aff 链接表(
aff_links表中的链接,支持手工添加或批量生成) - 产品的 buy_url(原始购买链接)
- 产品的 url(产品页链接)
在产品编辑页可以看到"推送用的 Aff 链接",明确标识哪个链接会被用于推送。
后台功能
访问 /admin/login 登录后进入管理后台:
- 仪表盘、商家/产品/Aff 链接/频道/任务的增删改
- 产品支持完整编辑(名称、价格、地区、配置、流量、优惠码、检测模式等)
- 产品可设置"前台展示"、"推荐"、"排序值"来控制前台展示
手动执行检测
Web 界面
后台「监控任务」页面,点击任务行的 ▶ 执行 按钮。
CLI
npm run task:list # 列出所有任务
npm run task:run -- 1 # 执行指定任务
npm run task:run-all # 执行所有启用的任务
API
curl -X POST http://localhost:3900/admin/tasks/api/1/run
部署到 Debian 13 服务器
# 1. 安装 Node.js
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs
# 2. 上传代码
rsync -avz --exclude node_modules --exclude 'db/*.sqlite*' aff-monitor/ root@your-server:~/aff-monitor/
# 3. 服务器上安装 + 初始化
cd ~/aff-monitor
npm install --production
cp .env.example .env
# 编辑 .env:设置 ADMIN_PASSWORD, SESSION_SECRET, TG_BOT_TOKEN 等
npm run db:init
npm run db:migrate
# 4. 用 systemd 管理进程
sudo tee /etc/systemd/system/aff-monitor.service << 'EOF'
[Unit]
Description=VPS补货监控
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/root/aff-monitor
ExecStart=/usr/bin/node src/app.js
Restart=on-failure
RestartSec=5
Environment=NODE_ENV=production
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now aff-monitor
数据表概览
| 表名 | 用途 |
|---|---|
merchants |
商家信息 |
products |
产品 + 检测配置 + 前台展示控制 |
aff_links |
Aff 推广链接 |
tg_channels |
Telegram 频道配置 |
monitor_tasks |
监控任务 |
check_logs |
每次检测的记录 |
settings |
系统配置(TG_BOT_TOKEN 等) |
products 表关键字段
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
internal_pid |
TEXT | 自动生成 | 系统内部编号(VPS-000001) |
provider_pid |
TEXT | 自动解析 | 商家产品 ID |
slug |
TEXT | 自动生成 | 前台友好 URL |
aff_code |
TEXT | 自动解析 | 用户的 aff 标识值 |
aff_param |
TEXT | aff |
aff 参数名 |
generated_aff_url |
TEXT | 自动生成 | 自动生成的 aff 链接(推送优先使用) |
is_public |
INTEGER | 1 | 是否在前台展示 |
is_featured |
INTEGER | 0 | 是否推荐(首页推荐区) |
sort_order |
INTEGER | 100 | 排序值(越小越靠前) |
settings 表
| 字段 | 类型 | 说明 |
|---|---|---|
key |
TEXT | 配置键名(主键) |
value |
TEXT | 配置值 |
updated_at |
TEXT | 更新时间 |
Changelog
v0.5.0
- ✅ 新增后台「系统设置」页面,支持网页配置 TG_BOT_TOKEN / TG_DEFAULT_CHANNEL_ID / SITE_NAME
- ✅ 配置优先级:数据库优先,.env 兜底
- ✅ 设置页支持测试 Telegram 连接
- ✅ 产品表新增
generated_aff_url字段,缓存自动生成的 aff 链接 - ✅ 产品编辑页显示"推送用的 Aff 链接",明确标识推送时使用哪个链接
- ✅ 推送链接优先级:generated_aff_url → aff_links 表 → buy_url → url
- ✅ Aff 链接页显示链接来源(系统生成/手工添加)
v0.4.0
- ✅ 新增 internal_pid(系统内部编号,自动生成 VPS-000001)
- ✅ 新增 provider_pid(商家产品 ID,从购买链接自动解析)
- ✅ 新增 slug(前台友好 URL,自动生成)
- ✅ 前台详情路由支持
/plans/:slug,旧数字 ID 自动 301 重定向 - ✅ 后台产品表单增加 PID/Slug 字段展示与编辑
- ✅ 购买链接输入时实时解析 provider_pid(前端 AJAX)
- ✅ 迁移脚本自动回填已有产品的三个字段
- ✅ 新增 aff_code / aff_param 字段,支持设置用户自己的 aff 标识
- ✅ 购买链接粘贴时自动识别 aff 参数(aff/ref/affiliate 等)
- ✅ 基础购买链接 + aff 值 → 自动生成最终 aff 推广链接
- ✅ Aff 链接页支持批量为所有有 aff_code 的产品一键生成
- ✅ 产品列表展示 aff 状态和生成的链接
- ✅ 前端实时预览生成的 aff 链接
v0.3.0
- ✅ 新增前台公开页面(首页、产品列表、产品详情)
- ✅ 后台登录保护(express-session + .env 账号密码)
- ✅ 后台路由统一移到 /admin 前缀
- ✅ 产品编辑功能
- ✅ 新增 is_public / is_featured / sort_order 字段
- ✅ 前后台导航分离
v0.2.0
- 库存检测(HTTP + 关键词匹配)
- Telegram 推送
- 定时调度器
- 推送文案模板
v0.1.0
- 基础 CRUD(商家、产品、Aff 链接、频道、任务)