TaoLei2025/12/13开源项目#Subly#订阅管理#Cloudflare Workers#Vue 3#到期提醒
Subly:轻量级订阅管理与提醒系统完全指南
在数字化时代,我们每个人都订阅了大量的服务:域名、服务器、会员、软件许可证……这些订阅的到期时间各不相同,稍不留意就可能错过续费导致服务中断。Subly 正是为解决这一痛点而生的开源工具。
什么是 Subly?
Subly 是一个轻量级的订阅管理与提醒系统,帮助您轻松跟踪各类订阅服务的到期时间,并通过邮件或微信发送及时提醒。它基于现代化的技术栈构建,完全运行在 Cloudflare 的边缘计算平台上,无需传统服务器即可部署。
项目的名称 "Subly" 来源于 "Subscription"(订阅)的缩写,简洁地表达了其核心功能——管理您的所有订阅服务。
为什么选择 Subly?
与传统的订阅管理工具相比,Subly 在以下方面表现突出:
- 零服务器成本:完全运行在 Cloudflare Workers 上,免费额度足够个人使用
- 多渠道提醒:支持邮件(Resend)和微信(Server酱)双通道通知
- 安全可靠:内置两步验证(2FA)、频率限制等安全机制
- 开源免费:Apache License 2.0 协议,可自由使用和修改
核心特性详解
1. 全面的订阅管理
Subly 提供了完整的订阅生命周期管理功能:
订阅类型支持
- 域名:管理您的所有域名续费
- 服务器:VPS、云服务器、托管服务
- 会员:视频网站、音乐平台、云存储等
- 软件:许可证、订阅制软件
- 其他:任何需要定期续费的服务
附件管理
- 支持上传 PDF、DOCX、PNG、JPG 格式文件
- 每个订阅可上传多个附件(如合同、发票、截图等)
- 附件存储在 Cloudflare R2,安全可靠
- 支持在线预览和下载
续费类型标记
- 自动续费:系统会自动扣费续期
- 手动续费:需要您主动操作续费
- 不续费:到期后不再续费
- 永久授权:永久授权,无需续费
状态追踪
系统自动根据到期时间更新订阅状态:
- 活跃(Active):正常使用中
- 即将到期(Expiring):在提醒天数内
- 已过期(Expired):已超过到期日期
- 已停用(Inactive):手动停用的订阅
2. 智能统计概览
首页仪表盘提供直观的数据统计:
核心指标
- 总订阅数:当前管理的所有订阅数量
- 即将到期:在提醒周期内的订阅数量
- 一次性支出:所有买断类订阅的总金额
- 月均支出:订阅类服务的月均成本
统计图表
可折叠的统计图表面板,提供三种可视化分析:
- 月均支出分布:按订阅类型展示月均支出的饼图
- 永久授权:按订阅类型展示永久授权支出的饼图
- 月度支出趋势:近 6 个月的支出柱状图
到期倒计时
首页显示 7 天内即将到期的订阅列表,直观展示:
- 订阅名称和到期日期
- 剩余天数标签(颜色区分紧急程度)
- 今天到期、已过期等状态提示
多币种支持
支持五种主流货币:
- CNY(人民币)
- USD(美元)
- EUR(欧元)
- GBP(英镑)
- HKD(港币)
实时汇率转换
集成 ExchangeRate API,自动获取实时汇率,将所有订阅统一换算为您选择的显示币种。
3. 多渠道到期提醒
Subly 支持两种主流的通知渠道,确保您不会错过任何重要的续费提醒。
邮件通知(Resend)
Resend 是一个现代化的邮件发送服务,提供可靠的邮件投递:
# 配置项
- 通知邮箱:接收提醒的邮箱地址
- API Key:Resend 平台的 API 密钥
- 自定义域名:可选,使用自己的发件域名
- 通知时间:每天发送提醒的时间点(支持多选)
- 邮件模板:自定义邮件标题和内容
微信通知(Server酱)
Server酱是一个简单易用的微信推送服务:
# 配置项
- SendKey:Server酱的 API 密钥
- 通知时间:每天发送提醒的时间点(支持多选)
- 消息模板:自定义消息标题和内容(支持 Markdown)
自定义模板变量
两种通知渠道都支持以下模板变量:
{{count}}:即将到期的订阅数量
{{subscriptions}}:订阅列表(表格格式)
{{time}}:发送时间
{{site_url}}:站点链接
4. 强大的安全机制
Subly 在设计之初就将安全性作为核心考量:
用户认证系统
- JWT Token 认证:安全的无状态身份验证
- 密码加密存储:使用安全的哈希算法
- Token 自动刷新:无感知的会话续期
两步验证(2FA)
支持 TOTP 标准的两步验证:
- 兼容 Google Authenticator、Microsoft Authenticator 等主流验证器
- 可在注册时启用或后续在设置中开启
- 支持备份和恢复 2FA 配置
频率限制防护
多层次的频率限制机制,有效防止暴力破解:
| 限制类型 | 限制规则 | 说明 |
|---|
| IP 短期限制 | 每分钟 10 次 | 防止快速尝试 |
| IP 中期限制 | 每小时 60 次 | 防止持续攻击 |
| IP 长期限制 | 每天 200 次 | 防止分布式攻击 |
| 用户名限制 | 15分钟内 5 次失败 | 防止针对特定账户 |
| 注册限制 | 每小时 3 个账户 | 防止批量注册 |
渐进式账户锁定
登录失败次数过多时,账户会被临时锁定:
- 第 1 次锁定:5 分钟
- 第 2 次锁定:10 分钟
- 第 3 次锁定:20 分钟
- 以此类推,最长锁定 24 小时
角色权限控制
三种用户角色,权限分明:
- 管理员(Admin):完全控制权限,可管理系统配置
- 普通用户(User):管理自己的订阅和设置
- 演示用户(Demo):只读权限,用于展示
5. 数据备份与恢复
完善的数据保护机制,确保您的数据安全:
自动备份
- 备份频率:每日、每周或每月
- 备份目标:邮箱或 R2 云存储
- 备份内容:订阅数据、系统设置(可选)
备份格式
- JSON:完整的结构化数据,便于程序处理
- CSV:表格格式,可用 Excel 打开
设置恢复
支持从备份文件恢复系统设置,包括:
- Resend 邮件配置
- Server酱配置
- 汇率 API 配置
- 备份配置
- 两步验证配置(2FA)
6. 优雅的用户界面
基于 Naive UI 构建的现代化界面:
视图模式
- 列表视图:紧凑的表格展示,适合大量数据,支持批量选择
- 卡片视图:直观的卡片布局,信息一目了然
- 日历视图:按到期日期在日历上展示,直观查看每月到期情况
主题支持
- 浅色主题:清爽明亮
- 深色主题:护眼舒适
- 自定义主题色:个性化您的界面
响应式设计
完美适配各种设备:
- 桌面端:充分利用大屏空间
- 平板端:优化的触控体验
- 移动端:精简的移动界面
搜索与筛选
- 关键词搜索:快速定位订阅
- 类型筛选:按订阅类型过滤
- 状态筛选:按状态过滤
- 排序选项:按名称、到期时间、价格等排序
- 设置持久化:记住您的筛选偏好
技术架构
整体架构
Subly 采用前后端分离的架构,完全运行在 Cloudflare 的边缘计算平台上:
┌─────────────────────────────────────────────────────────────┐
│ Cloudflare Edge │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Workers │ │ D1 │ │ R2 │ │
│ │ (后端API) │ │ (数据库) │ │ (对象存储) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
│ │ │ │ │
│ └────────────────┼────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Static Assets (前端) │ │
│ │ Vue 3 + TypeScript + Naive UI │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
│ │ │
┌──────▼──────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Resend │ │ Server酱 │ │ ExchangeRate│
│ (邮件API) │ │ (微信推送) │ │ (汇率API) │
└─────────────┘ └─────────────┘ └─────────────┘
技术栈详解
前端技术
| 技术 | 用途 | 说明 |
|---|
| Vue 3 | 框架 | Composition API,响应式数据绑定 |
| TypeScript | 语言 | 类型安全,提升开发体验 |
| Naive UI | 组件库 | 美观、功能丰富的 Vue 3 组件库 |
| Pinia | 状态管理 | Vue 3 官方推荐的状态管理方案 |
| Vue Router | 路由 | 单页应用路由管理 |
| ECharts | 图表 | 数据可视化图表库 |
| Rsbuild | 构建工具 | 基于 Rspack 的高性能构建工具 |
| Biome | 代码规范 | 快速的代码格式化和检查工具 |
后端技术
| 技术 | 用途 | 说明 |
|---|
| Cloudflare Workers | 运行时 | 边缘计算,全球低延迟 |
| Cloudflare D1 | 数据库 | 基于 SQLite 的边缘数据库 |
| Cloudflare R2 | 存储 | S3 兼容的对象存储 |
| TypeScript | 语言 | 类型安全的后端代码 |
| Hono | 路由 | 轻量级 Web 框架 |
外部服务
| 服务 | 用途 | 说明 |
|---|
| Resend | 邮件发送 | 现代化的邮件 API 服务 |
| Server酱 | 微信推送 | 简单易用的微信通知服务 |
| ExchangeRate API | 汇率查询 | 实时货币汇率数据 |
数据库设计
Subly 使用 Cloudflare D1(SQLite)作为数据库,表结构设计如下:
核心表
-- 用户表
users (
id, username, password, role,
site_url, totp_secret, totp_enabled
)
-- 订阅表
subscriptions (
id, user_id, name, type, type_detail,
price, currency, start_date, end_date,
remind_days, renew_type, one_time, status, notes
)
配置表
-- Resend 邮件配置
resend_config (
user_id, email, api_key, domain,
notify_hours, last_sent_at, enabled,
template_subject, template_body
)
-- Server酱配置
serverchan_config (
user_id, api_key, notify_hours,
last_sent_at, enabled,
template_title, template_body
)
-- 汇率 API 配置
exchangerate_config (user_id, api_key, enabled)
-- 备份配置
backup_config (
user_id, enabled, frequency,
to_email, to_r2,
backup_subscriptions, backup_settings, last_at
)
-- 系统配置(全局单行)
system_config (registration_enabled)
-- 频率限制记录(防暴力破解)
rate_limits (
key, attempts, first_attempt_at,
last_attempt_at, lockout_until, lockout_count
)
-- 附件表
attachments (
id, user_id, subscription_id,
filename, original_name, mime_type,
size, r2_key, created_at
)
快速开始指南
环境要求
在开始之前,请确保您的开发环境满足以下要求:
- Node.js >= 18
- pnpm >= 8
- Cloudflare 账户(免费即可)
- Git
安装步骤
步骤一:克隆项目
git clone https://github.com/your-username/subly.git
cd subly
步骤二:安装依赖
步骤三:创建 Cloudflare 资源
# 登录 Cloudflare
npx wrangler login
# 创建 D1 数据库
npx wrangler d1 create subly
# 创建 R2 存储桶(用于备份,可选)
npx wrangler r2 bucket create subly
步骤四:配置 wrangler.toml
name = "subly"
main = "worker/src/index.ts"
compatibility_date = "2024-01-01"
[vars]
ENVIRONMENT = "production"
[[d1_databases]]
binding = "DB"
database_name = "subly"
database_id = "your-database-id" # 替换为实际的数据库 ID
[[r2_buckets]]
binding = "BACKUP_BUCKET"
bucket_name = "subly"
步骤五:设置密钥
# 设置 JWT 密钥(用于用户认证)
npx wrangler secret put JWT_SECRET
# 输入一个随机的强密码
步骤六:初始化数据库
# 执行数据库迁移(本地)
npx wrangler d1 execute subly --local --file=worker/schema.sql
# 执行数据库迁移(生产环境)
npx wrangler d1 execute subly --file=worker/schema.sql
本地开发
启动开发服务器
# 终端 1:启动前端开发服务器
pnpm dev
# 终端 2:启动后端 Worker
pnpm --filter subly-worker dev
访问地址:
代码检查与格式化
# 运行代码检查
pnpm check
# 格式化代码
pnpm format
部署到生产环境
构建并部署
# 构建前端并部署到 Cloudflare
pnpm deploy
或者分步执行:
# 构建前端
pnpm build
# 部署到 Cloudflare
pnpm --filter subly-worker deploy
部署完成后,您将获得一个 *.workers.dev 的域名,也可以绑定自定义域名。
详细配置指南
用户注册与登录
首次使用
- 访问您部署的 Subly 地址
- 点击"注册"创建账户
- 第一个注册的用户自动成为管理员
启用两步验证
- 登录后进入"系统设置"
- 找到"两步验证 (2FA)"部分
- 点击"设置两步验证"
- 使用验证器 App 扫描二维码
- 输入验证码完成设置
Resend 邮件配置
获取 API Key
- 访问 resend.com 并注册账户
- 在左侧菜单点击 "API Keys"
- 点击 "Create API Key"
- 复制生成的 Key(以
re_ 开头)
配置自定义域名(可选)
- 在 Resend 控制台添加您的域名
- 按照指引配置 DNS 记录
- 验证通过后,在 Subly 中填入域名
配置通知时间
选择每天发送提醒的时间点(北京时间),支持多选:
- 建议选择早上 8-9 点,开始工作时查看
- 可以选择多个时间点,如 8:00 和 20:00
Server酱配置
获取 SendKey
- 访问 sct.ftqq.com
- 使用微信扫码登录
- 点击顶部菜单的 "SendKey"
- 复制您的 SendKey(以
SCT 开头)
关注公众号
确保已关注"方糖"公众号,否则无法接收消息。
ExchangeRate 汇率配置
获取 API Key
- 访问 exchangerate-api.com
- 注册免费账户
- 在控制台获取 API Key
免费额度
免费版每月 1500 次请求,对于个人使用完全足够。
备份配置
自动备份设置
- 进入"系统设置" > "数据备份"
- 启用"自动备份"
- 选择备份频率:每日/每周/每月
- 选择备份目标:邮箱/R2 存储
- 选择备份内容:订阅数据/系统设置
手动备份
点击"立即备份"按钮,可以立即执行一次备份。
查看备份历史
点击"备份历史"可以查看所有 R2 存储的备份记录,支持下载。
使用指南
添加订阅
基本信息
- 点击首页的"添加订阅"按钮
- 填写订阅名称(如"Netflix 会员")
- 选择订阅类型
- 如果选择"其他",可以填写自定义类型
费用信息
- 输入订阅价格
- 选择货币类型
- 如果是永久授权,勾选"永久授权"
时间信息
- 选择开始日期
- 选择到期日期
- 设置提前提醒天数(默认 7 天)
续费设置
选择续费类型:
- 自动续费:系统会自动扣费
- 手动续费:需要您主动操作
- 不续费:到期后不再续费
备注
可以添加任何相关备注,如账号信息、续费链接等。
附件上传
可以上传相关文件:
- 支持格式:PDF、DOCX、PNG、JPG
- 单个文件最大 10MB
- 可上传多个附件
- 支持拖拽上传
管理订阅
编辑订阅
点击订阅卡片或列表行,进入编辑模式。
删除订阅
- 单个删除:点击订阅的删除按钮
- 批量删除:勾选多个订阅后点击"批量删除"
更新状态
订阅状态会自动更新,也可以手动切换:
搜索与筛选
关键词搜索
在搜索框输入关键词,实时过滤订阅列表。
类型筛选
点击类型筛选器,选择要显示的订阅类型。
状态筛选
点击状态筛选器,选择要显示的订阅状态。
排序
支持多种排序方式:
- 按名称排序
- 按到期时间排序
- 按价格排序
- 按创建时间排序
API 文档
所有 API 请求都需要在 Header 中携带 Authorization: Bearer <token>(除了登录和注册接口)。
认证接口
| 方法 | 路径 | 说明 |
|---|
| POST | /api/auth/register | 用户注册 |
| POST | /api/auth/login | 用户登录 |
| GET | /api/auth/me | 获取当前用户信息 |
| PUT | /api/auth/profile | 更新个人信息 |
注册请求示例
{
"username": "your_username",
"password": "your_password"
}
登录请求示例
{
"username": "your_username",
"password": "your_password",
"totp_code": "123456"
}
登录响应示例
{
"success": true,
"data": {
"token": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": 1,
"username": "your_username",
"role": "admin"
}
}
}
订阅接口
| 方法 | 路径 | 说明 |
|---|
| GET | /api/subscriptions | 获取订阅列表 |
| POST | /api/subscriptions | 创建订阅 |
| GET | /api/subscriptions/:id | 获取单个订阅 |
| PUT | /api/subscriptions/:id | 更新订阅 |
| DELETE | /api/subscriptions/:id | 删除订阅 |
| PUT | /api/subscriptions/:id/status | 更新订阅状态 |
| DELETE | /api/subscriptions/batch | 批量删除 |
| PATCH | /api/subscriptions/batch | 批量更新提醒天数 |
创建订阅请求示例
{
"name": "Netflix",
"type": "membership",
"price": 15.99,
"currency": "USD",
"start_date": "2024-01-01",
"end_date": "2025-01-01",
"remind_days": 7,
"renew_type": "auto",
"one_time": false
}
设置接口
| 方法 | 路径 | 说明 |
|---|
| PUT | /api/settings | 更新用户设置 |
| GET | /api/system/config | 获取系统配置(管理员) |
| PUT | /api/system/config | 更新系统配置(管理员) |
| GET | /api/exchange-rate | 获取汇率 |
更新设置请求示例
{
"email": "new@email.com",
"resend_api_key": "re_xxx",
"resend_enabled": true,
"backup_enabled": true,
"backup_frequency": "weekly"
}
备份接口
| 方法 | 路径 | 说明 |
|---|
| POST | /api/backup/trigger | 触发手动备份 |
| GET | /api/backup/list | 获取订阅备份列表 |
| GET | /api/backup/list?type=settings | 获取设置备份列表 |
| GET | /api/backup/download | 下载备份文件 |
| POST | /api/settings/restore | 恢复设置 |
触发备份请求示例
{
"to_email": true,
"to_r2": true,
"backup_subscriptions": true,
"backup_settings": false
}
下载备份请求参数
| 参数 | 类型 | 说明 |
|---|
| date | string | 备份日期,格式 YYYY-MM-DD |
| format | string | 文件格式,json 或 csv |
| type | string | 备份类型,subscriptions 或 settings |
2FA 接口
| 方法 | 路径 | 说明 |
|---|
| POST | /api/auth/2fa/setup | 设置 2FA(获取二维码) |
| POST | /api/auth/2fa/enable | 启用 2FA |
| POST | /api/auth/2fa/disable | 禁用 2FA |
启用/禁用 2FA 请求示例
附件接口
| 方法 | 路径 | 说明 |
|---|
| GET | /api/subscriptions/:id/attachments | 获取订阅附件列表 |
| POST | /api/subscriptions/:id/attachments | 上传附件 |
| GET | /api/attachments/:id | 下载/预览附件 |
| DELETE | /api/attachments/:id | 删除附件 |
上传附件
使用 multipart/form-data 格式上传文件:
curl -X POST \
-H "Authorization: Bearer <token>" \
-F "file=@document.pdf" \
https://your-domain.com/api/subscriptions/1/attachments
测试接口
| 方法 | 路径 | 说明 |
|---|
| POST | /api/auth/test-email | 发送测试邮件 |
| POST | /api/auth/test-serverchan | 发送测试微信消息 |
高级配置
自定义通知模板
邮件模板(HTML)
<p>您有以下订阅即将到期,请及时处理:</p>
{{subscriptions}}
<table style="width: 100%; margin-top: 16px;">
<tr>
<td style="color: #999;">发送时间</td>
<td>{{time}}</td>
</tr>
<tr>
<td style="color: #999;">到期数量</td>
<td>{{count}} 个</td>
</tr>
</table>
<div style="margin-top: 20px; text-align: center;">
<a href="{{site_url}}" style="background: #18a058; color: white; padding: 12px 24px; text-decoration: none; border-radius: 6px;">查看详情</a>
</div>
Server酱模板(Markdown)
## ⏰ 订阅到期提醒
您有以下订阅即将到期,请及时处理:
{{subscriptions}}
---
**发送时间**:{{time}}
**到期数量**:{{count}} 个
[👉 查看详情]({{site_url}})
---
*这是一条自动发送的消息,请勿直接回复。*
定时任务配置
Subly 使用 Cloudflare Workers 的 Cron Triggers 来执行定时任务:
wrangler.toml 配置
[triggers]
crons = ["0 * * * *"] # 每小时执行一次
定时任务功能
- 检查并发送到期提醒(邮件和微信)
- 执行自动备份
- 清理过期的频率限制记录
多用户部署
Subly 支持多用户使用,每个用户独立管理自己的订阅:
用户隔离
- 每个用户只能看到自己的订阅
- 配置信息完全隔离
- 备份数据按用户分开存储
管理员功能
自定义域名
绑定自定义域名
- 在 Cloudflare 控制台进入 Workers
- 选择您的 Subly Worker
- 点击 "Triggers" > "Custom Domains"
- 添加您的域名
配置 SSL
Cloudflare 自动提供 SSL 证书,无需额外配置。
故障排查
常见问题
问题 1:无法登录
# 检查是否被频率限制
# 等待锁定时间结束后重试
# 检查用户名密码是否正确
# 如果启用了 2FA,确保输入正确的验证码
问题 2:收不到邮件通知
# 检查 Resend API Key 是否正确
# 检查邮箱地址是否正确
# 检查是否在垃圾邮件文件夹
# 如果使用自定义域名,检查 DNS 配置
问题 3:收不到微信通知
# 检查 Server酱 SendKey 是否正确
# 确保已关注"方糖"公众号
# 检查通知时间设置
问题 4:汇率显示不正确
# 检查 ExchangeRate API Key 是否正确
# 检查是否超过免费额度
# 可以暂时禁用汇率功能,使用默认汇率
问题 5:备份失败
# 邮箱备份:检查 Resend 配置
# R2 备份:检查 R2 存储桶是否正确配置
# 检查 wrangler.toml 中的 R2 绑定
日志查看
本地开发
# Worker 日志会直接输出到终端
pnpm --filter subly-worker dev
生产环境
# 使用 wrangler 查看实时日志
npx wrangler tail
数据库操作
查看数据
# 本地数据库
npx wrangler d1 execute subly --local --command "SELECT * FROM users"
# 生产数据库
npx wrangler d1 execute subly --command "SELECT * FROM users"
重置 2FA
如果用户丢失了验证器,管理员可以重置:
npx wrangler d1 execute subly --command "UPDATE users SET totp_enabled = 0, totp_secret = NULL WHERE username = 'username'"
清除频率限制
npx wrangler d1 execute subly --command "DELETE FROM rate_limits WHERE key LIKE '%username%'"
与其他工具对比
Subly vs 传统表格管理
| 特性 | Subly | Excel/表格 |
|---|
| 自动提醒 | ✅ 邮件+微信 | ❌ 无 |
| 多设备同步 | ✅ 云端存储 | ❌ 需手动同步 |
| 汇率转换 | ✅ 实时汇率 | ❌ 手动计算 |
| 统计分析 | ✅ 自动统计 | ❌ 需公式 |
| 安全性 | ✅ 加密存储 | ❌ 明文 |
Subly vs 付费订阅管理服务
| 特性 | Subly | 付费服务 |
|---|
| 费用 | 免费 | $5-20/月 |
| 数据所有权 | ✅ 完全自主 | ❌ 第三方托管 |
| 自定义 | ✅ 开源可改 | ❌ 功能固定 |
| 隐私 | ✅ 自托管 | ❌ 数据上传 |
| 通知渠道 | 邮件+微信 | 通常仅邮件 |
Subly vs 其他开源方案
| 特性 | Subly | 其他方案 |
|---|
| 部署难度 | 简单(Serverless) | 需要服务器 |
| 运维成本 | 零(Cloudflare 免费) | 需要维护 |
| 性能 | 全球边缘节点 | 单点部署 |
| 扩展性 | 自动扩展 | 需手动扩容 |
安全最佳实践
1. 密钥管理
# 使用强随机密钥
openssl rand -base64 32
# 定期轮换 JWT 密钥
npx wrangler secret put JWT_SECRET
# 不要在代码中硬编码密钥
2. 启用两步验证
强烈建议所有用户启用 2FA,特别是管理员账户。
3. 定期备份
- 启用自动备份功能
- 同时备份到邮箱和 R2
- 定期测试备份恢复
4. 监控异常
- 关注登录失败通知
- 检查频率限制触发情况
- 定期查看 Worker 日志
5. 保持更新
# 定期更新依赖
pnpm update
# 关注项目更新
git pull origin main
开发指南
项目结构
subly/
├── frontend/ # 前端源码
│ ├── src/
│ │ ├── api/ # API 请求封装
│ │ ├── components/ # Vue 组件
│ │ │ ├── common/ # 通用组件
│ │ │ ├── layout/ # 布局组件
│ │ │ ├── settings/ # 设置面板
│ │ │ └── subscription/ # 订阅组件
│ │ ├── constants/ # 常量定义
│ │ ├── router/ # 路由配置
│ │ ├── stores/ # Pinia Store
│ │ ├── types/ # TypeScript 类型
│ │ ├── utils/ # 工具函数
│ │ └── views/ # 页面视图
│ ├── public/ # 静态资源
│ └── biome.json # 代码规范配置
├── worker/ # 后端 Worker
│ ├── src/
│ │ ├── routes/ # API 路由
│ │ ├── services/ # 业务服务
│ │ ├── types/ # 类型定义
│ │ ├── utils/ # 工具函数
│ │ └── index.ts # 入口文件
│ └── schema.sql # 数据库 Schema
├── wrangler.toml # Workers 配置
└── package.json # 项目配置
添加新功能
1. 添加新的 API 路由
// worker/src/routes/your-feature.ts
export async function yourHandler(request: Request, env: Env): Promise<Response> {
// 实现逻辑
}
// worker/src/router.ts
import { yourHandler } from './routes/your-feature';
const routes = [
{ pattern: '/your-endpoint', method: 'POST', handler: yourHandler },
];
2. 添加新的前端页面
// frontend/src/views/YourView.vue
<template>
<!-- 页面内容 -->
</template>
// frontend/src/router/index.ts
{
path: '/your-page',
name: 'YourPage',
component: () => import('../views/YourView.vue'),
}
3. 添加新的数据库表
-- worker/schema.sql
CREATE TABLE IF NOT EXISTS your_table (
id INTEGER PRIMARY KEY AUTOINCREMENT,
-- 字段定义
);
执行迁移:
# 本地环境
npx wrangler d1 execute subly --local --file=worker/schema.sql
# 生产环境
npx wrangler d1 execute subly --file=worker/schema.sql
代码规范
项目使用 Biome 进行代码检查和格式化:
# 检查代码
pnpm check
# 自动修复
pnpm check --write
# 格式化代码
pnpm format
提交规范
建议使用语义化的提交信息:
feat: 添加新功能
fix: 修复 bug
docs: 更新文档
style: 代码格式调整
refactor: 代码重构
test: 添加测试
chore: 构建/工具变更
未来路线图
Subly 正在持续开发中,以下是计划中的功能:
近期计划
- 移动端 App:原生 iOS/Android 应用
- 更多通知渠道:Telegram、钉钉、飞书
- 订阅分组:按项目或类别分组管理
- 共享订阅:团队成员共享订阅信息
中期计划
- 智能提醒:基于历史数据的智能提醒时间
- 价格追踪:记录订阅价格变化历史
- 续费建议:基于使用情况的续费建议
- API 开放:提供公开 API 供第三方集成
长期愿景
- 多语言支持:国际化界面
- 插件系统:支持第三方插件扩展
- 数据分析:详细的支出分析报告
- 自动续费:集成支付网关自动续费
常见问题 FAQ
基础问题
Q: Subly 是免费的吗?
A: 是的,Subly 是完全开源免费的。部署在 Cloudflare 上,免费额度足够个人使用。
Q: 我的数据安全吗?
A: 您的数据存储在您自己的 Cloudflare 账户中,完全由您控制。密码使用安全算法加密存储,支持两步验证。
Q: 支持多少个订阅?
A: 没有硬性限制。Cloudflare D1 免费版支持 5GB 存储,足够存储数万条订阅记录。
Q: 可以多人使用吗?
A: 可以。每个用户独立管理自己的订阅,数据完全隔离。
技术问题
Q: 为什么选择 Cloudflare Workers?
A: Workers 提供全球边缘计算,延迟低、免运维、免费额度充足,非常适合个人项目。
Q: 可以部署到其他平台吗?
A: 目前专为 Cloudflare 优化。理论上可以改造为其他 Serverless 平台,但需要一定的开发工作。
Q: 数据库会不会丢失?
A: Cloudflare D1 提供持久化存储,数据不会丢失。建议启用自动备份功能,双重保障。
使用问题
Q: 为什么收不到提醒?
A: 请检查:
- 是否正确配置了 Resend/Server酱
- 通知时间设置是否正确
- 订阅是否在提醒天数内
- 订阅状态是否为"活跃"
Q: 如何迁移数据?
A: 使用导出功能导出 JSON 文件,在新实例中使用导入功能即可。
Q: 忘记密码怎么办?
A: 目前没有密码重置功能,需要管理员在数据库中重置。建议启用 2FA 并妥善保管。
总结
Subly 是一个现代化的订阅管理解决方案,它充分利用了 Cloudflare 边缘计算平台的优势,提供了一个轻量、安全、功能丰富的订阅管理工具。无论您是个人用户还是小团队,都能从 Subly 的便捷管理和及时提醒中受益。
核心优势回顾
- 零成本部署:完全运行在 Cloudflare 免费层
- 多渠道提醒:邮件和微信双通道,不错过任何续费
- 安全可靠:2FA、频率限制、数据备份,全方位保护
- 开源免费:Apache License 2.0 协议,可自由使用和修改
适用场景
适合的用户:
- 订阅了多个服务,需要统一管理
- 希望自托管,掌控自己的数据
- 需要邮件和微信双渠道提醒
- 追求轻量级、低成本的解决方案
可能不适合的场景:
- 需要复杂的团队协作功能
- 需要与财务系统深度集成
- 不熟悉 Cloudflare 平台
如果您正在寻找一个简单高效的订阅管理工具,Subly 绝对值得一试。它的轻量级设计、强大的提醒功能和完善的安全机制,使其成为个人订阅管理的理想选择。
相关资源
本文基于 Subly 项目撰写,技术细节可能随版本更新而变化,建议访问项目仓库获取最新文档。