321 lines
10 KiB
Markdown
321 lines
10 KiB
Markdown
# Day 9: 发布模块代码优化
|
||
|
||
**日期**: 2026-01-23
|
||
**目标**: 代码质量优化 + 发布功能验证
|
||
|
||
---
|
||
|
||
## 📋 任务概览
|
||
|
||
| 任务 | 状态 |
|
||
|------|------|
|
||
| B站/抖音发布验证 | ✅ 完成 |
|
||
| 资源清理保障 (try-finally) | ✅ 完成 |
|
||
| 超时保护 (消除无限循环) | ✅ 完成 |
|
||
| 小红书 headless 模式修复 | ✅ 完成 |
|
||
| API 输入验证 | ✅ 完成 |
|
||
| 类型提示完善 | ✅ 完成 |
|
||
| 服务层代码优化 | ✅ 完成 |
|
||
| 扫码登录等待界面 | ✅ 完成 |
|
||
| 抖音登录策略优化 | ✅ 完成 |
|
||
| 发布成功审核提示 | ✅ 完成 |
|
||
| 用户认证系统规划 | ✅ 计划完成 |
|
||
|
||
---
|
||
|
||
## 🎉 发布验证结果
|
||
|
||
### 登录功能
|
||
- ✅ **B站登录成功** - 策略3(Text)匹配,Cookie已保存
|
||
- ✅ **抖音登录成功** - 策略3(Text)匹配,Cookie已保存
|
||
|
||
### 发布功能
|
||
- ✅ **抖音发布成功** - 自动关闭弹窗、跳转管理页面
|
||
- ✅ **B站发布成功** - API返回 `bvid: BV14izPBQEbd`
|
||
|
||
---
|
||
|
||
## 🔧 代码优化
|
||
|
||
### 1. 资源清理保障
|
||
|
||
**问题**:Playwright 浏览器在异常路径可能未关闭
|
||
|
||
**修复**:`try-finally` 模式确保资源释放
|
||
```python
|
||
browser = None
|
||
context = None
|
||
try:
|
||
browser = await playwright.chromium.launch(headless=True)
|
||
context = await browser.new_context(...)
|
||
# ... 业务逻辑 ...
|
||
finally:
|
||
if context:
|
||
try: await context.close()
|
||
except Exception: pass
|
||
if browser:
|
||
try: await browser.close()
|
||
except Exception: pass
|
||
```
|
||
|
||
### 2. 超时保护
|
||
|
||
**问题**:`while True` 循环可能导致任务卡死
|
||
|
||
**修复**:添加类级别超时常量
|
||
```python
|
||
class DouyinUploader(BaseUploader):
|
||
UPLOAD_TIMEOUT = 300 # 视频上传超时
|
||
PUBLISH_TIMEOUT = 180 # 发布检测超时
|
||
PAGE_REDIRECT_TIMEOUT = 60 # 页面跳转超时
|
||
```
|
||
|
||
### 3. B站 bvid 提取修复
|
||
|
||
**问题**:API 返回的 bvid 在 `data` 字段内
|
||
|
||
**修复**:同时检查多个位置
|
||
```python
|
||
bvid = ret.get('data', {}).get('bvid') or ret.get('bvid', '')
|
||
aid = ret.get('data', {}).get('aid') or ret.get('aid', '')
|
||
```
|
||
|
||
### 4. API 输入验证
|
||
|
||
**修复**:所有端点添加平台验证
|
||
```python
|
||
SUPPORTED_PLATFORMS = {"bilibili", "douyin", "xiaohongshu"}
|
||
|
||
if platform not in SUPPORTED_PLATFORMS:
|
||
raise HTTPException(status_code=400, detail=f"不支持的平台: {platform}")
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 用户体验优化
|
||
|
||
### 1. 扫码登录等待界面
|
||
|
||
**问题**:点击登录后,二维码获取需要几秒,用户无反馈
|
||
|
||
**优化**:
|
||
- 点击登录后立即显示加载弹窗
|
||
- 加载动画 (旋转圈 + "正在获取二维码...")
|
||
- 二维码获取成功后自动切换显示
|
||
|
||
### 2. 抖音登录策略优化
|
||
|
||
**问题**:抖音登录需要约 23 秒获取二维码 (策略1/2超时)
|
||
|
||
**原因分析**:
|
||
| 策略 | 抖音耗时 | B站耗时 | 结果 |
|
||
|------|----------|---------|------|
|
||
| Role | 10s 超时 | N/A | ❌ |
|
||
| CSS | 8s 超时 | 8s 超时 | ❌ |
|
||
| Text | ~1s | ~1s | ✅ |
|
||
|
||
**优化**:
|
||
```python
|
||
# 抖音/B站:Text 策略优先
|
||
if self.platform in ("douyin", "bilibili"):
|
||
qr_element = await self._try_text_strategy(page) # 优先
|
||
if not qr_element:
|
||
await page.wait_for_selector(..., timeout=3000) # CSS 备用
|
||
else:
|
||
# 其他平台保持 CSS 优先
|
||
```
|
||
|
||
**效果**:
|
||
- 抖音登录二维码获取:~23s → ~5s
|
||
- B站登录二维码获取:~13s → ~5s
|
||
|
||
### 3. 发布成功审核提示
|
||
|
||
**问题**:发布成功后,用户不知道需要审核
|
||
|
||
**优化**:
|
||
- 后端消息改为 "发布成功,待审核"
|
||
- 前端增加提示 "⏳ 审核一般需要几分钟,请耐心等待"
|
||
- 发布结果 10 秒后自动消失
|
||
|
||
---
|
||
|
||
## 📁 修改文件列表
|
||
|
||
### 后端
|
||
|
||
| 文件 | 修改内容 |
|
||
|------|----------|
|
||
| `app/api/publish.py` | 输入验证、平台常量、文档改进 |
|
||
| `app/services/publish_service.py` | 类型提示、平台 enabled 标记 |
|
||
| `app/services/qr_login_service.py` | **策略顺序优化**、超时缩短 |
|
||
| `app/services/uploader/base_uploader.py` | 类型提示 |
|
||
| `app/services/uploader/bilibili_uploader.py` | **发布消息改为"待审核"** |
|
||
| `app/services/uploader/douyin_uploader.py` | **发布消息改为"待审核"** |
|
||
| `app/services/uploader/xiaohongshu_uploader.py` | **发布消息改为"待审核"** |
|
||
|
||
### 前端
|
||
|
||
| 文件 | 修改内容 |
|
||
|------|----------|
|
||
| `src/app/publish/page.tsx` | **加载动画、审核提示、结果自动消失** |
|
||
|
||
---
|
||
|
||
## ✅ 完成总结
|
||
|
||
1. **发布功能验证通过** - B站/抖音登录和发布均正常
|
||
2. **代码健壮性提升** - 资源清理、超时保护、异常处理
|
||
3. **代码可维护性** - 完整类型提示、常量化配置
|
||
4. **服务器兼容性** - 小红书 headless 模式修复
|
||
5. **用户体验优化** - 加载状态、策略顺序、审核提示
|
||
|
||
---
|
||
|
||
## 🔐 用户认证系统规划
|
||
|
||
> 规划完成,待下一阶段实施
|
||
|
||
### 技术方案
|
||
|
||
| 项目 | 方案 |
|
||
|------|------|
|
||
| 认证框架 | FastAPI + JWT (HttpOnly Cookie) |
|
||
| 数据库 | Supabase (PostgreSQL + RLS) |
|
||
| 管理员 | .env 预设 + startup 自动初始化 |
|
||
| 授权期限 | expires_at 字段,可设定有效期 |
|
||
| 单设备登录 | 后踢前模式 + Session Token 强校验 |
|
||
| 账号隔离 | 规范化 Cookie 路径 `user_data/{user_id}/` |
|
||
|
||
### 安全增强
|
||
|
||
1. **HttpOnly Cookie** - 防 XSS 窃取 Token
|
||
2. **Session Token 校验** - JWT 包含 session_token,每次请求验证
|
||
3. **Startup 初始化管理员** - 服务启动自动创建
|
||
4. **RLS 最后防线** - Supabase 行级安全策略
|
||
5. **Cookie 路径规范化** - UUID 格式验证 + 白名单平台校验
|
||
|
||
### 数据库表
|
||
|
||
```sql
|
||
-- users (用户)
|
||
-- user_sessions (单设备登录)
|
||
-- social_accounts (社交账号绑定)
|
||
```
|
||
|
||
> 详细设计见 [implementation_plan.md](file:///C:/Users/danny/.gemini/antigravity/brain/06e7632c-12c6-4e80-b321-e1e642144560/implementation_plan.md)
|
||
|
||
### 后端实现进度
|
||
|
||
**状态**:✅ 核心模块完成
|
||
|
||
| 文件 | 说明 | 状态 |
|
||
|------|------|------|
|
||
| `requirements.txt` | 添加 supabase, python-jose, passlib | ✅ |
|
||
| `app/core/config.py` | 添加 Supabase/JWT/管理员配置 | ✅ |
|
||
| `app/core/supabase.py` | Supabase 客户端单例 | ✅ |
|
||
| `app/core/security.py` | JWT + 密码 + HttpOnly Cookie | ✅ |
|
||
| `app/core/paths.py` | Cookie 路径规范化 | ✅ |
|
||
| `app/core/deps.py` | 依赖注入 (当前用户/管理员) | ✅ |
|
||
| `app/api/auth.py` | 注册/登录/登出 API | ✅ |
|
||
| `app/api/admin.py` | 用户管理 API | ✅ |
|
||
| `app/main.py` | startup 初始化管理员 | ✅ |
|
||
| `database/schema.sql` | Supabase 数据库表 + RLS | ✅ |
|
||
|
||
### 前端实现进度
|
||
|
||
**状态**:✅ 核心页面完成
|
||
|
||
| 文件 | 说明 | 状态 |
|
||
|------|------|------|
|
||
| `src/shared/lib/auth.ts` | 认证工具函数 | ✅ |
|
||
| `src/app/login/page.tsx` | 登录页 | ✅ |
|
||
| `src/app/register/page.tsx` | 注册页 | ✅ |
|
||
| `src/app/admin/page.tsx` | 管理后台 | ✅ |
|
||
| `src/proxy.ts` | 路由保护 | ✅ |
|
||
|
||
### 账号隔离集成
|
||
|
||
**状态**:✅ 完成
|
||
|
||
| 文件 | 修改内容 | 状态 |
|
||
|------|----------|------|
|
||
| `app/services/publish_service.py` | 重写支持 user_id 隔离 Cookie | ✅ |
|
||
| `app/api/publish.py` | 添加认证依赖,传递 user_id | ✅ |
|
||
|
||
**Cookie 存储路径**:
|
||
- 已登录用户: `user_data/{user_id}/cookies/{platform}_cookies.json`
|
||
- 未登录用户: `app/cookies/{platform}_cookies.json` (兼容旧版)
|
||
|
||
---
|
||
|
||
## 🔐 用户认证系统实现 (2026-01-23)
|
||
|
||
### 问题描述
|
||
为了支持多用户管理和资源隔离,需要实现一套完整的用户认证系统,取代以前的单用户模式。要求:
|
||
- 使用 Supabase 作为数据库
|
||
- 支持注册、登录、登出
|
||
- 管理员审核机制 (is_active)
|
||
- 单设备登录限制
|
||
- HttpOnly Cookie 存储 Token
|
||
|
||
### 解决方案
|
||
|
||
#### 1. 数据库设计 (Supabase)
|
||
创建了三张核心表:
|
||
- `users`: 存储邮箱、密码哈希、角色、激活状态
|
||
- `user_sessions`: 存储 Session Token,实现单设备登录 (后踢前)
|
||
- `social_accounts`: 社交账号绑定信息 (B站/抖音Cookie)
|
||
|
||
#### 2. 后端实现 (FastAPI)
|
||
- **依赖注入** (`deps.py`): `get_current_user` 自动验证 Token 和 Session
|
||
- **安全模块** (`security.py`): JWT 生成与验证,密码 bcrypt 哈希
|
||
- **路由模块** (`auth.py`):
|
||
- `/register`: 注册后默认为 `pending` 状态
|
||
- `/login`: 验证通过后生成 JWT 并写入 HttpOnly Cookie
|
||
- `/me`: 获取当前用户信息
|
||
|
||
#### 3. 部署方案
|
||
- 采用 Supabase 云端免费版
|
||
- 为了防止 7 天不活跃暂停,配置了 GitHub Actions / Crontab 自动保活
|
||
- 创建了独立的部署文档 `Docs/AUTH_DEPLOY.md`
|
||
|
||
### 结果
|
||
- ✅ 成功实现了完整的 JWT 认证流程
|
||
- ✅ 管理员可以控制用户激活状态
|
||
- ✅ 实现了安全的无感 Token 刷新 (Session Token)
|
||
- ✅ 敏感配置 (Supabase Key) 通过环境变量管理
|
||
|
||
---
|
||
|
||
## 🔗 相关文档
|
||
|
||
- [用户认证系统实现计划](file:///C:/Users/danny/.gemini/antigravity/brain/06e7632c-12c6-4e80-b321-e1e642144560/implementation_plan.md)
|
||
- [代码审核报告](file:///C:/Users/danny/.gemini/antigravity/brain/a28bb1a6-2929-4c55-b837-c989943844e1/walkthrough.md)
|
||
- [部署手册](file:///d:/CodingProjects/Antigravity/ViGent2/Docs/DEPLOY_MANUAL.md)
|
||
|
||
---
|
||
|
||
## 🛠️ 部署调试记录 (2026-01-23)
|
||
|
||
### 1. 服务启动方式修正
|
||
- **问题**: pm2 直接启动 python/uvicorn 会导致 `SyntaxError` (Node.js 尝试解释 Python)
|
||
- **解决**: 改用 `.sh` 脚本封装启动命令
|
||
|
||
### 2. 依赖缺失与兼容性
|
||
- **问题 1**: `ImportError: email-validator is not installed` (Pydantic 依赖)
|
||
- **修复**: 添加 `email-validator>=2.1.0`
|
||
- **问题 2**: `AttributeError: module 'bcrypt' has no attribute '__about__'` (Passlib 兼容性)
|
||
- **修复**: 锁定 `bcrypt==4.0.1`
|
||
|
||
### 3. 前端生产环境构建
|
||
- **问题**: `Error: Could not find a production build`
|
||
- **解决**: 启动前必须执行 `npm run build`
|
||
|
||
### 4. 性能调优
|
||
- **现象**: SSH 远程连接出现显著卡顿
|
||
- **排查**: `vigent2-latentsync` 启动时模型加载占用大量系统资源
|
||
- **优化**: 生产环境建议按需开启 LatentSync 服务,或确保服务器 IO/带宽充足。停止该服务后 SSH 恢复流畅。
|
||
|
||
|