# 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 文件。推荐在后台「系统设置」页面直接配置。 ## 本地启动 ```bash # 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 标识,自动生成最终推广链接。 ### 工作流程 1. **录入产品时**填写基础购买链接(`buy_url`)和你的 aff 值(`aff_code`) 2. 系统自动生成最终 aff 链接:`buy_url` + `aff_param=aff_code` 3. 生成的链接会自动出现在产品管理页和 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 连接(发送测试消息到指定频道) ## 推送链接优先级 补货推送时,系统按以下优先级选择链接: 1. **产品生成的 Aff 链接**(`products.generated_aff_url`,由 buy_url + aff_code 自动生成) 2. **Aff 链接表**(`aff_links` 表中的链接,支持手工添加或批量生成) 3. **产品的 buy_url**(原始购买链接) 4. **产品的 url**(产品页链接) 在产品编辑页可以看到"推送用的 Aff 链接",明确标识哪个链接会被用于推送。 ## 后台功能 访问 `/admin/login` 登录后进入管理后台: - 仪表盘、商家/产品/Aff 链接/频道/任务的增删改 - 产品支持完整编辑(名称、价格、地区、配置、流量、优惠码、检测模式等) - 产品可设置"前台展示"、"推荐"、"排序值"来控制前台展示 ## 手动执行检测 ### Web 界面 后台「监控任务」页面,点击任务行的 **▶ 执行** 按钮。 ### CLI ```bash npm run task:list # 列出所有任务 npm run task:run -- 1 # 执行指定任务 npm run task:run-all # 执行所有启用的任务 ``` ### API ```bash curl -X POST http://localhost:3900/admin/tasks/api/1/run ``` ## 部署到 Debian 13 服务器 ```bash # 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 链接、频道、任务)