527 lines
30 KiB
Markdown
527 lines
30 KiB
Markdown
## 文档分层收敛 + 音色试听修复 + 录音弹窗重构 + 弹窗体系统一 (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`)为会话副产物,不属于代码/文档变更项
|