diff --git a/docs/README.md b/docs/README.md index ec22d5c..c0718de 100644 --- a/docs/README.md +++ b/docs/README.md @@ -105,6 +105,8 @@ go run ./cmd/api `GET /healthz` 返回 `{"status": "ok"}`,用于部署探活。 +更多子系统/专题文档请查阅 `docs/*` 子目录,例如 `docs/remove_watermark/README.md` 描述了去水印小程序的详细需求。 + ## 多小程序共用后台设计 - **凭证管理表**:`mini_programs` 持久化 `name/app_id/app_secret`,可通过后台页面或 SQL 插入,避免把密钥写进环境变量。 diff --git a/docs/remove_watermark/README.md b/docs/remove_watermark/README.md new file mode 100644 index 0000000..752aa60 --- /dev/null +++ b/docs/remove_watermark/README.md @@ -0,0 +1,92 @@ +# 去水印小程序需求说明 + +## 背景 + +小程序需要提供“短视频去水印”功能。用户提交的文本中包含短视频分享链接,后台需调用第三方接口 `https://api.23bt.cn/api/d1w/index?key=<你的key>&url=<分享链接>` 获取解析结果并返回。该接口仅向已登录用户开放。 + +## 功能需求 + +1. **访问控制** + - 用户必须先调用 `POST /api/v1/auth/login` 完成登录,接口需要校验 token / 会话。 +2. **请求参数** + - 前端提交 JSON:`{"content":"帮我解析 https://v.douyin.com/xxx/"}`。 + - 后端从 `content` 中提取第一个合法 http/https 链接;未找到时返回 400。 +3. **第三方请求** + - 构造 `GET https://api.23bt.cn/api/d1w/index?key=&url=`。 + - `key` 存放在配置或环境变量(如 `SHORT_VIDEO_API_KEY`)。 + - 设置合理超时(建议 ≤5s),捕获网络/业务错误。 +4. **返回结果** + - 成功:将第三方返回体(可直接透传或转换为 `provider/raw` 结构)返回客户端。 + - 失败:输出统一错误结构,例如 `{"code":502,"message":"third-party api error: ..."}` +5. **日志与监控** + - 记录 mini_program_id、user_id、目标链接、第三方响应码、耗时。 + - 按用户建立调用记录表,统计每日次数并保存第三方返回内容概要(参考「计费与记录设计」)。 + +## 推荐接口设计 + +``` +POST /api/v1/video/remove_watermark +Authorization: Bearer + +{ + "content": "帮我解析这个 https://v.douyin.com/xxx/ 谢谢" +} +``` + +**成功响应** +```json +{ + "code": 200, + "message": "success", + "data": { + "provider": "23bt", + "raw": { "...第三方响应..." } + } +} +``` + +**常见错误** +- `400`:缺少 `content`、未能解析链接。 +- `401/403`:未登录或 token 失效。 +- `502`:第三方解析失败。 + +## 处理流程 + +1. 校验登录状态 → 解析 JSON → 提取链接。 +2. 生成第三方接口 URL(带 key、url),发起 HTTP 请求。 +3. 根据第三方响应判定成功/失败,封装结果并返回。 +4. 记录日志,可在失败时重试一次或提示用户稍后重试。 + +## 计费与记录设计 + +### 表结构建议:`video_parse_logs` + +| 字段 | 类型 | 说明 | +| --- | --- | --- | +| `id` | bigint unsigned | 主键 | +| `mini_program_id` | bigint unsigned | 关联 `mini_programs.id` | +| `user_id` | bigint unsigned | 关联 `users.id` | +| `request_content` | text | 用户提交的原始文本 | +| `parsed_url` | varchar(500) | 提取的短视频链接 | +| `third_party_status` | int | 第三方 HTTP 状态或业务码 | +| `third_party_payload` | json | 第三方响应原文(可截断/脱敏) | +| `free_quota_used` | tinyint | 本次调用是否计入免费次数 | +| `created_at` | datetime | 记录生成时间 | + +按 `user_id + date(created_at)` 建索引,方便统计当日次数。 + +### 免费次数与广告策略 + +1. **每日额度**:默认每天 20 次免费解析。统计逻辑基于 `video_parse_logs` 中 `free_quota_used=1` 的数量(按用户和当天日期)。 +2. **广告解锁**: + - 当用户当天已使用 ≥20 次免费额度时,接口返回提示“需观看广告以继续使用”。 + - 用户观看广告后,后台记录一条标记(例如 `video_parse_unlocks` 表,包含 `user_id`、`date`、`ad_watched_at`)。 + - 当天一旦观看成功,`free_quota_used` 设为 `0`,并允许无限制解析。 +3. **流程概述**: + - 登录 → 检查 `video_parse_unlocks` 是否在当天存在记录。 + - 若不存在,统计 `video_parse_logs` 免费调用次数;未超 20 次→继续,超限→返回广告提示。 + - 用户观看广告后调用“广告完成”接口,服务端写入解锁记录。 + - 解锁后所有解析均记录日志但不再限制次数(直到次日零点自动失效)。 +4. **其他注意事项**: + - 可在日志中存储第三方返回摘要(如视频标题、作者),便于后续分析。 + - 可配置单独的付费/会员策略,覆盖默认 20 次逻辑。