Files
ViGent2/Docs/DevLogs/Day31.md
Kevin Wong 23ff4ff86e 更新
2026-03-04 14:07:54 +08:00

527 lines
30 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
## 文档分层收敛 + 音色试听修复 + 录音弹窗重构 + 弹窗体系统一 (Day 31)
### 概述
今天的工作聚焦四件事:
1. 清理并收敛根目录文档README/DEV 职责边界、历史内容归档、参数描述与代码对齐)
2. 完成 EdgeTTS 音色列表「一键试听」能力,并修复浏览器端试听失败问题
3. 重构声音克隆录音交互:录音入口下沉到参考音频区域底部右侧,流程改为弹窗
4. 抽离统一弹窗基座 `AppModal`,将主要弹窗迁移到同一视觉和交互规范
---
## ✅ 1) 文档体系与内容一致性优化
### 1.1 README / DEV 边界明确
-`FRONTEND_README.md``BACKEND_README.md``FRONTEND_DEV.md``BACKEND_DEV.md` 增加「文档定位」
- README 只保留稳定说明功能、接口、运行DEV 保留规范约束、分层、Checklist
- 将 README 中偏日志化内容(如 Day 标注)清理为稳定表述
### 1.2 部署与参数文档对齐当前代码
- 将唇形路由阈值文案统一为阈值驱动,并以当前 `.env` 示例 `100` 为参考
- 修正旧编码描述(将 MuseTalk 合成描述对齐为 rawvideo 管道 + `libx264`
- 修复文档中不存在的 `.env.example` 指引,改为基于 `backend/.env` 的说明
- 将 Qwen3-TTS 文档标注为「历史归档(已停用)」并指向 CosyVoice 3.0
---
## ✅ 2) 音色试听能力落地与故障修复
### 2.1 功能实现
- 音色下拉项新增试听按钮(播放/暂停/加载态)
- 新增后端试听接口:`/api/videos/voice-preview`
- 试听文本按音色 locale 自动选择固定示例文案9 国语言 + 中文兜底)
### 2.2 兼容与稳定性调整
- 保留 `POST /api/videos/voice-preview`(兼容)
- 新增 `GET /api/videos/voice-preview?voice=...`,前端改为直接播放 GET 音频流,减少浏览器自动播放策略干扰
```python
@router.get("/voice-preview")
async def preview_voice_get(voice: str, current_user: dict = Depends(get_current_user)):
voice_value = voice.strip()
if not voice_value:
raise HTTPException(status_code=400, detail="voice 不能为空")
text = _get_preview_text_for_voice(voice_value)
return await _render_voice_preview(voice=voice_value, text=text)
```
### 2.3 本次线上问题结论(已修复)
- 现象:浏览器端试听请求 404
- 根因:新增 GET 路由后,后端进程未重启,运行中的代码仍是旧版本
- 处理:`pm2 restart vigent2-backend` 后路由生效
- 补充:`curl` 返回 401无 auth cookie属于预期浏览器同源请求会自动带 cookie
---
## ✅ 3) 录音交互重构(声音克隆)
### 3.1 入口重排
- 去掉参考音频面板内的独立录音大块区域
- 将「上传音频 / 录音」入口放到「我的参考音频」区域底部右侧
### 3.2 录音流程改为弹窗
- 录音弹窗支持:开始录音 / 停止录音 / 状态计时 / 试听
- 保留并强化「使用此录音」和「弃用本次录音」
- 关闭弹窗时若仍在录音,会先停止录音再关闭
- 修正弹窗挂载位置:从局部组件渲染改为 `AppModal` Portal 到 `document.body`,确保是全页面弹窗体验
- 参考音频区按钮文案更新:`录音` -> `在线录音`
### 3.4 文案区按钮视觉统一
- 统一「文案提取与编辑」区按钮尺寸与圆角(`px-3 py-1.5 text-xs rounded-lg`
-`AI智能改写``保存文案` 按钮改为与上传/在线录音同等级的视觉规格
- 同步统一图标尺寸与禁用态样式,消除“底部按钮偏小”问题
### 3.5 录音试听条 UI 美化
- 将录音完成后的原生白色 `<audio controls>` 替换为项目深色风格的自定义试听条
- 新试听条包含:播放/暂停按钮、进度拖拽、当前时长/总时长显示
- 统一配色到当前页面(深色底 + 绿色强调),避免与整体 UI 风格割裂
### 3.6 录音上传关闭时机优化
- 原逻辑:点击「使用此录音」后,需等待上传+识别完成才关闭弹窗(体感卡顿)
- 新逻辑:点击后立即关闭弹窗,上传/识别在后台继续进行
- 状态反馈仍在参考音频区域显示(上传识别中的提示 + 失败错误提示)
---
## ✅ 5) 发布管理抖音登录「无法获取二维码」修复
### 问题定位
- 现象:发布管理中点击抖音登录,前端提示无法获取二维码
- 后端日志显示根因:
- `Page.goto: Timeout 30000ms exceeded`
- 导航目标:`https://creator.douyin.com/`
- 等待条件:`wait_until="networkidle"`
### 修复方案
- 抖音登录页改为与微信一致的更稳策略:`wait_until="domcontentloaded"`
- 对抖音导航超时增加容错:即使 `goto` 超时,也继续执行二维码提取流程(避免长连接导致误失败)
### 验证
- 本地接口冒烟:`POST /api/publish/login/douyin` 返回 `success=true` 且包含 `qr_code`
- 已重启后端进程使修复生效:`pm2 restart vigent2-backend`
### 3.3 状态逻辑补齐
- 新增 `discardRecording()`:清空本次录音与计时
- 开始新录音前先清空旧录音,避免旧状态残留
---
## ✅ 4) 弹窗 UI/UX 统一AppModal
新增统一弹窗基座:`frontend/src/shared/ui/AppModal.tsx`
- 统一遮罩:`bg-black/80 + backdrop-blur-sm`
- 统一容器:深色半透明背景、`border-white/10``rounded-2xl`、重阴影
- 统一 Header标题/副标题/关闭按钮
- 统一行为ESC 关闭、背景滚动锁定、按需控制 overlay 点击关闭
- 统一挂载:通过 Portal 渲染到 `document.body`,避免出现“看起来只在配音区弹出”的层叠问题
- 统一可访问性:补齐 `role="dialog"` + `aria-modal="true"`
- 统一焦点管理:打开弹窗自动聚焦,关闭后恢复到打开前焦点元素
- 统一滚动锁计数:支持多弹窗并存,避免一个弹窗关闭后提前恢复页面滚动
已迁移弹窗:
- 视频预览(`VideoPreviewModal`
- 文案提取(`ScriptExtractionModal`
- AI 改写(`RewriteModal`
- 截取设置(`ClipTrimmer`
- 录音弹窗(`RefAudioPanel` 内)
- 修改密码弹窗(`AccountSettingsDropdown`
- 发布管理扫码登录弹窗(`PublishPage` 内 QR 登录弹窗)
---
## ✅ 6) 微信视频号登录二维码观感优化(“能扫但像被截断”)
### 问题现象
- 微信视频号登录二维码可扫码成功,但视觉上像“边缘不完整/被切掉”,观感不佳
### 修复方案
- 后端二维码提取策略增强(`qr_login_service.py`
- 优先导出二维码原始 PNG 数据(`canvas.toDataURL('image/png')` / `img[data:image/png]`),减少二次截图导致的边缘损失
- 微信回退截图时改为“按二维码 bbox 外扩留白裁剪”,避免贴边截取带来的不完整感
- 仅接受 PNG Data URL避免把非 PNG如 SVG 片段)直接当二维码返回造成边角异常
- 前端扫码弹窗展示优化(`PublishPage.tsx`
- 取消二维码图片本体圆角裁切,改为外层白底容器 + 内边距(模拟 quiet zone
- 同步调整二维码显示宽度与边框,提升完整感与观感一致性
### 验证
- 本地接口冒烟:`POST /api/publish/login/weixin` 返回 `success=true` 且包含 `qr_code`
- 解码后图片尺寸为 `1000x1000`,扫码仍正常
- 前后端进程已重启使修复生效:
- `pm2 restart vigent2-frontend`
- `pm2 restart vigent2-backend`
---
## ✅ 7) 发布流程性能与日志可读性优化(双平台发布场景)
### 7.1 发布请求并发优化(前端)
- 原逻辑:发布页按平台串行 `for...of await`,多平台总耗时为各平台耗时累加
- 新逻辑:引入受限并发执行(并发度=2两平台可并行发布显著缩短总等待时长
- 结果列表仍按用户选择的平台顺序回填,避免并发返回导致顺序抖动
### 7.2 微信上传日志噪声优化(后端)
- 原逻辑:`set_input_files` 后若立即读不到 `input.files[0]` 就直接打 warning`[weixin][file_input] empty`
- 新逻辑:先轮询确认“是否已进入上传中状态”,再决定是否告警;非最后一次重试只记 info最后一次才 warning
- 效果:减少误报警(实际已开始上传时不再刷 warning排障日志更干净
### 验证
- `python -m py_compile backend/app/services/uploader/weixin_uploader.py`
- `npm run build`frontend
- 服务重启:`pm2 restart vigent2-frontend && pm2 restart vigent2-backend`
---
## ✅ 8) 小红书发布链路对齐改造(启动模式 / Cookie 格式 / 成功截图)
### 8.1 启动模式与反检测参数对齐
-`config.py` 新增小红书 Playwright 配置:
- `XIAOHONGSHU_HEADLESS_MODE`(默认 `headless-new`
- `XIAOHONGSHU_USER_AGENT / LOCALE / TIMEZONE_ID`
- `XIAOHONGSHU_CHROME_PATH / BROWSER_CHANNEL`
- `XIAOHONGSHU_FORCE_SWIFTSHADER / DEBUG_ARTIFACTS`
- `xiaohongshu_uploader.py` 改为与抖音/微信一致的可配置启动策略,并保留反检测基础参数(`--disable-blink-features=AutomationControlled`
### 8.2 小红书 uploader 重构增强
- 重写小红书 uploader 主流程(参考抖音/微信模式):
- 上传入口/文件 input 多选择器回退
- 上传中/成功/失败状态轮询判定
- 标题与正文/话题填充容错
- 发布按钮多选择器与可点击检查
- 发布成功判定从“仅 URL”增强为“多信号组合”
- URL 跳转判定
- 页面成功/失败文案判定
- 发布 API 响应监听(`publish` / `note create` 类接口)
- 发布成功后补齐截图能力并返回 `screenshot_url`(路径格式与抖音/微信一致):
- `/api/publish/screenshot/{filename}`
### 8.3 Cookie 保存格式统一
- `publish_service.save_cookie_string()` 调整:
- `bilibili` 继续使用原有简化 cookie dict兼容既有上传库
-`bilibili` 平台统一保存为 Playwright `storage_state`
- `{"cookies": [...], "origins": []}`
- 补充平台默认 domain抖音/微信/小红书),使 cookie 文件可直接用于 `browser.new_context(storage_state=...)`
### 8.4 验证与生效
- `python -m py_compile backend/app/core/config.py backend/app/services/publish_service.py backend/app/services/uploader/xiaohongshu_uploader.py`
- `pm2 restart vigent2-backend`
---
## ✅ 9) 小红书登录二维码修复(默认短信登录需先切换)
### 问题现象
- 小红书创作平台 `https://creator.xiaohongshu.com/` 默认落在“短信登录”视图
- 二维码需要先点击右上角切换图标才会出现,导致后端直接按二维码选择器抓取失败
### 修复方案(`qr_login_service.py`
- 新增 `_ensure_xiaohongshu_qr_mode()`
- 先检测是否处于短信登录(`input[placeholder*='手机号']`
- 自动点击登录卡片右上角切换图标(优先稳定选择器,失败后用几何位置兜底)
- 切换后等待二维码渲染再进入提取流程
- 扩展小红书二维码选择器集合:
- 增加登录卡片内二维码图片选择器(包含当前页面结构)
- 保留通用 `img[src*='qr'/'qrcode']` 兜底
- 提高小红书候选过滤阈值(`min_side=120`),避免误选右上角切换小图标
- 文本策略补充小红书关键词(如 `APP扫一扫登录`
### 验证
- 本地接口冒烟:`POST /api/publish/login/xiaohongshu` 返回 `success=true``qr_code` 非空
- 后端日志确认修复链路生效:
- `已点击登录方式切换,等待二维码渲染`
- `策略1(CSS): 匹配成功`
---
## ✅ 10) 小红书发布上传阶段修复(“发布笔记 - 上传视频”场景)
### 问题现象
- 小红书发布在“上传视频”阶段失败,页面停留在发布页,前端提示发布失败
- 后端日志显示 `set_input_files` 触发成功,但短时间内未检测到上传状态,导致重复触发上传并误判失败
- 进一步定位到上传文件实际是 Supabase 本地对象文件(无后缀),日志里 `file_input type=` 为空,平台可能无法正确识别视频 MIME
### 修复方案(`xiaohongshu_uploader.py`
- 新增上传启动探测窗口 `UPLOAD_SIGNAL_TIMEOUT=12s`
- `set_input_files` 成功后给上传状态留出启动时间
- 检测到“上传中/处理中/转码中”等信号即进入后续上传轮询
- 启动窗口内未出现明显信号时,不再立即判失败,转入主上传监控阶段继续等待
- 修正失败判定词:
- 从失败关键词中移除 `重新上传`(该文案在小红书页面常作为正常状态/操作入口,不能直接视为失败)
- 增补上传文件诊断日志:
- 输出 `file_input` 选中文件名/大小/类型,便于确认文件是否真正注入 input
- 上传失败命中时记录明确告警日志,便于线上快速定位
- 增加无后缀视频文件兜底:
- 若原文件无后缀且父目录名带后缀(如 `xxx.mp4/<uuid>`),自动在 `/tmp/vigent_uploads` 生成同名临时文件(硬链接/软链接/复制兜底)
- 上传改用带后缀临时文件,提升站点 MIME 识别稳定性
- 任务结束后自动清理临时上传文件
### 10.1 二次定位与加固(卡住复现后)
- 复现日志显示:即使传入了带后缀临时路径,`file_input` 中仍出现无后缀文件名,且长时间停留在 `等待上传状态...`
- 根因进一步确认:此前在跨设备场景下会走 `symlink` 回退,浏览器实际取到原始目标文件名(无后缀),导致站点识别失败
- 加固修复:
- 去掉 `symlink` 回退,仅保留 `hardlink -> copy`,确保最终上传文件名稳定带 `.mp4`
- 新增 `file_input` 文件名后缀一致性校验:若与预期后缀不一致,直接重试并在最终失败时提前返回(不再无意义长时间等待)
- 新增上传空转超时保护(`UPLOAD_IDLE_TIMEOUT=90s`):长时间无有效上传信号时提前失败并保留调试截图,避免前端“看起来卡死”
- 优化失败文案为“未能触发有效视频上传,请确认发布页状态及视频文件格式”
### 10.2 实时发布验证(修复后)
- 重新发起 `POST /api/publish`(小红书),后端完整走通上传+发布,接口返回 `200`
- 本次实测耗时约 `45.77s`,属于上传与发布等待区间内的正常时长
- 发布成功截图可访问:`GET /api/publish/screenshot/xiaohongshu_success_20260303_115944_633.png` 返回 `200`
- 关键日志链路:`正在上传` -> `已设置上传文件` -> `等待发布结果` -> `Cookie 更新完毕`
### 验证
- `python -m py_compile backend/app/services/uploader/xiaohongshu_uploader.py`
- `pm2 restart vigent2-backend`
- `curl http://127.0.0.1:8006/health` 返回 `{"status":"ok"}`
---
## ✅ 11) 首页「AI生成标题标签」按钮位置优化迁移到四、标题与字幕
### 设计结论
-`AI生成标题标签` 从「一、文案提取与编辑」迁移到「四、标题与字幕」
- 标题区改为两行:
- 第一行:`四、标题与字幕` 标题 + 右侧 `AI生成标题标签`
- 第二行:右对齐放置 `标题短暂显示/常驻显示` + `预览样式`
- 显示语义补充:`标题短暂显示/常驻显示` 对主标题与副标题统一生效(常驻=主/副标题都常驻)
- 不额外增加提示文案,保持界面简洁
- `AI生成标题标签` 外观对齐 `在线录音` 按钮的圆角与尺寸(`rounded-lg` + 同级按钮尺寸),颜色保留原蓝色渐变
### 结果
- 标题相关动作集中到同一板块,避免用户在「一」和「四」之间来回跳转
- 行内层级更明确AI 动作在标题同层,配置项与预览在下一行
- AI 按钮圆角与尺寸更柔和,配色仍保持原蓝色渐变,视觉更统一
### 验证
- `npm run build`frontend
- `pm2 restart vigent2-frontend`
---
## ✅ 12) 文案编辑框右下角扩展角标(弹出大编辑器)
### 设计与实现
- 在「一、文案提取与编辑」主输入框右下角新增角标按钮(点击后打开扩展编辑器)
- 扩展编辑器使用 `AppModal`,提供更大编辑空间(高约 `66vh`
- 主输入框与弹窗内输入框共享同一份 `text` 状态,双向实时同步
- 为避免角标遮挡正文,主输入框增加右下内边距(`pr-6 pb-6`
- 角标样式进一步极简化:仅保留双箭头图标,去掉外框容器并贴近输入框边缘
- 角标位置微调为更协调的“上移+右移”:`right-0.5 bottom-2`,并固定点击区域 `h-5 w-5`
- 修复扩展编辑输入焦点丢失:`AppModal` 改为使用 `onCloseRef` 处理 ESC避免父组件重渲染时 effect 误清理导致 textarea 失焦
- 移除扩展编辑输入框紫色聚焦边框,改为中性边框高亮(`focus:border-white/25`
### 验证
- `npm run build`frontend
- `pm2 restart vigent2-frontend`
---
## ✅ 13) 站点 Icon 替换(使用 `Temp/video.png`
### 变更
- 将提供的 `Temp/video.png` 转换并替换为站点图标资源
- 新增 `frontend/src/app/icon.png`Next App Router icon 资源)
- 更新 `frontend/src/app/favicon.ico`16/32/48/64 多尺寸)
### 验证
- `npm run build`frontend
- 构建产物包含 `/icon.png` 路由 ✅
- `pm2 restart vigent2-frontend`
---
## ✅ 14) 发布后工作区清理链路加固CleanupContext + `/api/videos/cleanup`
### 14.1 功能落地
- 发布页新增“全平台发布成功后清理引导”链路:
- 全平台成功:触发 `CleanupModal`
- 任一平台失败:保持原内联结果展示
- `CleanupModal` 支持展示:成功平台列表、成功截图、下载视频备份、一键清理
- 清理状态 `cleanup_pending` 持久化到 localStorage刷新/跳转后可恢复
### 14.2 稳定性与防锁死优化
- 后端删除能力改为“异常上抛”,避免静默吞错导致前端误判清理成功
- 清理接口改为严格成功语义:
- 视频和配音删除都成功才返回 success
- 任一删除失败直接返回错误,前端保留弹窗并允许重试
- 前端清理动作改为“先后端、后本地”:
- 后端失败:不清本地、不关弹窗
- 后端成功:再清理本地输入字段并关闭弹窗
- 后端成功清理后前端派发 `vigent:workspace-cleared` 事件,发布页就地重置标题/标签输入态(无需手动刷新)
- 连续失败达到阈值3 次)后显示“暂不清理,继续使用”,避免异常环境下永久阻塞
- 清理弹窗增加 24h 过期,避免跨天残留状态
- 用户切换/登出时重置 cleanup 状态,避免旧账号状态串扰
### 14.3 清理范围口径
- 仅清理输入内容字段:
- 首页:文案/标题/副标题
- 发布页:标题/标签
- 保留用户偏好字段样式、字号、边距、模型、BGM 等)
### 验证
- `python -m py_compile backend/app/services/storage.py backend/app/modules/videos/service.py backend/app/modules/generated_audios/service.py backend/app/modules/videos/router.py`
- `npm run build`frontend
- `pm2 restart vigent2-backend && pm2 restart vigent2-frontend`
- `curl http://127.0.0.1:8006/health` 返回 `{"status":"ok"}`
---
## 📁 今日主要修改文件
| 文件 | 改动 |
|------|------|
| `backend/app/modules/videos/router.py` | 新增/增强 `voice-preview` GET+POST试听文本 locale 路由,临时文件清理;新增 `POST /api/videos/cleanup` 严格成功语义 |
| `backend/app/modules/videos/service.py` | 新增批量删除生成视频能力;返回 `(deleted, failed)` 供 cleanup 路由判定 |
| `backend/app/modules/generated_audios/service.py` | 新增批量删除预生成配音能力;返回 `(deleted, failed)` 供 cleanup 路由判定 |
| `backend/app/services/storage.py` | `delete_file()` 改为异常上抛,避免删除失败静默吞错造成“假成功” |
| `backend/app/modules/videos/schemas.py` | 新增 `VoicePreviewRequest` |
| `frontend/src/features/home/ui/VoiceSelector.tsx` | 音色下拉增加试听按钮,改为 GET 音频流播放 |
| `frontend/src/features/home/model/useHomeController.ts` | 录音状态重置、`discardRecording` |
| `frontend/src/features/home/ui/HomePage.tsx` | 透传录音弃用动作;将 `AI生成标题标签` 事件改为传入 `TitleSubtitlePanel` |
| `frontend/src/features/home/ui/RefAudioPanel.tsx` | 上传/录音入口重排;录音改弹窗;使用/弃用流程 |
| `frontend/src/features/home/ui/ScriptEditor.tsx` | 文案编辑区按钮视觉统一;移除 `AI生成标题标签`(职责回归标题板块);新增输入框右下角扩展角标与大编辑弹窗;角标改为双箭头极简贴边样式并微调到 `right-0.5 bottom-2`;输入框去除紫色聚焦边框 |
| `frontend/src/features/home/ui/TitleSubtitlePanel.tsx` | 标题区改为“首行标题+AI、次行右对齐设置+预览”AI按钮外观对齐在线录音按钮软圆角 |
| `frontend/src/features/home/ui/RefAudioPanel.tsx` | 录音完成试听条改为自定义深色播放器(替换原生白色控制条) |
| `frontend/src/features/home/ui/RefAudioPanel.tsx` | 使用录音后弹窗立即关闭,上传识别后台进行(提升交互流畅度) |
| `frontend/src/features/publish/model/usePublishController.ts` | 发布改为受限并发(并发度=2全平台发布成功时触发 `triggerCleanup()`,失败保持内联结果;监听 `workspace-cleared` 事件就地清空发布输入态 |
| `frontend/src/shared/contexts/CleanupContext.tsx` | 新增发布后清理弹窗与持久化状态;失败不关闭/不清本地、3 次失败可跳过、24h 过期、用户切换复位;清理范围收敛为输入内容字段;成功清理后派发 `workspace-cleared` 事件 |
| `frontend/src/app/layout.tsx` | 在 `TaskProvider` 内挂载 `CleanupProvider`,确保全局可触发发布后清理弹窗 |
| `backend/app/core/config.py` | 新增小红书 Playwright 配置headless/UA/locale/timezone/chrome/debug |
| `backend/app/services/uploader/xiaohongshu_uploader.py` | 按抖音/微信模式重构补充上传启动容错窗口、无后缀文件兜底hardlink/copy、后缀一致性校验、空转超时保护与上传诊断日志 |
| `backend/app/services/publish_service.py` | `save_cookie_string` 非 bilibili 统一存储为 Playwright `storage_state`;小红书 uploader 透传 `user_id` |
| `backend/app/services/qr_login_service.py` | 抖音导航超时容错 + 微信二维码提取增强 + 小红书登录自动切换到扫码模式并提取二维码 |
| `backend/app/services/uploader/weixin_uploader.py` | `file_input empty` 告警策略优化:先检测上传信号,非最后一次重试降级为 info |
| `frontend/src/shared/ui/AppModal.tsx` | 统一弹窗组件 + 无障碍语义 + 焦点管理 + 多弹窗滚动锁计数;新增 `onCloseRef` 避免回调引用变化引发的意外失焦 |
| `frontend/src/components/VideoPreviewModal.tsx` | 迁移到 `AppModal` |
| `frontend/src/features/home/ui/ScriptExtractionModal.tsx` | 迁移到 `AppModal` |
| `frontend/src/features/home/ui/RewriteModal.tsx` | 迁移到 `AppModal` |
| `frontend/src/features/home/ui/ClipTrimmer.tsx` | 迁移到 `AppModal` |
| `frontend/src/components/AccountSettingsDropdown.tsx` | 修改密码弹窗迁移到 `AppModal` |
| `frontend/src/app/icon.png` | 新增站点 icon 资源(来自 `Temp/video.png` |
| `frontend/src/app/favicon.ico` | 替换站点 favicon`video.png` 转换为多尺寸 ico |
| `frontend/src/features/publish/ui/PublishPage.tsx` | 扫码登录QR弹窗迁移到 `AppModal` + 二维码白底留白容器优化(避免边缘观感被裁) |
| `Docs/FRONTEND_DEV.md` | 新增统一弹窗规范AppModal和录音交互规范补充文案扩展编辑也统一走 AppModal新增 CleanupContext 清理策略规范 |
| `Docs/FRONTEND_README.md` | 增补录音入口与弹窗交互说明;明确“标题常驻显示”对主/副标题同时生效;补充文案输入框扩展编辑器说明;补充发布后清理弹窗失败兜底说明 |
| `Docs/BACKEND_README.md` | 增补 `voice-preview` 接口说明;更新发布 API 路径(`/login/{platform}` 等)并链接发布专项文档;补充 `title_display_mode` 对主/副标题统一生效说明;新增 `/api/videos/cleanup` 接口说明 |
| `Docs/BACKEND_DEV.md` | 更新后端规范中的发布器覆盖范围与小红书配置项;补充发布专项文档指引;补充 `title_display_mode` 主/副标题统一生效约定;新增 cleanup 严格成功语义约定 |
| `Docs/PUBLISH_DEPLOY.md` | 新增多平台发布专项文档(登录实现、自动化发布流程、部署要点与排障);补充“发布成功后清理联动”说明 |
| `Docs/DEPLOY_MANUAL.md` | 部署参数与扫码说明补充小红书要点;新增发布专项文档入口 |
| `README.md` | 文档中心新增 `PUBLISH_DEPLOY.md` 入口;发布结果可视化描述补齐小红书;补充发布成功后工作区清理引导说明 |
| `Docs/TASK_COMPLETE.md` | 新增 Day31 任务汇总,更新 Current 标签与更新时间;补充发布后清理链路加固条目 |
| `Docs/DOC_RULES.md` | 增补“发布相关三检”(路由真值/专项文档/入口回写)、敏感信息处理规范,更新工具规范为 `Read/Grep/apply_patch`,并对齐 TASK_COMPLETE 检查清单 |
| `Docs/SUBTITLE_DEPLOY.md` | 与当前阈值/参数说明对齐 |
| `Docs/LATENTSYNC_DEPLOY.md` | 与当前阈值/参数说明对齐 |
| `Docs/COSYVOICE3_DEPLOY.md` | TTS 部署说明与当前运行路径对齐 |
| `Docs/QWEN3_TTS_DEPLOY.md` | 标注为历史归档并指向 CosyVoice 3.0 |
---
## 🔍 验证记录
- `python -m py_compile backend/app/modules/videos/router.py backend/app/modules/videos/schemas.py`
- `python -m py_compile backend/app/services/qr_login_service.py`
- `python -m py_compile backend/app/services/uploader/weixin_uploader.py`
- `python -m py_compile backend/app/core/config.py backend/app/services/publish_service.py backend/app/services/uploader/xiaohongshu_uploader.py`
- `POST /api/publish/login/xiaohongshu` 冒烟返回 `success=true` + `qr_code`
- `python -m py_compile backend/app/services/uploader/xiaohongshu_uploader.py`(上传阶段修复后)✅
- `pm2 restart vigent2-backend`(上传阶段修复后)✅
- `curl http://127.0.0.1:8006/health` 返回 `{"status":"ok"}`
- `backend/venv/bin/python` 本地探针验证 `_prepare_upload_file()`:临时文件非 symlink、后缀 `.mp4`、清理成功 ✅
- 小红书发布实测:`POST /api/publish` 返回 `200``Duration: 45.77s`)且成功截图接口返回 `200`
- 新增 `Docs/PUBLISH_DEPLOY.md`(抖音/微信/B站/小红书登录与发布实现说明)✅
- `npm run build`frontend
- 站点 icon 替换后构建通过,产物包含 `/icon.png` 路由 ✅
- `pm2 restart vigent2-frontend`icon 替换后)✅
- `python -m py_compile backend/app/services/storage.py backend/app/modules/videos/service.py backend/app/modules/generated_audios/service.py backend/app/modules/videos/router.py`cleanup 链路加固后)✅
- `npm run build`CleanupContext 优化后)✅
- `pm2 restart vigent2-backend && pm2 restart vigent2-frontend`cleanup 链路加固后)✅
- `curl http://127.0.0.1:8006/health` 返回 `{"status":"ok"}`cleanup 链路加固后)✅
- `POST /api/publish/login/weixin` 冒烟返回 `success=true` + `qr_code`
- `npx eslint` 定向检查以下文件通过:
- `VoiceSelector.tsx`
- `RefAudioPanel.tsx`
- `HomePage.tsx`
- `useHomeController.ts`
- `AppModal.tsx`
- `VideoPreviewModal.tsx`
- `ScriptExtractionModal.tsx`
- `RewriteModal.tsx`
- `AccountSettingsDropdown.tsx`
- `ClipTrimmer.tsx` 仍有仓库既有 lint 规则项(`react-hooks/set-state-in-effect`),与本次弹窗风格迁移无关
- 音色试听线上问题经后端重启后已恢复可用(浏览器同源携带 cookie
---
## ☑️ Day31 覆盖核对(今日新增补充)
已对照今天新增改动做二次核对,以下内容已写入本日志:
- `AppModal` 的可访问性与焦点/滚动锁稳健性增强
- 微信视频号二维码“观感不完整”问题的后端提取修复
- 发布页二维码展示样式优化(白底留白、去除本体圆角裁切)
- 小红书 uploader 对齐重构(启动参数、发布判定、成功截图)
- 小红书“上传阶段卡住”二次定位与加固(文件名后缀一致性 + 空转超时)并完成实测发布成功
- 形成发布专项文档 `Docs/PUBLISH_DEPLOY.md`,沉淀四平台登录与自动化发布实现
- 回写 `Docs/BACKEND_README.md` / `Docs/BACKEND_DEV.md` / `Docs/DEPLOY_MANUAL.md`,统一发布 API 与部署说明口径
- 回写 `Docs/FRONTEND_README.md` / `Docs/FRONTEND_DEV.md` / `Docs/PUBLISH_DEPLOY.md`,补齐发布后清理弹窗与 cleanup 接口联动说明
- 回写 `README.md`,补充发布专项文档入口与小红书发布成功截图能力描述
- 回写 `Docs/TASK_COMPLETE.md`,补齐 Day31 任务完成记录
- 回写 `Docs/DOC_RULES.md`,同步文档更新规则到当前文档结构与工具链
- 首页「AI生成标题标签」按钮迁移到「四、标题与字幕」并固定标题同层最右显示方式与预览下沉到下一行右侧
- 文案输入框右下角新增扩展角标,支持弹出大编辑器进行长文案编辑
- 站点 icon 已替换为 `Temp/video.png` 对应资源(`app/icon.png` + `app/favicon.ico`
- 发布后工作区清理链路落地CleanupModal + `/api/videos/cleanup`)并补齐失败兜底(失败不关弹窗、不清本地)
- 清理链路防锁死优化3 次失败可跳过、24h 过期、用户切换复位
- 文档补充:`标题短暂显示/常驻显示` 对主标题与副标题统一生效(常驻=主/副标题全程显示)
- 非 bilibili 平台 cookie 保存为 `storage_state` 格式
- 小红书登录二维码自动切换(短信登录 -> 扫码登录)与提取修复
- 对应构建/重启/冒烟验证记录
- 今日运行期产物(`backend/user_data/**/cookies/*.json``watchdog.log`)为会话副产物,不属于代码/文档变更项