# 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/lib/auth.ts` | 认证工具函数 | ✅ | | `src/app/login/page.tsx` | 登录页 | ✅ | | `src/app/register/page.tsx` | 注册页 | ✅ | | `src/app/admin/page.tsx` | 管理后台 | ✅ | | `src/middleware.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 恢复流畅。