fix: 逐张等待图片上传完成,避免多图上传时图片丢失

每张图片上传后等待预览元素出现(最多60秒)再传下一张,
替代原来固定 sleep(1s) 的方式,解决部分图片静默丢失的问题。
跳过 current=0 的无意义日志
跳过上传等待中已知计数的重复日志

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
tan jun
2026-02-07 11:51:54 +08:00
committed by tanjun
parent dfa94e84ef
commit 44061fdabc
2 changed files with 41 additions and 23 deletions

View File

@@ -27,8 +27,23 @@
"Bash(tar:*)", "Bash(tar:*)",
"mcp__playwright__browser_type", "mcp__playwright__browser_type",
"mcp__playwright__browser_close", "mcp__playwright__browser_close",
"Bash(git remote:*)" "Bash(git remote:*)",
"mcp__plugin_playwright_playwright__browser_navigate",
"mcp__xiaohongshu-mcp__check_login_status",
"mcp__xiaohongshu-mcp__publish_content",
"mcp__plugin_playwright_playwright__browser_click",
"mcp__plugin_playwright_playwright__browser_resize",
"mcp__plugin_playwright_playwright__browser_snapshot",
"mcp__plugin_playwright_playwright__browser_evaluate",
"Bash(date:*)",
"mcp__xiaohongshu-mcp__publish_with_video",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(git checkout:*)",
"Bash(git pull:*)",
"Bash(git branch:*)"
], ],
"deny": [] "deny": []
} }
} }

View File

@@ -210,15 +210,14 @@ func uploadImages(page *rod.Page, imagesPaths []string) error {
logrus.Infof("获取有效图片:%s", path) logrus.Infof("获取有效图片:%s", path)
} }
// 逐张上传:第一张用 .upload-input后续页面会移除该 class改用 input[type="file"] // 逐张上传:每张上传后等待预览出现,再上传下一张
for i, path := range validPaths { for i, path := range validPaths {
selector := `input[type="file"]` selector := `input[type="file"]`
if i == 0 { if i == 0 {
selector = ".upload-input" selector = ".upload-input"
} }
pp := page.Timeout(60 * time.Second) uploadInput, err := page.Element(selector)
uploadInput, err := pp.Element(selector)
if err != nil { if err != nil {
return errors.Wrapf(err, "查找上传输入框失败(第%d张)", i+1) return errors.Wrapf(err, "查找上传输入框失败(第%d张)", i+1)
} }
@@ -227,42 +226,46 @@ func uploadImages(page *rod.Page, imagesPaths []string) error {
} }
slog.Info("图片已提交上传", "index", i+1, "path", path) slog.Info("图片已提交上传", "index", i+1, "path", path)
// 等待当前图片上传完成(预览元素数量达到 i+1最多等 60 秒
if err := waitForUploadComplete(page, i+1); err != nil {
return errors.Wrapf(err, "第%d张图片上传超时", i+1)
}
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
} }
// 等待并验证上传完成 return nil
return waitForUploadComplete(page, len(validPaths))
} }
// waitForUploadComplete 等待并验证上传完成 // waitForUploadComplete 等待第 expectedCount 张图片上传完成,最多等 60 秒
func waitForUploadComplete(page *rod.Page, expectedCount int) error { func waitForUploadComplete(page *rod.Page, expectedCount int) error {
maxWaitTime := 60 * time.Second maxWaitTime := 60 * time.Second
checkInterval := 500 * time.Millisecond checkInterval := 500 * time.Millisecond
start := time.Now() start := time.Now()
lastLogCount := expectedCount - 1
slog.Info("开始等待图片上传完成", "expected_count", expectedCount)
for time.Since(start) < maxWaitTime { for time.Since(start) < maxWaitTime {
// 使用具体的pr类名检查已上传的图片
uploadedImages, err := page.Elements(".img-preview-area .pr") uploadedImages, err := page.Elements(".img-preview-area .pr")
if err != nil {
time.Sleep(checkInterval)
continue
}
slog.Info("uploadedImages", "uploadedImages", uploadedImages) currentCount := len(uploadedImages)
// 数量变化时才打印,避免刷屏
if err == nil { if currentCount != lastLogCount {
currentCount := len(uploadedImages) slog.Info("等待图片上传", "current", currentCount, "expected", expectedCount)
slog.Info("检测到已上传图片", "current_count", currentCount, "expected_count", expectedCount) lastLogCount = currentCount
if currentCount >= expectedCount { }
slog.Info("所有图片上传完成", "count", currentCount) if currentCount >= expectedCount {
return nil slog.Info("图片上传完成", "count", currentCount)
} return nil
} else {
slog.Debug("未找到已上传图片元素")
} }
time.Sleep(checkInterval) time.Sleep(checkInterval)
} }
return errors.New("上传超时,请检查网络连接和图片大小") return errors.Errorf("第%d张图片上传超时(60s),请检查网络连接和图片大小", expectedCount)
} }
func submitPublish(page *rod.Page, title, content string, tags []string, scheduleTime *time.Time) error { func submitPublish(page *rod.Page, title, content string, tags []string, scheduleTime *time.Time) error {