Files
clash_subscriptions/tools/SubConverter/DEPLOYMENT_GUIDE.md

1403 lines
31 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
访问 <https://dash.cloudflare.com/> 并登录(没有账号需先注册)
#### 步骤 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", // 订阅唯一ID8位随机字符
"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使用配置的输出类型
- Clashhttps://worker.com/s/abc123?type=clash
- V2Rayhttps://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
- 强制 Clashhttps://worker.com/s/abc123?type=clash
- 强制 V2Rayhttps://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 TTLTime 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.02024-12-20⭐ 当前版本
**主要更新**
- 🎨 全新左右分栏 UI 设计
- 📂 订阅分类:正式订阅 vs 临时订阅
- ⏱️ 临时订阅自动过期删除
- 🔧 临时订阅有效期限制1/3/7天
- 🏷️ 订阅列表显示分类标签
- 🎯 简化用户操作流程
- 📡 工具更名为「订阅管理中心」
### v3.12024-12-20
**主要更新**
- ✨ 智能订阅类型识别Clash/V2Ray
- 🔄 双向格式转换Clash ⇄ V2Ray
- 📅 灵活有效期单位(天/月/年/无限期)
- 🏷️ 订阅类型标签显示
- 🎨 改进的 UI 反馈
### v3.02024-11-XX
**主要更新**
- 📋 多订阅管理功能
- 🔗 短链生命周期管理
- 💾 KV 存储集成
- 📊 订阅列表视图
- ⚙️ 编辑/续期/换链接功能
### v2.02024-10-XX
**主要更新**
- 🌐 Web UI 界面
- ⚡ 快速转换模式
- 📥 直接下载功能
### v1.02024-09-XX
**初始版本**
- 🔧 基础 Clash → V2Ray 转换
- 📝 命令行工具
---
**当前版本**: v4.0
**更新时间**: 2024-12-20