# Cloudflare Worker 部署与使用指南 ## 📦 文件说明 本工具只需要 **2 个文件**: 1. **cf_worker_v2ray_converter.js** (~88KB) - Worker 主文件 - 包含所有功能代码和完整的 HTML/CSS/JavaScript 界面 - **这是唯一需要部署到 Cloudflare 的文件** 2. **DEPLOYMENT_GUIDE.md** - 本文件,部署和使用指南 --- ## 🎯 功能说明 ### v4.1 核心功能 ⭐ 最新版本 #### 📡 订阅管理中心(需要配置 KV) 全新的订阅管理界面,专注于订阅的长期管理: - ✅ **左右分栏布局**:左侧订阅列表,右侧详情操作 - ✅ **订阅分类管理**: - **正式订阅**:支持 7天、1个月、3个月、1年、3年、长期(默认1年) - **临时订阅**:限定1天/3天/7天有效期,到期自动删除 - ✅ **智能类型识别**:自动检测 Clash 或 V2Ray 格式 - ✅ **双向格式转换**:Clash ⇄ V2Ray 任意转换 - ✅ **短链生命周期管理**:续期、换新链接、删除 - ✅ **状态标记**:快过期(30天内)和已过期订阅有明显标记 - ✅ **自定义对话框**:美观的模态确认框替代浏览器默认弹窗 --- ## 🚀 快速部署(5分钟) ### 方式 1: 通过 Cloudflare Dashboard(推荐新手) #### 步骤 1:登录 Cloudflare 访问 并登录(没有账号需先注册) #### 步骤 2:创建 Worker 1. 点击左侧菜单 **Workers & Pages** 2. 点击 **Create application** → **Create Worker** 3. 输入名称(如:`subscription-manager`) - 这将成为你的访问域名:`subscription-manager.你的账号.workers.dev` 4. 点击 **Deploy** #### 步骤 3:部署代码 1. 点击 **Quick edit** 打开代码编辑器 2. **删除**编辑器中的所有默认代码 3. 打开本地的 `cf_worker_v2ray_converter.js` 4. **全选复制**所有内容(Ctrl+A / Cmd+A,然后 Ctrl+C / Cmd+C) - ⚠️ 重要:必须复制全部 ~88KB 内容 5. **粘贴**到编辑器(Ctrl+V / Cmd+V) 6. 点击右上角 **Save and deploy** #### 步骤 4:验证部署 1. 访问 `https://你的worker名称.你的账号.workers.dev/` 2. 应该看到紫色渐变背景的「📡 订阅管理中心」页面 3. 提示需要配置 KV 命名空间 4. 继续下一步配置 KV ✅ **基础部署完成!** --- ### 方式 2: 使用 Wrangler CLI(推荐开发者) ```bash # 1. 安装 wrangler npm install -g wrangler # 2. 登录 wrangler login # 3. 创建项目 mkdir subscription-manager && cd subscription-manager wrangler init # 4. 复制代码到 src/index.js cp /path/to/cf_worker_v2ray_converter.js src/index.js # 5. 部署 wrangler deploy # 6. 查看日志(可选) wrangler tail ``` --- ## 🔧 必需配置:启用订阅管理 ### 为什么需要配置 KV? 订阅管理功能依赖 Cloudflare KV 存储数据: **不配置 KV:** - ✅ 快速转换可用 - ❌ 订阅管理不可用 - ❌ 短链接不可用 **配置 KV:** - ✅ 全部功能可用 - ✅ 可保存多个订阅 - ✅ 数据持久化 **强烈建议配置 KV!** 以下是详细步骤: --- ### 第一步:创建 KV 命名空间 #### 通过 Dashboard 创建 1. 在 Cloudflare Dashboard 中,点击 **Workers & Pages** 2. 点击顶部的 **KV** 标签 3. 点击 **Create a namespace** 4. 输入名称:`SUBSCRIPTION_STORE` 5. 点击 **Add** #### 通过 CLI 创建(可选) ```bash wrangler kv:namespace create "SUBSCRIPTION_STORE" # 记录输出的 namespace id ``` --- ### 第二步:绑定 KV 到 Worker #### 通过 Dashboard 绑定 1. 进入你的 Worker 页面 2. 点击 **Settings** 标签 3. 选择左侧的 **Variables** 4. 滚动到 **KV Namespace Bindings** 部分 5. 点击 **Add binding** 6. 填写: - **Variable name**: `SUBSCRIPTION_KV` ⚠️ **必须用这个名字** - **KV namespace**: 选择 `SUBSCRIPTION_STORE` 7. 点击 **Save and deploy** #### 通过 Wrangler 绑定(可选) 在 `wrangler.toml` 中添加: ```toml [[kv_namespaces]] binding = "SUBSCRIPTION_KV" id = "your_namespace_id" ``` 重新部署: ```bash wrangler deploy ``` --- ### 第三步:验证配置 1. 访问你的 Worker URL 2. 切换到「订阅管理」标签 3. 如果看到「+ 添加新订阅」按钮 4. 说明配置成功! **如果显示"KV 未配置":** - 检查变量名是否为 `SUBSCRIPTION_KV` - 检查是否点击了 Save and deploy - 强制刷新页面(Ctrl+Shift+R) --- ## 💾 订阅数据存储机制 ### 存储架构概览 本工具使用 Cloudflare KV 的**三层存储结构**来管理订阅数据: ``` ┌─────────────────────────────────────────────────┐ │ Cloudflare KV Storage │ ├─────────────────────────────────────────────────┤ │ │ │ 1️⃣ 订阅配置存储 │ │ Key: sub:{subscriptionId} │ │ Value: {...订阅详细信息...} │ │ 生命周期: 永久 │ │ │ │ 2️⃣ 短链接映射存储 │ │ Key: {shortId} │ │ Value: clashUrl │ │ 生命周期: 7-365天(可配置) │ │ │ │ 3️⃣ 订阅列表索引 │ │ Key: subscriptions:list │ │ Value: [id1, id2, id3, ...] │ │ 生命周期: 永久 │ │ │ └─────────────────────────────────────────────────┘ ``` --- ### 详细存储说明 #### 1️⃣ 订阅配置存储 **键格式**: `sub:{subscriptionId}` **值类型**: JSON 对象 **生命周期**: 永久(手动删除才会消失) **存储内容**: ```json { "id": "abc12345", // 订阅唯一ID(8位随机字符) "name": "我的订阅", // 用户设置的订阅名称 "clashUrl": "https://...", // 原始订阅链接(Clash或V2Ray) "subscriptionType": "clash", // 订阅源类型:clash/v2ray "subscriptionMode": "permanent", // 订阅分类:permanent/temporary "outputType": "v2ray", // 输出类型:auto/clash/v2ray "shortIds": {}, // 短链ID对象(按需生成) "shortIdsExpiry": {}, // 短链过期时间对象 "createdAt": 1703001234567, // 创建时间(Unix时间戳) "expiresAt": 1703606034567, // 订阅过期时间(null表示无限期) "expiration": "7d", // 有效期配置(如:7d, 30d, 3m, 1y, unlimited) "updatedAt": 1703001234567 // 最后更新时间 } ``` **实际例子**: ```json Key: sub:aB7cD9eF Value: { "id": "aB7cD9eF", "name": "公司网络", "clashUrl": "https://...", "subscriptionType": "clash", "subscriptionMode": "permanent", "outputType": "v2ray", "shortIds": {}, "shortIdsExpiry": {}, "createdAt": 1734672000000, "expiresAt": 1737264000000, "expiration": "30d", "updatedAt": 1734672000000 } ``` --- #### 2️⃣ 短链接映射存储 **键格式**: `{shortId}`(直接使用短ID) **值类型**: JSON 对象(包含 url、type、subscriptionId、outputType) **生命周期**: 有过期时间(TTL机制) **存储内容**: ```json Key: xyz98765 Value: { "url": "https://example.com/clash-subscription", "type": "clash", "subscriptionId": "abc12345", "outputType": "v2ray" } TTL: 604800 秒(7天) ``` **TTL 机制**: - 创建时设置过期时间(expirationTtl) - 到期后 KV 自动删除 - 订阅配置仍保留(可续期或换新链接) **实际例子**: ```json Key: x3Y8z2W Value: { "url": "https://sub.example.com/api/v1/client/subscribe?token=abc123", "type": "clash", "subscriptionId": "aB7cD9eF", "outputType": "v2ray" } TTL: 2592000 秒(30天) ``` --- #### 3️⃣ 订阅列表索引 **键格式**: `subscriptions:list`(固定键名) **值类型**: JSON 数组 **生命周期**: 永久 **存储内容**: ```json ["aB7cD9eF", "gH4iJ6kL", "mN1oP8qR"] ``` **作用**: - 快速获取所有订阅ID - 避免遍历整个 KV 空间 - 支持高效的列表查询 --- ### 数据操作流程 #### 📝 创建订阅 ``` 用户输入 → 生成ID → 写入3个地方 ``` 详细步骤: 1. 用户提交:名称、Clash URL、有效期 2. 生成 `subscriptionId`(8位随机字符) 3. 生成 `shortId`(8位随机字符) 4. **写入操作**: ```javascript // ① 创建短链数据(按需生成,不在创建时预先生成) const shortLinkData = { url: clashUrl, type: subscriptionType, subscriptionId: subscriptionId, outputType: outputType } // ② 写入订阅配置 await KV.put(`sub:${subscriptionId}`, JSON.stringify(subscription)) // ③ 更新订阅列表 const list = await getList() list.push(subscriptionId) await KV.put('subscriptions:list', JSON.stringify(list)) ``` --- #### 📖 获取订阅列表 ``` 读取索引 → 遍历读取 → 检查状态 → 返回列表 ``` 详细步骤: 1. 读取 `subscriptions:list` 获取所有ID 2. 循环读取每个 `sub:{id}` 3. 检查 `expiresAt` 判断是否过期 4. 组装并返回完整列表 **性能**: - 假设有 10 个订阅 - 需要 11 次 KV 读取(1次索引 + 10次配置) - 免费版每天 100K 读取,完全够用 --- #### 🔄 续期短链 ``` 读取配置 → 更新TTL → 更新配置 ``` 详细步骤: 1. 读取 `sub:{id}` 获取 shortIds 和订阅信息 2. **重新写入短链**(更新 TTL): ```javascript const shortLinkData = { url: subscription.clashUrl, type: subscription.subscriptionType, subscriptionId: id, outputType: subscription.outputType } await KV.put(shortId, JSON.stringify(shortLinkData), { expirationTtl: newDays * 86400 }) ``` 3. **更新订阅配置**: ```javascript subscription.shortIdsExpiry[type] = Date.now() + newTTL * 1000 subscription.updatedAt = Date.now() await KV.put(`sub:${id}`, JSON.stringify(subscription)) ``` **优势**: - 短链接URL不变 - v2rayN客户端无需重新配置 - 只需2次KV操作 --- #### 🔁 换新链接 ``` 删除旧链 → 生成新ID → 写入新链 → 更新配置 ``` 详细步骤: 1. 读取订阅配置,获取旧的 shortIds 2. **删除旧短链**: ```javascript if (subscription.shortIds[type]) { await KV.delete(subscription.shortIds[type]) } ``` 3. 生成新的 shortId 4. **写入新短链**: ```javascript const shortLinkData = { url: subscription.clashUrl, type: subscription.subscriptionType, subscriptionId: id, outputType: subscription.outputType } await KV.put(newShortId, JSON.stringify(shortLinkData), { expirationTtl: days * 86400 }) ``` 5. **更新订阅配置**: ```javascript subscription.shortIds[type] = newShortId subscription.shortIdsExpiry[type] = Date.now() + newTTL * 1000 subscription.updatedAt = Date.now() await KV.put(`sub:${id}`, JSON.stringify(subscription)) ``` **注意**: - 旧短链立即失效 - 需要在v2rayN中更新订阅链接 - 用于应对链接泄露的情况 --- #### 🗑️ 删除订阅 ``` 删除短链 → 删除配置 → 更新索引 ``` 详细步骤: 1. 读取配置获取 shortIds 对象 2. **删除所有短链映射**: ```javascript for (const type in subscription.shortIds) { await KV.delete(subscription.shortIds[type]) } ``` 3. **删除订阅配置**:`await KV.delete(`sub:${id}`)` 4. **更新订阅列表**: ```javascript const list = await getList() const newList = list.filter(x => x !== id) await KV.put('subscriptions:list', JSON.stringify(newList)) ``` --- ### 存储容量和限制 #### Cloudflare KV 免费版配额 | 指标 | 限制 | 说明 | |------|------|------| | 存储空间 | 1 GB | 可存储约100万个订阅 | | 读取操作 | 100,000 次/天 | 获取订阅、访问短链 | | 写入操作 | 1,000 次/天 | 创建、更新、删除订阅 | | 删除操作 | 1,000 次/天 | 包含在写入配额中 | | 列表操作 | 1,000 次/天 | 遍历键名 | #### 操作消耗计算 **创建1个订阅**: - 2次写入(配置 + 索引) - 消耗配额:2/1000 - 注:短链按需生成,不在创建时预先生成 **获取订阅列表**(假设10个订阅): - 11次读取(1次索引 + 10次配置) - 消耗配额:11/100000 **续期1个订阅**: - 1次读取 + 2次写入 - 消耗配额:1/100000 + 2/1000 **换新链接**: - 1次读取 + 1次删除 + 2次写入 - 消耗配额:1/100000 + 3/1000 --- #### 实际使用场景 **个人使用(推荐)**: ``` 订阅数量:10-50 个 短链有效期:30-90 天 每天操作: - 查看列表 5 次 → 55 次读取 - 访问短链 50 次 → 50 次读取 - 创建订阅 1 次 → 2 次写入 - 续期订阅 1 次 → 2 次写入 总消耗: - 读取:105 / 100,000 = 0.1% - 写入:4 / 1,000 = 0.4% 结论:完全在免费额度内 ✅ ``` **小团队使用**: ``` 订阅数量:100-200 个 短链有效期:60-180 天 每天操作: - 查看列表 20 次 → 4,020 次读取 - 访问短链 500 次 → 500 次读取 - 创建订阅 5 次 → 10 次写入 - 续期订阅 5 次 → 10 次写入 总消耗: - 读取:4,520 / 100,000 = 4.5% - 写入:20 / 1,000 = 2.0% 结论:免费额度足够 ✅ ``` **高频使用(需付费)**: ``` - 写入 > 1,000 次/天 - 读取 > 100,000 次/天 建议:升级到付费版 ``` --- ### 数据持久性 #### 永久保存的数据 - ✅ 订阅配置(`sub:{id}`) - ✅ 订阅列表索引(`subscriptions:list`) - ✅ 不会因为 Worker 重新部署而丢失 #### 有生命周期的数据 - ⏰ 短链接(`{shortId}`) - ⏰ 创建时设置 TTL - ⏰ 到期自动删除 - ⏰ 但可以续期或换新 #### 数据丢失风险 - ❌ 删除 KV 命名空间 → 所有数据丢失 - ❌ 解绑 KV → 无法访问数据 - ✅ Worker 重新部署 → 数据不受影响 - ✅ 修改代码 → 数据不受影响 --- ### 数据安全性 #### 1. 数据隔离 - 每个 Worker 绑定独立的 KV 命名空间 - 其他人无法访问你的 KV 数据 - Cloudflare 账号权限控制 #### 2. 访问控制 - 订阅管理功能在前端,无内置权限控制 - **建议**:不要公开分享 Worker URL - **可选**:配置 `ADMIN_TOKEN` 环境变量启用管理员页面 配置管理员 Token: ``` Worker Settings → Variables → Environment Variables Name: ADMIN_TOKEN Value: your-secret-token ``` 访问管理页面: ``` https://your-worker.workers.dev/admin?token=your-secret-token ``` #### 3. 数据备份 - KV 数据由 Cloudflare 自动备份 - **建议**:定期导出重要订阅的 Clash URL - 可通过 API 或管理页面查看所有订阅 #### 4. 隐私保护 - Clash URL 存储在 KV 中(加密存储) - 短链接隐藏了原始 URL - **建议**:使用短链接分享,不要直接分享 Clash URL --- ## 📱 使用指南 ### 场景 1:快速转换(临时使用) **适合**:偶尔需要转换、不想保存 **步骤**: 1. 访问 Worker URL 2. 在「快速转换」标签 3. 粘贴 Clash 订阅链接 4. 点击「生成在线链接」或「下载订阅」 5. 使用生成的链接或文件 --- ### 场景 2:保存订阅(长期管理)⭐ 推荐 **适合**:经常使用、需要管理多个订阅 #### 首次添加订阅 1. 切换到「订阅管理」标签 2. 点击「+ 添加新订阅」 3. 填写信息: ``` 订阅名称:公司网络 Clash 订阅链接:https://... 短链有效期:30 天 ``` 4. 点击「保存」 #### 使用订阅 1. 找到订阅卡片 2. 点击「复制链接」 3. 在 v2rayN 中: ``` 订阅 → 订阅设置 添加订阅地址 粘贴链接 → 确定 更新订阅 ``` #### 管理订阅 - **续期**:短链快过期 → 点击「续期」→ 设置天数 - 优点:链接不变,客户端无需更新 - **换新链接**:担心链接泄露 → 点击「换新链接」→ 设置天数 - 注意:旧链接失效,需要更新客户端 - **编辑**:Clash URL 变了 → 点击「编辑」→ 修改并保存 - **删除**:不再需要 → 点击「删除」→ 确认 --- ### 场景 3:管理多个订阅 **适合**:多个机场、多个环境 **示例**: ``` 订阅列表: ├─ 机场A - 美国节点(30天) ├─ 机场B - 香港节点(60天) ├─ 公司专线(90天) └─ 备用订阅(7天) ``` **操作**: 1. 分别添加所有订阅 2. 设置不同的名称和有效期 3. 在 v2rayN 中添加多个订阅源 4. 定期检查过期状态 5. 需要时单独续期或换链接 --- ## 🔌 API 接口说明 ### 基础接口 #### 1. 网页界面 ```http GET / ``` 返回 HTML 页面 #### 2. 快速转换(POST) ```http POST /convert Content-Type: application/json { "clashUrl": "https://..." } ``` 返回 Base64 编码的 v2rayN 订阅 #### 3. 快速转换(GET) ```http GET /convert?url=https://... ``` 直接返回订阅内容,用于在线订阅 #### 4. 生成短链 ```http POST /shorten Content-Type: application/json { "clashUrl": "https://..." } ``` #### 5. 访问短链 ```http GET /s/{shortId} ``` --- ### 订阅管理 API #### 创建订阅 ```http POST /api/subscriptions Content-Type: application/json { "name": "我的订阅", "clashUrl": "https://...", "expirationDays": 30 } ``` #### 获取所有订阅 ```http GET /api/subscriptions ``` #### 获取单个订阅 ```http GET /api/subscriptions/{id} ``` #### 更新订阅 ```http PUT /api/subscriptions/{id} Content-Type: application/json { "name": "新名称", "clashUrl": "https://..." } ``` #### 删除订阅 ```http DELETE /api/subscriptions/{id} ``` #### 续期短链 ```http POST /api/subscriptions/{id}/renew Content-Type: application/json { "days": 30 } ``` #### 换新链接 ```http POST /api/subscriptions/{id}/regenerate Content-Type: application/json { "days": 30 } ``` --- ## ❓ 常见问题 ### Q1: 必须配置 KV 吗? **答**:不是必须,但强烈建议 - 不配置:只能用快速转换 - 配置后:完整功能,可保存订阅 ### Q2: 免费版够用吗? **答**:个人使用完全够用 - 存储:1GB(数万个订阅) - 读取:10万次/天 - 写入:1000次/天 ### Q3: 订阅会丢失吗? **答**:不会 - 订阅配置永久保存 - 短链接有过期时间 - Worker 重新部署不影响数据 ### Q4: 短链过期了怎么办? **答**:两种方式 1. **续期**:延长有效期,链接不变 2. **换新链接**:生成新链接,旧链失效 推荐续期,无需更新客户端。 ### Q5: 如何备份数据? **答**:建议 1. 定期导出订阅列表(API 或页面) 2. 保存重要的 Clash URL 3. KV 数据 Cloudflare 自动备份 ### Q6: 支持多少个订阅? **答**:理论上无限 - 免费版存储 1GB - 每个订阅约 1KB - 可存储约 100 万个 实际建议:10-100个 ### Q7: 如何查看日志? **答**:使用 wrangler ```bash wrangler tail ``` ### Q8: 可以自定义域名吗? **答**:可以 在 Worker 设置中添加自定义域名 ### Q9: 数据安全吗? **答**:安全 - KV 数据加密存储 - 账号权限隔离 - 建议不公开分享 Worker URL ### Q10: 转换失败怎么办? **答**:检查 1. Clash URL 是否有效 2. 浏览器控制台错误 3. Worker 日志 --- ## 🔄 更新日志 ### v3.1 (2024-12-20) 🆕 **订阅类型支持**: - ✨ 自动识别订阅类型(Clash / V2Ray) - ✨ 双向转换:Clash ⇄ V2Ray - ✨ 自定义输出类型(保存时选择) - ✨ 短链支持类型参数 `?type=clash` 或 `?type=v2ray` **灵活的有效期管理**: - ✨ 支持多种时间单位:天(d)、月(m)、年(y) - ✨ 支持无限期订阅 - ✨ 示例:`7d`(7天)、`3m`(3个月)、`1y`(1年)、`unlimited`(无限期) **UI 改进**: - ✨ 订阅卡片显示类型标签(Clash/V2Ray) - ✨ 显示输出类型和转换方向 - ✨ 续期/换链接使用模态框界面(替代 prompt) - ✨ 时间单位下拉选择(更友好) **数据结构升级**: - 📝 订阅对象新增 `subscriptionType` 和 `outputType` 字段 - 📝 短链存储改为 JSON 对象(包含类型信息) - 📝 过期时间格式改为字符串(如 `7d`) ### v4.1 (2025-01) **有效期选项简化**: - ✨ 正式订阅有效期简化为:7天、1个月、3个月、1年、3年、长期 - ✨ 默认选择1年(更适合长期使用场景) - ✨ 移除过于细分的有效期选项 **状态标记增强**: - ✨ 快过期订阅(30天内到期)显示「快过期」橙色标记 - ✨ 已过期订阅显示「已过期」红色标记 - ✨ 便于用户及时续期或清理 **UI/UX 改进**: - ✨ 自定义对话框替代浏览器默认 alert/confirm 弹窗 - ✨ 统一的模态框风格,更美观 - ✨ 清空订阅列表功能完善 **代码优化**: - 📝 移除本地 KV 模拟代码(Wrangler 自带模拟) - 📝 优化 API 路由顺序 - 📝 简化 clearAllSubscriptions 函数 ### v3.0 (2024-12-20) - ✨ 多订阅管理 - ✨ 短链生命周期管理 - ✨ 双标签界面 - ✨ 12个新API端点 ### v2.0 (2025-12-19) - ✨ 在线链接生成 - ✨ KV 短链接支持 ### v1.0 (2025-12-19) - 🎉 初始版本 - ✅ 基础转换功能 --- ## 📞 技术支持 遇到问题? 1. 查看本文档的常见问题 2. 检查浏览器控制台 3. 查看 Worker 日志 **当前版本**: v3.1 **更新时间**: 2024-12-20 --- ## 🆕 v3.1 新功能详细说明 ### 1. 订阅类型自动识别 **功能说明**: 添加订阅时,系统会自动检测订阅链接的类型: - Clash 格式:YAML 配置文件 - V2Ray 格式:Base64 编码的节点列表 **识别逻辑**: 1. 尝试下载订阅内容 2. 检查是否包含 "proxies:" → Clash 3. 尝试 Base64 解码 → V2Ray 4. 检查是否包含 vmess:// 等协议 → V2Ray **使用场景**: - 无需手动选择类型 - 支持混合使用多种订阅源 - 自动标记订阅类型 ### 2. 双向转换功能 **支持的转换方向**: - ✅ Clash → V2Ray(原有功能) - ✅ V2Ray → Clash(新增功能) - ✅ Clash → Clash(直接透传) - ✅ V2Ray → V2Ray(直接透传) **短链动态转换**: ``` 短链:https://worker.com/s/abc123 - 默认:https://worker.com/s/abc123(使用配置的输出类型) - Clash:https://worker.com/s/abc123?type=clash - V2Ray:https://worker.com/s/abc123?type=v2ray ``` ### 3. 灵活的有效期设置 **支持的格式**: | 格式 | 说明 | 实际时长 | |------|------|---------| | `7` 或 `7d` | 7天 | 604,800 秒 | | `30d` | 30天 | 2,592,000 秒 | | `3m` | 3个月 | ~7,776,000 秒 | | `1y` | 1年 | ~31,536,000 秒 | | `unlimited` | 无限期 | 永不过期 | ### 4. API 变更说明 **创建订阅 API**: ```http POST /api/subscriptions { "name": "订阅名", "clashUrl": "https://...", // 支持 Clash 或 V2Ray "expiration": "7d", // 支持 d/m/y/unlimited "outputType": "auto" // auto/v2ray/clash } ``` **续期/换链接 API**: ```http POST /api/subscriptions/{id}/renew POST /api/subscriptions/{id}/regenerate { "expiration": "7d", // 支持 d/m/y/unlimited "outputType": "v2ray" // 可选:更改输出类型 } ``` --- ## 📝 v4.0 新特性详解 ### 1. 全新的左右分栏界面 **界面结构**: ``` ┌─────────────────────────────────────────────┐ │ 📡 订阅管理中心 │ ├─────────────┬───────────────────────────────┤ │ 订阅列表 │ 订阅详情 │ │ [+新建] │ │ │ │ 订阅名称 [正式] [V2Ray] │ │ > 我的订阅 │ ─────────────────────── │ │ 机场A │ 原始链接: https://... │ │ 测试订阅 │ 输出类型: V2Ray │ │ │ 创建时间: 2025-01-01 │ │ │ 有效期: 2025-02-01 │ │ │ │ │ │ 短链接: https://... │ │ │ [复制] ✅ 正常使用中 │ │ │ │ │ │ [编辑] [续期] [换链接] [删除] │ └─────────────┴───────────────────────────────┘ ``` **交互流程**: 1. 左侧列表点击订阅 → 右侧显示详情 2. 点击「新建」→ 弹出添加表单 3. 点击「编辑」→ 弹出编辑表单 4. 点击「续期」→ 弹出续期表单 5. 点击「换链接」→ 弹出换链接表单 ### 2. 订阅分类:正式 vs 临时 #### 正式订阅(Permanent) **特点**: - ✅ 完整的功能和灵活性 - ✅ 支持全部有效期选项:1天-无限期 - ✅ 支持所有单位:天(d)、月(m)、年(y)、无限期 - ✅ 适合长期使用的订阅 **使用场景**: - 主力机场订阅 - 公司专线 - 长期测试环境 - 需要永久保存的配置 #### 临时订阅(Temporary) **特点**: - ⚡ 限制有效期:只能选择 1天/3天/7天 - ⚡ 到期自动删除:短链过期后订阅配置也会被清理 - ⚡ 适合短期临时使用 **使用场景**: - 临时测试链接 - 短期分享给朋友 - 一次性测试任务 - 避免数据积累 **对比表格**: | 特性 | 正式订阅 | 临时订阅 | |------|---------|---------| | 有效期选项 | 1天-无限期 | 仅1天/3天/7天 | | 自动删除 | ❌ 不删除 | ✅ 过期自动删除 | | 续期 | ✅ 支持任意期限 | ✅ 仅支持1/3/7天 | | 换链接 | ✅ 支持任意期限 | ✅ 仅支持1/3/7天 | | 用途 | 长期使用 | 短期临时 | ### 3. 智能类型识别与双向转换 **自动识别逻辑**: ```javascript // 添加订阅时自动检测 const url = "https://example.com/subscription" // 系统会自动判断: // - Clash: 包含 proxies, proxy-groups, rules 等字段 // - V2Ray: base64 编码的 vmess:// 或 vless:// 链接列表 ``` **转换支持**: | 原始类型 | 目标类型 | 操作 | 说明 | |---------|---------|------|------| | Clash | V2Ray | ✅ 转换 | 提取节点转为 V2Ray 格式 | | V2Ray | Clash | ✅ 转换 | 解析节点生成 Clash 配置 | | Clash | Clash | ⏩ 直传 | 不做转换,直接返回 | | V2Ray | V2Ray | ⏩ 直传 | 不做转换,直接返回 | **短链动态切换**: ``` 短链地址:https://worker.com/s/abc123 可选参数: - 默认(自动):https://worker.com/s/abc123 - 强制 Clash:https://worker.com/s/abc123?type=clash - 强制 V2Ray:https://worker.com/s/abc123?type=v2ray ``` ### 4. 多单位有效期系统 **支持的格式**: | 输入格式 | 说明 | 实际时长(秒) | |---------|------|---------------| | `7` 或 `7d` | 7天 | 604,800 | | `30d` | 30天 | 2,592,000 | | `3m` | 3个月 | ~7,776,000 | | `6m` | 6个月 | ~15,552,000 | | `1y` | 1年 | ~31,536,000 | | `unlimited` | 无限期 | null(永不过期) | **解析规则**: ```javascript // parseExpiration() 函数 "7d" → 7 * 86400 = 604800 秒 "3m" → 3 * 30 * 86400 = 7776000 秒 "1y" → 1 * 365 * 86400 = 31536000 秒 "unlimited" → null(不设置TTL) ``` **临时订阅限制**: ```javascript // 临时订阅只接受以下值: ✅ "1d" - 1天 ✅ "3d" - 3天 ✅ "7d" - 7天 ❌ "30d", "1m", "1y", "unlimited" - 不允许 ``` ### 5. API 完整说明 #### 创建订阅(新增 subscriptionMode) ```http POST /api/subscriptions Content-Type: application/json { "name": "订阅名称", "clashUrl": "https://...", // 支持 Clash 或 V2Ray "subscriptionMode": "permanent", // 新增:permanent/temporary "expiration": "7d", // d/m/y/unlimited "outputType": "auto" // auto/v2ray/clash } ``` **Response**: ```json { "success": true, "subscription": { "id": "abc123xy", "name": "我的订阅", "clashUrl": "https://...", "subscriptionType": "clash", // 自动识别的类型 "subscriptionMode": "permanent", // 订阅分类 "outputType": "v2ray", "shortIds": {}, // 短链ID对象(按需生成) "shortIdsExpiry": {}, // 短链过期时间对象 "createdAt": 1704067200000, "expiresAt": 1704672000000, "expiration": "7d", "updatedAt": 1704067200000, "isExpired": false } } ``` #### 续期订阅(支持临时订阅限制) ```http POST /api/subscriptions/{id}/renew { "expiration": "7d", // 临时订阅只能 1d/3d/7d "outputType": "clash" // 可选:更改输出类型 } ``` #### 换新链接(支持临时订阅限制) ```http POST /api/subscriptions/{id}/regenerate { "expiration": "30d", // 临时订阅只能 1d/3d/7d "outputType": "v2ray" // 可选:更改输出类型 } ``` **临时订阅限制示例**: ```javascript // 如果是临时订阅 + 传入不合法的期限 { "subscriptionMode": "temporary", "expiration": "30d" // ❌ 不允许 } // 服务器会自动调整为默认值 "3d" ``` ### 6. 临时订阅自动清理机制 **工作原理**: 1. 临时订阅的短链设置 KV TTL(Time To Live) 2. 到期后 Cloudflare 自动删除短链 KV 记录 3. 用户访问订阅列表时,检测到短链已失效 4. **未来增强**:可以添加定时任务删除过期的订阅配置记录 **当前状态**: ```javascript // 短链过期后自动删除(由 KV TTL 机制保证) const shortLinkData = { url: subscription.clashUrl, type: subscription.subscriptionType, subscriptionId: id, outputType: subscription.outputType } await KV.put(shortId, JSON.stringify(shortLinkData), { expirationTtl: days * 86400 // 自动过期 }) // 订阅配置需要手动删除(访问时检测) // TODO: 未来可添加 Cron Trigger 定期清理 ``` --- ## 🆕 版本历史 ### v4.0(2024-12-20)⭐ 当前版本 **主要更新**: - 🎨 全新左右分栏 UI 设计 - 📂 订阅分类:正式订阅 vs 临时订阅 - ⏱️ 临时订阅自动过期删除 - 🔧 临时订阅有效期限制(1/3/7天) - 🏷️ 订阅列表显示分类标签 - 🎯 简化用户操作流程 - 📡 工具更名为「订阅管理中心」 ### v3.1(2024-12-20) **主要更新**: - ✨ 智能订阅类型识别(Clash/V2Ray) - 🔄 双向格式转换(Clash ⇄ V2Ray) - 📅 灵活有效期单位(天/月/年/无限期) - 🏷️ 订阅类型标签显示 - 🎨 改进的 UI 反馈 ### v3.0(2024-11-XX) **主要更新**: - 📋 多订阅管理功能 - 🔗 短链生命周期管理 - 💾 KV 存储集成 - 📊 订阅列表视图 - ⚙️ 编辑/续期/换链接功能 ### v2.0(2024-10-XX) **主要更新**: - 🌐 Web UI 界面 - ⚡ 快速转换模式 - 📥 直接下载功能 ### v1.0(2024-09-XX) **初始版本**: - 🔧 基础 Clash → V2Ray 转换 - 📝 命令行工具 --- **当前版本**: v4.0 **更新时间**: 2024-12-20