## 🛡️ 发布中防误刷新（15:46，合并）

### 内容
- 发布按钮文案统一为：`正在发布...请勿刷新或关闭网页`
- 发布中启用浏览器 `beforeunload` 拦截，刷新/关闭页面会触发原生二次确认
- 适用于发布管理页全部平台（抖音 / 微信视频号 / B站 / 小红书）
- 后续优化已登记：发布任务状态恢复机制（任务化 + 状态持久化 + 前端轮询恢复）

### 涉及文件
- `frontend/src/features/publish/model/usePublishController.ts`
- `frontend/src/features/publish/ui/PublishPage.tsx`

---

## 🖼️ 发布成功截图稳定性优化（15:26，合并）

### 内容
- 成功判定后先等待页面加载，再额外等待 `3s` 后截图，避免抓到半加载页面
- 针对“截图里页面内容只占 1/3”问题，成功截图从 `full_page=True` 调整为视口截图 `full_page=False`
- 视频号成功截图前额外恢复 `zoom=1.0`，避免流程缩放影响最终截图比例
- 抖音成功截图同步应用相同策略，统一前端展示观感

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧪 视频号录屏 Debug 开关（15:12，已回收）

### 内容
- 为视频号上传器新增 Playwright 录屏能力，开关受 `WEIXIN_DEBUG_ARTIFACTS && WEIXIN_RECORD_VIDEO` 控制
- 新增视频号录屏配置项：
  - `WEIXIN_RECORD_VIDEO`
  - `WEIXIN_KEEP_SUCCESS_VIDEO`
  - `WEIXIN_RECORD_VIDEO_WIDTH`
  - `WEIXIN_RECORD_VIDEO_HEIGHT`
- 上传流程在 `finally` 中统一保存录屏，失败必保留；成功录屏默认按开关清理
- 排障阶段临时开启过视频号 debug/录屏；当前已回收为默认关闭（`run_backend.sh` 设为 `false`）

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`
- `backend/app/core/config.py`
- `run_backend.sh`
- `Docs/DEPLOY_MANUAL.md`

---

## 🔁 后端启动脚本统一为 run_backend.sh (15:00)

### 内容
- 删除旧脚本 `run_backend_xvfb.sh`
- 将 `run_backend.sh` 统一为 xvfb + headful 启动逻辑（不再保留非 xvfb 版本）
- 默认端口从 `8010` 统一为 `8006`
- 启动脚本默认关闭微信/抖音 debug 产物
- 更新部署手册中的启动与 pm2 示例，统一使用 `run_backend.sh`

### 涉及文件
- `run_backend.sh`
- `run_backend_xvfb.sh` (deleted)
- `Docs/DEPLOY_MANUAL.md`

---

## 🧾 视频号卡顿与文案未写入修复 (14:52)

### 内容
- 复盘日志确认视频号 `post_create` 请求已成功，但结果判定仅靠页面文案，导致长时间“等待发布结果”
- 发布判定优化：`post_create` 成功且页面进入 `post/list` 时立即判定成功
- 发布超时改为失败返回（不再 `success=true` 假成功）
- “标题+标签写在视频描述”进一步加强：先按 `视频描述` 标签定位输入框，再做 placeholder 与 contenteditable 兜底
- 视频号发布结果等待超时从 `180s` 收敛到 `90s`

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`

---

## 🚦 视频号发布卡顿根因与快速判定 (14:45)

### 内容
- 定位到卡顿根因是实际请求已提交（`post_create` 成功）但结果判定仍在轮询文本提示，导致长时间等待
- 新增发布成功网络信号：监听 `post/post_create` 成功响应后标记已提交
- 若已提交且页面已回到内容列表（`/post/list`），立即判定发布成功，不再等满超时
- 新增发布接口失败信号：`post_create` 返回错误时立即失败返回

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`

---

## 📸 视频号发布成功截图接入前端 (13:34)

### 内容
- 为微信视频号新增“发布成功截图”能力：发布成功后直接对当前成功页截图
- 截图存储沿用私有隔离目录：`private_outputs/publish_screenshots/{user_id}`
- 返回前端的 `screenshot_url` 使用鉴权接口：`/api/publish/screenshot/{filename}`
- 视频号上传器新增 `user_id` 透传，确保截图按用户隔离

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`
- `backend/app/services/publish_service.py`

---

## ✍️ 视频号描述填充修正 + 关闭调试产物 (13:26)

### 内容
- 按最新规则调整视频号文案填充：标题和标签统一写入“视频描述”输入区
- 标签统一规范为 `#标签` 形式并去重
- 若未找到“视频描述”输入区，直接返回失败，避免“发布成功但标题/标签为空”
- 关闭视频号 debug 产物：新增 `WEIXIN_DEBUG_ARTIFACTS=false`，禁用调试日志与截图输出
- `run_backend.sh` 增加 `WEIXIN_DEBUG_ARTIFACTS=false`，启动脚本层面强制关闭

### 涉及文件
- `backend/app/services/uploader/weixin_uploader.py`
- `backend/app/core/config.py`
- `run_backend.sh`

---

## 🚫 强制关闭抖音调试产物 (13:15)

### 内容
- 进一步收紧为“默认不生成任何抖音 debug 截屏/日志/录屏”
- 录屏开关改为依赖 `DOUYIN_DEBUG_ARTIFACTS && DOUYIN_RECORD_VIDEO`，避免单独误开
- `run_backend.sh` 增加环境变量强制关闭：
  - `DOUYIN_DEBUG_ARTIFACTS=false`
  - `DOUYIN_RECORD_VIDEO=false`
- 仅保留给用户看的发布成功截图（私有目录 + 鉴权访问）

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
- `backend/app/core/config.py`
- `run_backend.sh`

---

## 🧹 关闭调试截屏/录屏并清理历史文件 (13:08)

### 内容
- 抖音调试产物默认关闭：
  - `DOUYIN_DEBUG_ARTIFACTS=false`
  - `DOUYIN_RECORD_VIDEO=false`
- 保留功能信号监听（上传提交/封面生成/发布接口状态）用于流程判断，不依赖调试文件
- 已删除现有抖音调试文件（`debug_screenshots` 下的 `douyin_*` 截图、日志与失败录屏）
- 继续保留并展示“给用户看的发布成功截图”（用户隔离 + 鉴权访问）

### 涉及文件
- `backend/app/core/config.py`
- `backend/app/services/uploader/douyin_uploader.py`
- `backend/app/debug_screenshots/douyin_*` (deleted)
- `backend/app/debug_screenshots/videos/douyin_*` (deleted)

---

## 🔒 成功截图用户隔离 (12:58)

### 内容
- 发布成功截图改为用户隔离存储，不再写入公开静态目录
- 存储目录迁移到私有路径：`private_outputs/publish_screenshots/{user_id}`
- 新增鉴权访问接口：`GET /api/publish/screenshot/{filename}`（必须登录，仅可访问本人截图）
- 返回给前端的 `screenshot_url` 改为鉴权接口地址，避免跨用户直接猜路径访问

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
- `backend/app/services/publish_service.py`
- `backend/app/modules/publish/router.py`
- `backend/app/core/config.py`

---

## 🎯 封面触发提速与审核中截图强化 (12:49)

### 内容
- 修复“上传完成后长时间不进入封面”：当出现 `重新上传+预览` 且已收到视频提交信号时，立即进入封面步骤
- 目标是减少“处理中”文案残留导致的额外等待
- 成功截图逻辑强化为优先“真实点击审核中标签”，新增文本点击兜底，不再只用可见即通过
- 若审核中列表未马上出现标题，自动刷新并再次进入审核中重查后再截图

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🔐 登录态识别增强（避免误报上传失败） (12:41)

### 内容
- 针对“未触发文件选择弹窗”误报，新增登录页识别：
  - URL 关键字：`passport/login/check_qrconnect/sso`
  - 页面文本：`扫码登录/验证码登录/立即登录/抖音APP扫码登录` 等
  - 登录控件：手机号/验证码输入框、登录按钮
- 上传阶段重试后若识别为登录页，直接返回 `Cookie 已失效，请重新登录`
- 避免把“实际掉登录”误判成“上传入口失效”

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⏱️ 发布阶段超时与网络不佳快速失败 (12:30)

### 内容
- 针对“网络不佳后长时间卡住”增加发布阶段快速失败
- 上传完成后到发布结果设置总超时 `60s`（`POST_UPLOAD_STAGE_TIMEOUT`），超过直接失败
- 识别发布接口 `create_v2` 的 HTTP 错误（如 403）并立即返回失败，不再等待 180 秒
- 发布结果判定新增网络类失败文案匹配（`网络不佳/网络异常/请稍后重试`）
- 阻塞弹窗关闭策略新增 `暂不设置`，避免“设置横封面获更多流量”弹窗阻塞点击发布

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧯 封面已完成但误判失败修复 (12:22)

### 内容
- 针对报错“封面为必填但未设置成功”新增页面态兜底，避免封面已完成却未点击发布
- 新增 `_is_cover_configured_on_page()`：通过 `横封面/竖封面` + 封面预览图判断页面已配置封面
- 当出现 `horizontal_switch_missed` 或 `no_cover_button` 时，若页面已配置封面则允许继续发布
- 封面必填主流程增加 `configured_fallback_continue` 兜底，降低误杀

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧾 成功截图切到审核中视图 (11:26)

### 内容
- 按需求将“发布成功截图”改为内容管理 `审核中/待审核` 视图，不再截“全部作品”
- 发布成功后先进入内容管理并点击 `审核中`（或 `待审核`）再截图
- 截图前额外尝试等待当前标题出现在审核中列表，便于确认是最新发布作品
- 发布超时兜底验证也改为优先在审核中列表查找标题

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ✅ 封面步骤按指定顺序强约束 (11:18)

### 内容
- 按确认流程收紧旧发布页封面链路：
  - 作品描述填完 → 点击 `选择封面` → 点击 `设置横封面` → 点击 `完成` → 等待封面效果检测通过 → 才允许发布
- 新增 `require_horizontal` 约束：封面必填场景必须切换到横封面，否则直接失败重试
- 新增封面效果检测通过等待：优先 `cover/gen` 新请求信号，其次页面“检测通过”文案
- 避免因漏点 `设置横封面` 导致后续卡住或误发布

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧩 横封面点击漏判修复 (11:10)

### 内容
- 根据复现反馈修复“未点击设置横封面导致封面流程卡住”问题
- 新增 `_switch_to_horizontal_cover()`，扩展横封面入口选择器（`设置横封面/横封面/横版封面`）
- 进入封面弹窗后先关闭阻塞弹窗再点击横封面，点击失败会重试一次
- 若页面存在横封面入口但始终未切换成功，直接返回失败并重试，避免长时间假等待
- 新增日志：`[douyin][cover] switched_horizontal ...`、`horizontal_switch_missed`

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⚡ 横封面后直接完成优化 (11:03)

### 内容
- 根据实测反馈，在点击 `设置横封面` 后新增一次“立即点击完成”快速路径
- 若平台已自动选中横封面，将直接确认并退出弹窗，不再执行后续封面扫描
- 新增日志：`[douyin][cover] fast_confirm_after_switch ...`

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⚙️ 封面步骤提速优化 (10:58)

### 内容
- 复盘日志确认旧发布页封面步骤存在明显耗时（示例：`required_by_text` 到 `cover selected` 约 35 秒）
- 新增封面“快速确认”路径：若平台已默认选中封面，直接确认并跳过多余扫描
- 收紧封面成功条件：仅“确认按钮点击成功”才算封面设置成功，避免误判
- 缩短不必要等待并新增封面耗时日志：`[douyin][cover] fast_confirm/selected=... confirmed=... elapsed=...`

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧾 发布成功截图前台展示 (10:48)

### 内容
- 按需求删除 `run_backend_xvfb_live.sh`，不再提供实时直播脚本
- 抖音发布成功时自动保存成功截图到 `outputs/publish_screenshots`
- 发布接口返回 `screenshot_url`，前端发布结果卡片直接展示截图并支持点击查看大图
- 发布结果不再 10 秒自动清空，方便用户确认“是否真正发布成功”

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
- `frontend/src/features/publish/model/usePublishController.ts`
- `frontend/src/features/publish/ui/PublishPage.tsx`
- `run_backend_xvfb_live.sh` (deleted)

---

## 🧬 抖音界面差异根因与环境对齐 (10:20)

### 内容
- 定位到 Playwright 与手动 Win11 Chrome 的环境指纹不一致（Linux 平台 + 自动化上下文），可能触发不同灰度界面
- 抖音上传器新增独立浏览器配置项，不再复用 `WEIXIN_*` 配置
- 新增 `DOUYIN_*` 配置：`HEADLESS_MODE/USER_AGENT/LOCALE/TIMEZONE_ID/CHROME_PATH/BROWSER_CHANNEL/FORCE_SWIFTSHADER`
- 上传器启动改为 `_build_launch_options()`，可直接切换到系统 Chrome + headful（推荐配合 xvfb）

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
- `backend/app/core/config.py`

---

## 🪄 新旧发布页封面逻辑分流 (10:28)

### 内容
- 依据页面结构自动分流：
  - 新版发布页（封面非必填）：默认跳过封面设置
  - 旧版发布页（出现 `设置封面` + `必填`）：强制先设置封面
- 新增 `_is_cover_required()` 判断，避免在新页面做多余封面操作
- 若判定为非必填但点击发布失败，会回退尝试设置封面后再重试发布

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 📺 虚拟屏实时观看方案 (10:36)

### 内容
- 新增 `run_backend_xvfb_live.sh`，在 Xvfb 下同时启动后端与实时画面转码
- 通过 ffmpeg 抓取虚拟屏并输出 HLS：`/outputs/live/live.m3u8`
- 适用于“边跑自动发布边实时观看”，不依赖 VNC
- 默认仍保留失败录屏，HLS 用于过程实时观察

### 涉及文件
- `run_backend_xvfb_live.sh`

---

## 🎥 抖音后台录屏能力 (09:55)

### 内容
- 新增抖音自动发布过程录屏能力，便于定位“卡住在哪一步”
- 录屏文件保存目录：`backend/app/debug_screenshots/videos`
- 默认开启录屏，默认只保留失败录屏（成功录屏自动清理）
- 每次执行会在网络日志追加录屏保存记录（`[douyin][record]`）
- 增加发布阶段关键标记日志：`publish_wait ready`、`publish_click try/clicked`
- 新增配置项：`DOUYIN_RECORD_VIDEO`、`DOUYIN_KEEP_SUCCESS_VIDEO`、`DOUYIN_RECORD_VIDEO_WIDTH`、`DOUYIN_RECORD_VIDEO_HEIGHT`

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
- `backend/app/core/config.py`

---

## 🚀 发布按钮等待逻辑修正 (10:00)

### 内容
- 根据线上反馈，发布页不再做冗长前置等待，改为“尽快尝试点击发布”
- 新增发布按钮定位策略（role + text 多选择器），避免 `exact role` 匹配失败导致假等待
- 将发布按钮等待上限从上传超时（300s）独立为 `PUBLISH_BUTTON_TIMEOUT=60s`
- 点击发布阶段统一走 `_click_publish_button`，并持续记录 `publish_wait/publish_click` 日志

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧪 上传完成特征判定增强 (10:07)

### 内容
- 基于实测页面特征补齐“上传中/上传完成”判定：
  - 上传中：`上传过程中请不要刷新`、`取消上传`、`已上传/当前速度/剩余时间`
  - 上传完成：`重新上传` + `预览视频/预览封面/标题`
- 仅在确认上传完成后才允许执行发布点击，避免“未传完提前发布”
- 新增上传等待日志：`[douyin][upload_wait] ...`，可直观看到卡在上传中还是等完成信号

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⏸️ 上传完成后延时发布 (10:10)

### 内容
- 根据实测反馈，增加“上传完成后固定等待 2 秒”再点发布
- 避免刚出现完成信号就立即点击，给前端状态收敛留缓冲
- 新增日志标记：`[douyin][upload_ready] wait_before_publish=2s`

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🖼️ 恢复封面设置流程 (10:14)

### 内容
- 按实测需求恢复“上传完成后先设置封面，再发布”流程
- 封面设置改为最多尝试 2 次，成功写入 `[douyin][cover] selected`
- 若封面未设置成功则直接终止发布并保存截图 `cover_not_selected`
- 避免出现“未设封面就点击发布”的情况

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🛠️ 抖音发布流程修复 (09:20)

### 内容
- 按最新页面流程改为先进入首页并点击 `高清发布`，再进入上传页
- 新增未发布草稿处理：检测到 `你还有上次未发布的视频` 时自动点击 `放弃`
- 上传策略改为优先点击 `上传视频` 并走 file chooser，失败后再回退多 input 选择器
- 只有检测到 `基础信息/作品描述/发布设置/重新上传` 等发布态信号才继续，避免误判“已上传”
- 修复无扩展名视频临时文件策略：优先 hardlink，失败时 copy，移除 symlink 回退
- 适配当前智能封面流程：跳过手动封面操作
- 话题填写改为在简介/描述区域使用 `#标签` 形式追加

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⚡ 抖音等待链路再收敛 (09:52)

### 内容
- 根据“选完视频即进入发布页”流程，移除独立的上传完成轮询阶段
- 改为在点击发布前统一等待“发布按钮可点击”，避免重复等待导致总时长偏长
- 新增 `publish_wait` 调试日志，按秒记录按钮可点击等待时长
- 超时文案改为明确提示“发布按钮长时间不可点击”
- 上传入口改为严格 file chooser 流程：只走“点击上传视频 → 选择文件 → 进入发布页”链路
- 移除直接 input 回退上传，避免绕开上传入口导致状态机异常

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## 🧭 抖音卡慢环节定位与修复 (09:45)

### 内容
- 通过 `douyin_network.log` 定位到卡慢发生在“上传完成判定”阶段，而非真正提交发布接口
- 新增上传完成网络信号：`CommitUploadInner` 成功与封面生成成功信号写入日志
- 收紧“上传完成”判定，移除 `publish_button_enabled` 这种过早放行条件
- 仅在检测到 `重新上传/重新选择` 或上传提交信号后才进入下一步，降低误判导致的长等待

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ✅ 抖音发布结果判定修正 (09:38)

### 内容
- 修复“发布检测超时仍返回 success=true”的问题，超时场景改为 `success=false`
- 优化超时返回文案，明确为“发布状态未知，需要后台确认”
- 下线过于宽松的管理页兜底判定（仅出现 `审核中` 不再当作发布成功）
- 超时时即使管理页出现同名标题也不直接判定成功，避免旧作品同名导致误报

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`

---

## ⏱️ 抖音上传完成判定优化 (09:34)

### 内容
- 根据最新日志确认文件上传已开始并有分片上传请求成功，但流程长时间停留在“等待上传完成”
- 扩展“上传完成”判定条件，不再只依赖单一 `long-card + 重新上传` 选择器
- 新增上传完成信号：`重新上传/重新选择` 可见、发布按钮可用、`发布设置` 或 `预览视频` 可见
- 上传等待日志增加耗时秒数，便于判断是否真实卡住

### 涉及文件
- `backend/app/services/uploader/douyin_uploader.py`
