This commit is contained in:
parent
15ea020bc1
commit
6c11412307
|
|
@ -1 +1 @@
|
|||
[{"name":"websectiga","value":"7750c37de43b7be9de8ed9ff8ea0e576519e8cd2157322eb972ecb429a7735d4","domain":".xiaohongshu.com","path":"/","expires":1776073705,"size":74,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"x-user-id-creator.xiaohongshu.com","value":"65d74a4c0000000005032a98","domain":".xiaohongshu.com","path":"/","expires":1810179755.091531,"size":57,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"xsecappid","value":"ugc","domain":".xiaohongshu.com","path":"/","expires":1807350714,"size":12,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"a1","value":"19d6b2f0b04zdps8dison8k8oibcyzaju3ji7d03d30000118748","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":54,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"webId","value":"f840cc8b10e0a01b0bdb839482af19d1","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":37,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"access-token-creator.xiaohongshu.com","value":"customer.creator.AT-68c517626228786611519495vggizcwmifuvnaaw","domain":".xiaohongshu.com","path":"/","expires":1778211754.091569,"size":96,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"sec_poison_id","value":"0e8199c2-5b2c-4b5d-9423-9ce4ae7c7d4a","domain":".xiaohongshu.com","path":"/","expires":1775815110,"size":49,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customerClientId","value":"231145420384063","domain":".xiaohongshu.com","path":"/","expires":1810179755.091552,"size":31,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"ets","value":"1775619738206","domain":".xiaohongshu.com","path":"/","expires":1778211738.206388,"size":16,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"gid","value":"yjfKDJiJ0J7SyjfKDJi8Dqf884ufUMYf3MlIVqfYTYl3D3q8Svu0VW888yyYW4Y8JD0j8Yd2","domain":".xiaohongshu.com","path":"/","expires":1810372429.581067,"size":75,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customer-sso-sid","value":"68c5176262287866115194944uxxdffhcemiwvwt","domain":".xiaohongshu.com","path":"/","expires":1776224554.091467,"size":56,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy_creator_session_id","value":"nWC5PzTFCCSJsLYiRFLFORIWUoUf5c4Egr3v","domain":".xiaohongshu.com","path":"/","expires":1778211755.091586,"size":61,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"acw_tc","value":"0a0d0eb817758145058628343eac7363daa6c0cadc9daf2e0f80b0fb928719","domain":"creator.xiaohongshu.com","path":"/","expires":1775816304.657778,"size":68,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy.creator.beaker.session.id","value":"1775619757404082990054","domain":".xiaohongshu.com","path":"/","expires":1778211755.091605,"size":54,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"loadts","value":"1775814714949","domain":".xiaohongshu.com","path":"/","expires":1807350714,"size":19,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443}]
|
||||
[{"name":"gid","value":"yjfKDJiJ0J7SyjfKDJi8Dqf884ufUMYf3MlIVqfYTYl3D3q8Svu0VW888yyYW4Y8JD0j8Yd2","domain":".xiaohongshu.com","path":"/","expires":1810372429.581067,"size":75,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"ets","value":"1775619738206","domain":".xiaohongshu.com","path":"/","expires":1778211738.206388,"size":16,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"a1","value":"19d6b2f0b04zdps8dison8k8oibcyzaju3ji7d03d30000118748","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":54,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customer-sso-sid","value":"68c5176262287866115194944uxxdffhcemiwvwt","domain":".xiaohongshu.com","path":"/","expires":1776224554.091467,"size":56,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"x-user-id-creator.xiaohongshu.com","value":"65d74a4c0000000005032a98","domain":".xiaohongshu.com","path":"/","expires":1810179755.091531,"size":57,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"access-token-creator.xiaohongshu.com","value":"customer.creator.AT-68c517626228786611519495vggizcwmifuvnaaw","domain":".xiaohongshu.com","path":"/","expires":1778211754.091569,"size":96,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy_creator_session_id","value":"nWC5PzTFCCSJsLYiRFLFORIWUoUf5c4Egr3v","domain":".xiaohongshu.com","path":"/","expires":1778211755.091586,"size":61,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"webId","value":"f840cc8b10e0a01b0bdb839482af19d1","domain":".xiaohongshu.com","path":"/","expires":1807155738,"size":37,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"xsecappid","value":"ugc","domain":".xiaohongshu.com","path":"/","expires":1807379925,"size":12,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"loadts","value":"1775843925008","domain":".xiaohongshu.com","path":"/","expires":1807379925,"size":19,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"galaxy.creator.beaker.session.id","value":"1775619757404082990054","domain":".xiaohongshu.com","path":"/","expires":1778211755.091605,"size":54,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"websectiga","value":"2a3d3ea002e7d92b5c9743590ebd24010cf3710ff3af8029153751e41a6af4a3","domain":".xiaohongshu.com","path":"/","expires":1776103125,"size":74,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"sec_poison_id","value":"680df974-cc97-44bd-9c18-b9efaafb66cc","domain":".xiaohongshu.com","path":"/","expires":1775844530,"size":49,"httpOnly":false,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"acw_tc","value":"0a00076417758431730566823e6256f5349e529f992a6ba74dc0835439d93a","domain":"creator.xiaohongshu.com","path":"/","expires":1775844709.365943,"size":68,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443},{"name":"customerClientId","value":"231145420384063","domain":".xiaohongshu.com","path":"/","expires":1810179755.091552,"size":31,"httpOnly":true,"secure":false,"session":false,"priority":"Medium","sameParty":false,"sourceScheme":"Secure","sourcePort":443}]
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -2,6 +2,7 @@ package entitys
|
|||
|
||||
type PublishTaskDetail struct {
|
||||
// publish 表字段
|
||||
ID int `db:"ID"`
|
||||
RequestID string `db:"request_id"`
|
||||
PlatIndex string `db:"plat_index"`
|
||||
Title string `db:"title"`
|
||||
|
|
|
|||
|
|
@ -194,11 +194,30 @@ func (pm *PublishManager) executeOneTask(workerID int, headless bool) {
|
|||
}
|
||||
|
||||
log.Printf("[Worker-%d] 开始处理任务 requestID=%s", workerID, task.RequestID)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
defer cancel()
|
||||
// 使用 channel 接收结果,避免 goroutine 泄漏
|
||||
resultChan := make(chan *SingleResult, 1)
|
||||
|
||||
result := pm.processTask(ctx, task, headless)
|
||||
go func() {
|
||||
resultChan <- pm.processTask(ctx, task, headless)
|
||||
}()
|
||||
|
||||
// 监听 ctx 超时
|
||||
var result *SingleResult
|
||||
select {
|
||||
case result = <-resultChan:
|
||||
// 任务正常完成
|
||||
case <-ctx.Done():
|
||||
// 超时或取消
|
||||
log.Printf("[Worker-%d] 任务超时或被取消 requestID=%s, err=%v", workerID, task.RequestID, ctx.Err())
|
||||
result = &SingleResult{
|
||||
Success: false,
|
||||
Message: fmt.Sprintf("任务执行超时: %v", ctx.Err()),
|
||||
}
|
||||
// 注意:这里不能等待 goroutine 结束,因为 processTask 可能卡住
|
||||
// cancel() 会在 defer 中调用,但 processTask 内部需要响应 ctx.Done()
|
||||
}
|
||||
|
||||
if result == nil {
|
||||
log.Printf("[Worker-%d] 任务返回空结果", workerID)
|
||||
|
|
@ -246,6 +265,7 @@ func (pm *PublishManager) acquireTask() (*entitys.PublishTaskDetail, error) {
|
|||
var task entitys.PublishTaskDetail
|
||||
querySQL := `
|
||||
SELECT
|
||||
p.id,
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
|
|
@ -302,7 +322,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
if r := recover(); r != nil {
|
||||
errMsg := fmt.Sprintf("任务执行发生panic: %v", r)
|
||||
taskLogger.Printf("❌ CRITICAL: %s", errMsg)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg)
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg)
|
||||
}
|
||||
}()
|
||||
|
||||
|
|
@ -310,7 +330,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
|
||||
params, sourceUrl := pm.extractTaskParams(publishData, taskLogger)
|
||||
if params == nil {
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, "提取任务参数失败")
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, "提取任务参数失败")
|
||||
return &SingleResult{Success: false, Message: "提取任务参数失败", RequestId: publishData.RequestID}
|
||||
}
|
||||
params.Headless = headless
|
||||
|
|
@ -319,7 +339,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
if publisherClass == nil {
|
||||
errMsg := fmt.Sprintf("不支持的平台: %s", params.PlatIndex)
|
||||
taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg)
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg)
|
||||
return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID}
|
||||
}
|
||||
|
||||
|
|
@ -327,7 +347,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
if err != nil {
|
||||
errMsg := fmt.Sprintf("准备文件失败: %v", err)
|
||||
taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg)
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg)
|
||||
return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID}
|
||||
}
|
||||
defer pm.cleanupFiles(docPath, imgPath, taskLogger, publishData.RequestID)
|
||||
|
|
@ -336,7 +356,7 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
if err != nil {
|
||||
errMsg := fmt.Sprintf("提取文档内容失败: %v", err)
|
||||
taskLogger.Printf("[任务 %s] ❌ %s", publishData.RequestID, errMsg)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, errMsg)
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, errMsg)
|
||||
return &SingleResult{Success: false, Message: errMsg, RequestId: publishData.RequestID}
|
||||
}
|
||||
params.ImagePath = imgPath
|
||||
|
|
@ -348,10 +368,10 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
|
||||
if success {
|
||||
taskLogger.Printf("[任务 %s] ✅ 发布成功: %s", publishData.RequestID, message)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusSuccess, message)
|
||||
pm.updatePublishStatus(publishData.ID, StatusSuccess, message)
|
||||
} else {
|
||||
taskLogger.Printf("[任务 %s] ❌ 发布失败: %s", publishData.RequestID, message)
|
||||
pm.updatePublishStatus(publishData.RequestID, StatusFailed, message)
|
||||
pm.updatePublishStatus(publishData.ID, StatusFailed, message)
|
||||
}
|
||||
|
||||
taskLogger.Printf(strings.Repeat("=", 80))
|
||||
|
|
@ -360,12 +380,12 @@ func (pm *PublishManager) processTask(ctx context.Context, publishData *entitys.
|
|||
}
|
||||
|
||||
// RetryTask 重试任务(非无头模式)
|
||||
func (pm *PublishManager) RetryTask(ctx context.Context, requestID string) *SingleResult {
|
||||
func (pm *PublishManager) RetryTask(ctx context.Context, tokenId int, requestID string) *SingleResult {
|
||||
if requestID == "" {
|
||||
return &SingleResult{Success: false, Message: "requestID不能为空"}
|
||||
}
|
||||
|
||||
publishData, err := pm.GetTaskByRequestID(requestID)
|
||||
publishData, err := pm.GetTaskByRequestID(requestID, tokenId)
|
||||
if err != nil || publishData == nil {
|
||||
return &SingleResult{Success: false, Message: "任务不存在"}
|
||||
}
|
||||
|
|
@ -379,13 +399,14 @@ func (pm *PublishManager) RetryTask(ctx context.Context, requestID string) *Sing
|
|||
}
|
||||
|
||||
// GetTaskByRequestID 根据RequestID获取任务
|
||||
func (pm *PublishManager) GetTaskByRequestID(requestID string) (*entitys.PublishTaskDetail, error) {
|
||||
func (pm *PublishManager) GetTaskByRequestID(requestID string, tokenId int) (*entitys.PublishTaskDetail, error) {
|
||||
if requestID == "" {
|
||||
return nil, fmt.Errorf("requestID不能为空")
|
||||
}
|
||||
|
||||
sql := `
|
||||
SELECT
|
||||
p.id,
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
|
|
@ -403,10 +424,10 @@ func (pm *PublishManager) GetTaskByRequestID(requestID string) (*entitys.Publish
|
|||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE p.request_id = ?
|
||||
WHERE p.request_id = ? AND token_id=?
|
||||
`
|
||||
var task entitys.PublishTaskDetail
|
||||
err := pm.db.GetOneToStruct(sql, &task, requestID)
|
||||
err := pm.db.GetOneToStruct(sql, &task, requestID, tokenId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -503,18 +524,18 @@ func (pm *PublishManager) extractContent(docPath string, publisherClass *publish
|
|||
}
|
||||
|
||||
// updatePublishStatus 更新发布状态
|
||||
func (pm *PublishManager) updatePublishStatus(requestID string, status int, message string) error {
|
||||
if requestID == "" {
|
||||
return fmt.Errorf("requestID不能为空")
|
||||
func (pm *PublishManager) updatePublishStatus(id int, status int, message string) error {
|
||||
if id == 0 {
|
||||
return fmt.Errorf("id不能为空")
|
||||
}
|
||||
var err error
|
||||
if message != "" {
|
||||
_, err = pm.db.Execute("UPDATE publish SET status = ?, msg = ? WHERE token_id=? AND request_id = ?", status, message, pm.TokenID, requestID)
|
||||
_, err = pm.db.Execute("UPDATE publish SET status = ?, msg = ? WHERE id=?", status, message, id)
|
||||
} else {
|
||||
_, err = pm.db.Execute("UPDATE publish SET status = ? WHERE token_id=? AND request_id = ?", status, pm.TokenID, requestID)
|
||||
_, err = pm.db.Execute("UPDATE publish SET status = ? WHERE id=?", status, id)
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("更新发布状态失败: requestID=%s, status=%d, error=%v", requestID, status, err)
|
||||
log.Printf("更新发布状态失败: id=%s, status=%d, error=%v", id, status, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-rod/rod"
|
||||
"github.com/go-rod/rod/lib/proto"
|
||||
|
|
@ -29,17 +30,10 @@ func (p *BaijiahaoPublisher) CheckLoginStatus() bool {
|
|||
}
|
||||
|
||||
func (p *BaijiahaoPublisher) CheckLogin() (bool, string) {
|
||||
driverCreated := false
|
||||
defer func() {
|
||||
if driverCreated && p.Browser != nil {
|
||||
p.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
driverCreated = true
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
|
|
@ -53,17 +47,10 @@ func (p *BaijiahaoPublisher) CheckLogin() (bool, string) {
|
|||
}
|
||||
|
||||
func (p *BaijiahaoPublisher) WaitLogin() (bool, string) {
|
||||
driverCreated := false
|
||||
defer func() {
|
||||
if driverCreated && p.Browser != nil {
|
||||
p.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
driverCreated = true
|
||||
|
||||
p.Page.MustNavigate(p.LoginedURL)
|
||||
p.Sleep(3)
|
||||
|
|
@ -98,7 +85,7 @@ func (p *BaijiahaoPublisher) PublishNote() (bool, string) {
|
|||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
if p.LoadCookies() == nil {
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.WaitForPageReady(5)
|
||||
|
|
@ -121,14 +108,14 @@ func (p *BaijiahaoPublisher) doPublish() (bool, string) {
|
|||
name string
|
||||
fn func() error
|
||||
}{
|
||||
//{"切换到图文编辑模式", p.switchToGraphicMode},
|
||||
{"点击hover", p.clickHoverButton},
|
||||
{"输入内容", p.inputContent},
|
||||
{"输入标题", p.inputTitle},
|
||||
{"设置封面", p.uploadImage},
|
||||
{"点击发布按钮", p.clickPublish},
|
||||
{"处理确认弹窗", p.handleConfirmModal},
|
||||
//{"处理确认弹窗", p.handleConfirmModal},
|
||||
}
|
||||
|
||||
//https://baijiahao.baidu.com/builder/rc/clue?aside=0&footer=true&from=news&firstPublish=undefined&word_bag_id=null
|
||||
for _, step := range steps {
|
||||
if err := step.fn(); err != nil {
|
||||
p.LogStep(step.name, false, err.Error())
|
||||
|
|
@ -141,25 +128,50 @@ func (p *BaijiahaoPublisher) doPublish() (bool, string) {
|
|||
return p.waitForPublishResult()
|
||||
}
|
||||
|
||||
func (p *BaijiahaoPublisher) switchToGraphicMode() error {
|
||||
p.LogInfo("切换到图文编辑模式...")
|
||||
tabSelectors := []string{
|
||||
".list-item.item-active",
|
||||
".header-list-content .list-item",
|
||||
"div[role='tab']:first-child",
|
||||
func (p *BaijiahaoPublisher) clickHoverButton() error {
|
||||
p.LogInfo("点击HoverButton...")
|
||||
|
||||
// 等待弹窗稳定
|
||||
p.WaitForPageReady(5)
|
||||
_, err := p.Page.Element("div.cheetah-tour-content")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, selector := range tabSelectors {
|
||||
tab, err := p.Page.Element(selector)
|
||||
if err == nil && tab != nil {
|
||||
visible, _ := tab.Visible()
|
||||
if visible {
|
||||
p.JSClick(tab)
|
||||
p.LogInfo(fmt.Sprintf("已点击图文标签: %s", selector))
|
||||
p.Sleep(1)
|
||||
return nil
|
||||
|
||||
maxAttempts := 10
|
||||
for i := 0; i < maxAttempts; i++ {
|
||||
// 检查弹窗是否存在
|
||||
exists, _, err := p.Page.Has(".cheetah-tour")
|
||||
if err != nil || !exists {
|
||||
p.LogInfo("弹窗已关闭")
|
||||
break
|
||||
}
|
||||
|
||||
// 查找并点击弹窗中的按钮
|
||||
result, err := p.Page.Eval(`() => {
|
||||
const btns = document.querySelectorAll('.cheetah-tour .cheetah-btn, .cheetah-tour-next-btn, .cheetah-tour-close');
|
||||
for (const btn of btns) {
|
||||
if (btn.offsetParent !== null) {
|
||||
const text = btn.innerText || btn.textContent;
|
||||
btn.click();
|
||||
return text;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}`)
|
||||
|
||||
if err != nil {
|
||||
p.LogInfof("执行点击出错: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
p.LogInfof("第%d次点击按钮: %v", i+1, result)
|
||||
|
||||
// 等待弹窗响应
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
p.LogInfo("引导弹窗处理完成")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,76 +113,61 @@ func NewBasePublisher(ctx context.Context, task *TaskParams, config *config.Conf
|
|||
|
||||
func (b *BasePublisher) SetupDriver() error {
|
||||
b.LogInfo("初始化浏览器。。。。")
|
||||
b.Headless = true
|
||||
l := launcher.New().Bin(b.config.Sys.ChromePath)
|
||||
l.Headless(b.Headless)
|
||||
|
||||
// 设置 Leakless 模式(解决 Windows 上的问题)
|
||||
l.Leakless(false)
|
||||
userDataDir := filepath.Join(b.config.Sys.ChromeDataDir, b.UserIndex, b.RequestID+fmt.Sprintf("___%d", time.Now().UnixNano()))
|
||||
//userDataDir := fmt.Sprintf("./chrome_data/user_%d_", time.Now().UnixNano())
|
||||
os.MkdirAll(userDataDir, 0755)
|
||||
l := launcher.New().
|
||||
Bin(b.config.Sys.ChromePath).
|
||||
UserDataDir(userDataDir).
|
||||
Headless(b.Headless).
|
||||
Leakless(false).Set("disable-blink-features", "AutomationControlled")
|
||||
|
||||
if b.Headless {
|
||||
// 无头模式专用参数
|
||||
l.Set("headless", "new") // 使用新版无头模式
|
||||
l.Set("disable-gpu")
|
||||
l.Set("disable-software-rasterizer")
|
||||
l.Set("disable-dev-shm-usage")
|
||||
l.Set("no-sandbox")
|
||||
// 禁用虚拟滚动,避免等待
|
||||
//l.Set("disable-scroll-to-text-fragment")
|
||||
l.Set("disable-dev-shm-usage")
|
||||
} else {
|
||||
l.Set("window-size", "1920,1080")
|
||||
l.Set("start-maximized")
|
||||
// 移除 headless 相关参数
|
||||
l.Delete("headless")
|
||||
}
|
||||
// 设置用户数据目录
|
||||
|
||||
userDataDir := filepath.Join(b.config.Sys.ChromeDataDir, b.UserIndex)
|
||||
os.MkdirAll(userDataDir, 0755)
|
||||
|
||||
l.UserDataDir(userDataDir)
|
||||
// 为每个用户分配一个可用的随机端口,确保端口不冲突
|
||||
//freePort, err := pkg.GetFreePort()
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("获取空闲端口失败: %v", err)
|
||||
//}
|
||||
l.Set("remote-debugging-port", "0")
|
||||
|
||||
// 关键优化:不重新使用已有的数据目录时不要清除
|
||||
l.Set("profile-directory", "Default")
|
||||
//l.Set("profile-directory", "Default")
|
||||
|
||||
// 设置 Chrome 启动参数
|
||||
l.Set("disable-blink-features", "AutomationControlled")
|
||||
l.Set("no-sandbox")
|
||||
l.Set("disable-dev-shm-usage")
|
||||
l.Set("disable-gpu")
|
||||
l.Set("disable-software-rasterizer")
|
||||
l.Set("disable-setuid-sandbox")
|
||||
|
||||
//l.Set("no-sandbox")
|
||||
//l.Set("disable-dev-shm-usage")
|
||||
|
||||
// 关键:禁用后台限制,让页面在后台也能正常执行
|
||||
l.Set("disable-background-timer-throttling")
|
||||
l.Set("disable-backgrounding-occluded-windows")
|
||||
l.Set("disable-renderer-backgrounding")
|
||||
l.Set("disable-ipc-flooding-protection")
|
||||
//l.Set("disable-background-timer-throttling")
|
||||
//l.Set("disable-backgrounding-occluded-windows")
|
||||
//l.Set("disable-renderer-backgrounding")
|
||||
//l.Set("disable-ipc-flooding-protection")
|
||||
|
||||
// 窗口大小
|
||||
l.Set("window-size", "1920,1080")
|
||||
l.Set("lang", "zh-CN")
|
||||
l.Set("start-maximized")
|
||||
l.Set("force-device-scale-factor", "1")
|
||||
url, err := l.Launch()
|
||||
if err != nil {
|
||||
|
||||
return fmt.Errorf("启动浏览器失败: %v", err)
|
||||
}
|
||||
|
||||
b.Browser = rod.New().Context(b.ctx).ControlURL(url).MustConnect()
|
||||
b.Page = b.Browser.MustPage()
|
||||
time.Sleep(5000)
|
||||
return nil
|
||||
}
|
||||
|
||||
// func (b *BasePublisher) SetupDriver() error {
|
||||
// b.LogInfo("初始化浏览器。。。。")
|
||||
// b.Headless = true
|
||||
//
|
||||
// b.Browser = rod.New().Context(b.ctx).
|
||||
// b.Page = b.Browser.MustPage()
|
||||
// time.Sleep(5000)
|
||||
// return nil
|
||||
// }
|
||||
func (b *BasePublisher) Close() {
|
||||
if b.Page != nil {
|
||||
b.Page.Close()
|
||||
|
|
@ -223,6 +208,15 @@ func (b *BasePublisher) LoadCookies() error {
|
|||
return b.Page.SetCookies(cookies)
|
||||
}
|
||||
|
||||
func (b *BasePublisher) DelCookies() error {
|
||||
err := os.Remove(b.CookiesFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *BasePublisher) RefreshPage() error {
|
||||
_, err := b.Page.Eval(`() => location.reload()`)
|
||||
return err
|
||||
|
|
@ -294,7 +288,7 @@ func (b *BasePublisher) LogInfo(message string) {
|
|||
}
|
||||
|
||||
func (b *BasePublisher) LogInfof(message string, arg ...any) {
|
||||
b.Logger.Printf("📌 %s", message, arg)
|
||||
b.Logger.Printf("📌 "+message, arg)
|
||||
}
|
||||
|
||||
func (b *BasePublisher) LogError(message string) {
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ func (p *CSDNPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
// 执行发布流程
|
||||
steps := []struct {
|
||||
|
|
|
|||
|
|
@ -179,32 +179,22 @@ func (p *DouyinSpPublisher) waitForUploadComplete() error {
|
|||
func (p *DouyinSpPublisher) inputTitle() error {
|
||||
p.LogInfo("输入视频标题...")
|
||||
|
||||
titleSelectors := []string{
|
||||
"textarea[placeholder*='标题']",
|
||||
"input[placeholder*='标题']",
|
||||
".container-sGoJ9f input",
|
||||
".semiInput-EyEyPL input",
|
||||
exist, titleInput, err := p.Page.Has("input[placeholder*='标题']")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return fmt.Errorf("未找到标题输入框")
|
||||
}
|
||||
|
||||
for _, selector := range titleSelectors {
|
||||
titleInput, err := p.WaitForElementVisible(selector, 5)
|
||||
if err == nil && titleInput != nil {
|
||||
p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector))
|
||||
|
||||
p.ClearInput(titleInput)
|
||||
p.SleepMs(300)
|
||||
titleInput.Input("")
|
||||
p.SleepMs(300)
|
||||
titleInput.Input(p.Title)
|
||||
|
||||
p.LogInfo(fmt.Sprintf("标题已输入: %s", p.Title))
|
||||
p.SleepMs(500)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("未找到标题输入框")
|
||||
}
|
||||
|
||||
func (p *DouyinSpPublisher) inputDescription() error {
|
||||
p.LogInfo("输入视频描述...")
|
||||
|
|
@ -299,22 +289,6 @@ func (p *DouyinSpPublisher) clickPublish() error {
|
|||
p.LogInfo("已点击发布按钮")
|
||||
p.SleepMs(3000)
|
||||
|
||||
confirmSelectors := []string{
|
||||
".semi-modal .semi-button-primary",
|
||||
".confirm-btn-JwJNCk",
|
||||
"button:contains('确认')",
|
||||
"button:contains('确定')",
|
||||
}
|
||||
for _, selector := range confirmSelectors {
|
||||
confirmBtn, _ := p.WaitForElementClickable(selector, 2)
|
||||
if confirmBtn != nil {
|
||||
p.JSClick(confirmBtn)
|
||||
p.LogInfo("已确认发布")
|
||||
p.SleepMs(2000)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -374,15 +348,18 @@ func (p *DouyinSpPublisher) InitPage() error {
|
|||
|
||||
// 尝试加载cookies并检查登录状态
|
||||
if err := p.LoadCookies(); err == nil {
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Page.MustNavigate(p.LoginURL)
|
||||
p.WaitForPageReady(5)
|
||||
p.Sleep(2)
|
||||
p.Sleep(4)
|
||||
}
|
||||
// 统一检查登录状态
|
||||
if !p.CheckLoginStatus() {
|
||||
p.LogInfo("未登录或登录已过期,需要重新登录")
|
||||
p.DelCookies()
|
||||
return fmt.Errorf("需要登录")
|
||||
}
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.WaitForPageReady(5)
|
||||
p.SaveCookies()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -393,7 +370,7 @@ func (p *DouyinSpPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
steps := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ func (p *JianshuPublisher) WaitLogin() (bool, string) {
|
|||
defer p.Close()
|
||||
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.Sleep(3)
|
||||
p.Sleep(10)
|
||||
|
||||
if p.CheckLoginStatus() {
|
||||
p.SaveCookies()
|
||||
|
|
@ -305,7 +305,7 @@ func (p *JianshuPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
steps := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -471,13 +471,20 @@ func (p *SohuPublisher) InitPage() error {
|
|||
if err := p.LoadCookies(); err == nil {
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.WaitForPageReady(5)
|
||||
p.Sleep(2)
|
||||
|
||||
}
|
||||
|
||||
// 统一检查登录状态
|
||||
if !p.CheckLoginStatus() {
|
||||
p.LogInfo("未登录或登录已过期,需要重新登录")
|
||||
return fmt.Errorf("需要登录")
|
||||
}
|
||||
p.Sleep(3)
|
||||
|
||||
if p.GetCurrentURL() != p.EditorURL {
|
||||
p.Page.MustNavigate(p.EditorURL)
|
||||
p.WaitForPageReady(5)
|
||||
}
|
||||
p.SaveCookies()
|
||||
return nil
|
||||
}
|
||||
|
|
@ -488,7 +495,7 @@ func (p *SohuPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
steps := []struct {
|
||||
name string
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (p *ShipinhaoVideoPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
// 3. 加载 cookies 并检查登录状态
|
||||
if err := p.LoadCookies(); err == nil {
|
||||
p.Page.Navigate(p.EditorURL)
|
||||
|
|
|
|||
|
|
@ -473,7 +473,7 @@ func (p *ToutiaoPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
// 执行发布流程
|
||||
steps := []struct {
|
||||
|
|
|
|||
|
|
@ -115,22 +115,13 @@ func (p *XiaohongshuPublisher) inputTitle() error {
|
|||
p.LogInfo("输入标题...")
|
||||
|
||||
// 查找标题输入框
|
||||
titleSelectors := []string{
|
||||
"textarea.d-input",
|
||||
".d-input input",
|
||||
"textarea[placeholder*='标题']",
|
||||
"textarea",
|
||||
}
|
||||
|
||||
var titleInput *rod.Element
|
||||
var err error
|
||||
|
||||
for _, selector := range titleSelectors {
|
||||
titleInput, err = p.WaitForElementVisible(selector, 3)
|
||||
if err == nil && titleInput != nil {
|
||||
p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector))
|
||||
break
|
||||
}
|
||||
exsist, titleInput, err := p.Page.Has("textarea[placeholder*='标题']")
|
||||
if exsist && err == nil {
|
||||
p.LogInfo(fmt.Sprintf("找到标题输入框"))
|
||||
|
||||
}
|
||||
|
||||
if titleInput == nil {
|
||||
|
|
@ -286,8 +277,8 @@ func (p *XiaohongshuPublisher) clickPublish() error {
|
|||
|
||||
// 输入话题标签
|
||||
p.LogInfo("输入话题标签...")
|
||||
tiptap, err := p.WaitForElement(".tiptap-container", 10)
|
||||
if err == nil && tiptap != nil {
|
||||
exist, tiptap, err := p.Page.Has(".tiptap-container")
|
||||
if err == nil && exist {
|
||||
editors, err := tiptap.Elements("[contenteditable='true']")
|
||||
if err == nil && len(editors) > 0 {
|
||||
// 将tags转换为 #tag1 #tag2 格式
|
||||
|
|
@ -332,18 +323,6 @@ func (p *XiaohongshuPublisher) clickPublish() error {
|
|||
|
||||
func (p *XiaohongshuPublisher) waitForPublishResult() (bool, string) {
|
||||
p.LogInfo("等待发布结果...")
|
||||
|
||||
for attempt := 0; attempt < 30; attempt++ {
|
||||
// 检查是否出现失败提示
|
||||
toastDiv, err := p.WaitForElement(".creator-publish-toast", 2)
|
||||
if err == nil && toastDiv != nil {
|
||||
toastText, err := toastDiv.Text()
|
||||
if err == nil && toastText != "" {
|
||||
p.LogInfo(fmt.Sprintf("发布失败提示: %s", toastText))
|
||||
return false, fmt.Sprintf("发布失败: %s", toastText)
|
||||
}
|
||||
}
|
||||
|
||||
// 检查URL是否包含success
|
||||
info, err := p.Page.Info()
|
||||
if err == nil && strings.Contains(info.URL, "success") {
|
||||
|
|
@ -351,6 +330,17 @@ func (p *XiaohongshuPublisher) waitForPublishResult() (bool, string) {
|
|||
return true, "发布成功"
|
||||
}
|
||||
|
||||
for attempt := 0; attempt < 30; attempt++ {
|
||||
// 检查是否出现失败提示
|
||||
exist, toastDiv, err := p.Page.Has(".creator-publish-toast")
|
||||
if err == nil && exist {
|
||||
toastText, err := toastDiv.Text()
|
||||
if err == nil && toastText != "" {
|
||||
p.LogInfo(fmt.Sprintf("发布失败提示: %s", toastText))
|
||||
return false, fmt.Sprintf("发布失败: %s", toastText)
|
||||
}
|
||||
}
|
||||
|
||||
p.SleepMs(1000)
|
||||
}
|
||||
|
||||
|
|
@ -427,7 +417,7 @@ func (p *XiaohongshuPublisher) PublishNote() (bool, string) {
|
|||
if err := p.SetupDriver(); err != nil {
|
||||
return false, fmt.Sprintf("浏览器启动失败: %v", err)
|
||||
}
|
||||
defer p.Page.Close()
|
||||
defer p.Close()
|
||||
|
||||
// 执行发布流程
|
||||
steps := []struct {
|
||||
|
|
|
|||
|
|
@ -175,31 +175,22 @@ func (p *XiaohongshuVideoPublisher) waitForUploadComplete() error {
|
|||
func (p *XiaohongshuVideoPublisher) inputTitle() error {
|
||||
p.LogInfo(fmt.Sprintf("输入视频标题: %s", p.Title))
|
||||
|
||||
titleSelectors := []string{
|
||||
"textarea.d-input",
|
||||
".d-input input",
|
||||
"input[type='text']",
|
||||
"textarea",
|
||||
exist, titleInput, err := p.Page.Has("input[placeholder*='标题']")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !exist {
|
||||
return fmt.Errorf("未找到标题输入框")
|
||||
}
|
||||
|
||||
for _, selector := range titleSelectors {
|
||||
titleInput, err := p.WaitForElementVisible(selector, 5)
|
||||
if err == nil && titleInput != nil {
|
||||
p.LogInfo(fmt.Sprintf("找到标题输入框: %s", selector))
|
||||
|
||||
p.ClearInput(titleInput)
|
||||
p.SleepMs(300)
|
||||
titleInput.Input("")
|
||||
p.SleepMs(300)
|
||||
titleInput.Input(p.Title)
|
||||
|
||||
p.LogInfo(fmt.Sprintf("标题已输入: %s", p.Title))
|
||||
p.SleepMs(500)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("未找到标题输入框")
|
||||
}
|
||||
|
||||
func (p *XiaohongshuVideoPublisher) inputDescription() error {
|
||||
p.LogInfo("输入视频描述...")
|
||||
|
|
|
|||
|
|
@ -350,23 +350,16 @@ func (p *ZhihuPublisher) waitForPublishResult(timeout int) (bool, string) {
|
|||
for time.Since(startTime) < time.Duration(timeout)*time.Second {
|
||||
currentURL := p.GetCurrentURL()
|
||||
|
||||
// 检查失败弹窗
|
||||
failedDiv, err := p.Page.Element(".Notification-textSection")
|
||||
if err == nil && failedDiv != nil {
|
||||
visible, _ := failedDiv.Visible()
|
||||
if visible {
|
||||
failedReason, _ := failedDiv.Text()
|
||||
p.LogInfo(fmt.Sprintf("发布失败: %s", failedReason))
|
||||
return false, failedReason
|
||||
}
|
||||
}
|
||||
|
||||
successKeywords := []string{"/p/", "/article/", "/people/", "/column/"}
|
||||
for _, keyword := range successKeywords {
|
||||
if strings.Contains(currentURL, keyword) && !strings.Contains(currentURL, "write") {
|
||||
if !strings.Contains(currentURL, "/edit") {
|
||||
p.LogInfo(fmt.Sprintf("发布成功!URL: %s", currentURL))
|
||||
return true, "发布成功"
|
||||
}
|
||||
// 检查失败弹窗
|
||||
exist, failedDiv, _ := p.Page.HasX(".Notification-textSection")
|
||||
if exist {
|
||||
failedReason, _ := failedDiv.Text()
|
||||
p.LogInfo(fmt.Sprintf("发布失败: %s", failedReason))
|
||||
return false, failedReason
|
||||
}
|
||||
|
||||
p.SleepMs(1000)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package service
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
|
@ -27,10 +28,14 @@ func TestMultipleChromeProcesses(t *testing.T) {
|
|||
time.Sleep(10 * time.Minute)
|
||||
}
|
||||
|
||||
func TestKill(t *testing.T) {
|
||||
exec.Command("taskkill", "/F", "/IM", "chrome.exe").Run()
|
||||
}
|
||||
|
||||
// TestCustomChromeWithMixedHeadless 使用自定义Chrome浏览器,启动5个进程(偶数有头,奇数无头)
|
||||
func TestCustomChromeWithMixedHeadless(t *testing.T) {
|
||||
// 配置你的Chrome路径
|
||||
chromePath := "D:\\gop\\geoGo\\chrome\\chrome.exe"
|
||||
chromePath := "D:\\goProject\\geogo\\chrome\\chrome.exe"
|
||||
|
||||
processCount := 5
|
||||
browsers := make([]*rod.Browser, processCount)
|
||||
|
|
@ -111,7 +116,7 @@ func TestCustomChromeWithMixedHeadless(t *testing.T) {
|
|||
t.Logf("[进程 %d] 无头模式已访问 example.com(不可见)", idx)
|
||||
}
|
||||
|
||||
page.MustClose()
|
||||
//page.MustClose()
|
||||
}(i)
|
||||
}
|
||||
|
||||
|
|
@ -132,7 +137,7 @@ func TestCustomChromeWithMixedHeadless(t *testing.T) {
|
|||
t.Logf("成功启动 %d/%d 个 Chrome 进程", successCount, processCount)
|
||||
t.Log("浏览器窗口已打开(有头模式可见),按 Enter 键关闭所有进程...")
|
||||
fmt.Scanln()
|
||||
|
||||
select {}
|
||||
// 清理
|
||||
//for i, browser := range browsers {
|
||||
// if browser != nil {
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ func (s *PublishService) PublishStatus(c *fiber.Ctx, req *entitys.PublishStatusR
|
|||
//}
|
||||
|
||||
func (s *PublishService) PublishExecuteRetry(c *fiber.Ctx, req *entitys.PublishExecuteRetryRequest) error {
|
||||
_, err := s.publishBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
||||
tokenInfo, err := s.publishBiz.ValidateAccessToken(c.UserContext(), req.AccessToken)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -156,7 +156,7 @@ func (s *PublishService) PublishExecuteRetry(c *fiber.Ctx, req *entitys.PublishE
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
result := pm.RetryTask(c.UserContext(), req.RequestID)
|
||||
result := pm.RetryTask(c.UserContext(), int(tokenInfo.ID), req.RequestID)
|
||||
return pkg.HandleResponse(c, result)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,485 +0,0 @@
|
|||
GOROOT=D:\go #gosetup
|
||||
GOPATH=D:\go #gosetup
|
||||
D:\go\bin\go.exe build -o C:\Users\Administrator\AppData\Local\JetBrains\GoLand2025.2\tmp\GoLand\___go_build_geo_cmd_server.exe -gcflags "all=-N -l" geo/cmd/server #gosetup
|
||||
warning: both GOPATH and GOROOT are the same directory (D:\go); see https://go.dev/wiki/InstallTroubleshooting
|
||||
"D:\GoLand 2025.2.5\plugins\go-plugin\lib\dlv\windows\dlv.exe" --listen=127.0.0.1:62082 --headless=true --api-version=2 --check-go-version=false --only-same-user=false exec C:\Users\Administrator\AppData\Local\JetBrains\GoLand2025.2\tmp\GoLand\___go_build_geo_cmd_server.exe -- #gosetup
|
||||
API server listening at: 127.0.0.1:62082
|
||||
WARNING: undefined behavior - version of Delve is too old for Go version go1.26.1 (maximum supported version 1.25)
|
||||
|
||||
┌───────────────────────────────────────────────────┐
|
||||
│ Fiber v2.52.12 │
|
||||
│ http://127.0.0.1:5001 │
|
||||
│ (bound on host 0.0.0.0 and port 5001) │
|
||||
│ │
|
||||
│ Handlers ............ 17 Processes ........... 1 │
|
||||
│ Prefork ....... Disabled PID ............. 22108 │
|
||||
└───────────────────────────────────────────────────┘
|
||||
|
||||
|
||||
2026/04/10 16:52:53 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[423.550ms] [rows:1] SELECT * FROM `token` WHERE access_token='6cb55ce2-2556-4908-91b5-5b78f0168cce' AND status=1 LIMIT 1
|
||||
token
|
||||
16:52:53 | 200 | 424.6891ms | 127.0.0.1 | POST | /publish_on | -
|
||||
2026/04/10 16:52:53 自动发布服务已启动,tokenID=1,worker数量=3
|
||||
2026/04/10 16:52:53 [Worker-1] 启动,tokenID=1
|
||||
2026/04/10 16:52:53 [Worker-2] 启动,tokenID=1
|
||||
2026/04/10 16:52:53 [Worker-0] 启动,tokenID=1
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[412.746ms] [rows:1]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='cd76b1df-df01-4a'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:52:53'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[418.524ms] [rows:1]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='f2a6982a-8bef-4e'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:52:53'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[425.694ms] [rows:1]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='eba6d8a6-88c3-49'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:52:53'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[391.244ms] [rows:1]
|
||||
SELECT
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
p.tag,
|
||||
p.user_index,
|
||||
p.url,
|
||||
p.img,
|
||||
p.publish_time,
|
||||
p.status,
|
||||
pl.index as plat_index_value,
|
||||
pl.status as plat_status,
|
||||
pl.login_url,
|
||||
pl.edit_url,
|
||||
pl.logined_url,
|
||||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE uid='cd76b1df-df01-4a' AND p.token_id = 1
|
||||
ORDER BY p.publish_time DESC
|
||||
LIMIT 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:52:54.478724 ================================================================================
|
||||
2026/04/10 16:52:54.478724 任务开始 | RequestID: 6 | 时间: 2026-04-10 16:52:54.478
|
||||
2026/04/10 16:52:54.478724 ================================================================================
|
||||
2026/04/10 16:52:54.478724 [任务 6] 开始处理(headless=true)
|
||||
2026/04/10 16:52:54.478724 [任务 6] 任务详情 - 平台:zh,标题:地推看过来!!!,用户:0d86b848uu2183uu4a08
|
||||
2026/04/10 16:52:54.478724 [任务 6] 标签解析完成: [#地推 #四川地推 #创业]
|
||||
2026/04/10 16:52:54.478724 [任务 6] 开始下载文档...
|
||||
2026/04/10 16:52:54 [Worker-1] 开始处理任务 requestID=6
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[406.859ms] [rows:1]
|
||||
SELECT
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
p.tag,
|
||||
p.user_index,
|
||||
p.url,
|
||||
p.img,
|
||||
p.publish_time,
|
||||
p.status,
|
||||
pl.index as plat_index_value,
|
||||
pl.status as plat_status,
|
||||
pl.login_url,
|
||||
pl.edit_url,
|
||||
pl.logined_url,
|
||||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE uid='f2a6982a-8bef-4e' AND p.token_id = 1
|
||||
ORDER BY p.publish_time DESC
|
||||
LIMIT 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:52:54.499312 ================================================================================
|
||||
2026/04/10 16:52:54.499312 任务开始 | RequestID: 4 | 时间: 2026-04-10 16:52:54.499
|
||||
2026/04/10 16:52:54.499312 ================================================================================
|
||||
2026/04/10 16:52:54.499840 [任务 4] 开始处理(headless=true)
|
||||
2026/04/10 16:52:54.499840 [任务 4] 任务详情 - 平台:xhssp,标题:萌妹,用户:0d86b848uu2183uu4a08
|
||||
2026/04/10 16:52:54.499840 [任务 4] 标签解析完成: [萌妹 宅舞 超性感]
|
||||
2026/04/10 16:52:54.499840 [任务 4] 开始下载文档...
|
||||
|
||||
2026/04/10 16:52:54 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[401.220ms] [rows:1]
|
||||
SELECT
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
p.tag,
|
||||
p.user_index,
|
||||
p.url,
|
||||
p.img,
|
||||
p.publish_time,
|
||||
p.status,
|
||||
pl.index as plat_index_value,
|
||||
pl.status as plat_status,
|
||||
pl.login_url,
|
||||
pl.edit_url,
|
||||
pl.logined_url,
|
||||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE uid='eba6d8a6-88c3-49' AND p.token_id = 1
|
||||
ORDER BY p.publish_time DESC
|
||||
LIMIT 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:52:54.501413 ================================================================================
|
||||
2026/04/10 16:52:54.501413 任务开始 | RequestID: 5 | 时间: 2026-04-10 16:52:54.501
|
||||
2026/04/10 16:52:54.501413 ================================================================================
|
||||
2026/04/10 16:52:54.501413 [任务 5] 开始处理(headless=true)
|
||||
2026/04/10 16:52:54.501413 [任务 5] 任务详情 - 平台:sphsp,标题:盘点全网最火的meme原型,用户:0d86b848uu2183uu4a08
|
||||
2026/04/10 16:52:54.501413 [任务 5] 标签解析完成: [猫 meme 万恶之源]
|
||||
2026/04/10 16:52:54.501413 [任务 5] 开始下载文档...
|
||||
2026/04/10 16:52:54 [Worker-2] 开始处理任务 requestID=4
|
||||
2026/04/10 16:52:54 [Worker-0] 开始处理任务 requestID=5
|
||||
2026/04/10 16:52:54.568721 [任务 6] ✅ 文档下载成功: D:\gop\geoGo\docs\6.docx
|
||||
2026/04/10 16:52:54.569769 [任务 6] 开始下载图片...
|
||||
2026/04/10 16:52:54.629638 [任务 6] ✅ 图片下载成功: D:\gop\geoGo\images\6_1e3dcdb4-0f8a-4b57-aac2-85ecff03ff12.jpg
|
||||
2026/04/10 16:52:55.723048 [任务 4] ✅ 文档下载成功: D:\gop\geoGo\docs\4.mp4
|
||||
2026/04/10 16:52:55.723048 [任务 4] 开始下载图片...
|
||||
2026/04/10 16:52:56.014721 [任务 5] ✅ 文档下载成功: D:\gop\geoGo\docs\5.mp4
|
||||
2026/04/10 16:52:56.015773 [任务 5] 开始下载图片...
|
||||
2026/04/10 16:52:56.206874 [任务 5] ✅ 图片下载成功: D:\gop\geoGo\images\5_003e4110-e937-491f-8cf2-92df3de00a8c.png
|
||||
2026/04/10 16:52:56.206874 [任务 5] 开始执行发布...
|
||||
2026/04/10 16:52:56.206874 📌 ==================================================
|
||||
2026/04/10 16:52:56.206874 📌 开始执行:sphsp
|
||||
2026/04/10 16:52:56.206874 📌 标题: 盘点全网最火的meme原型
|
||||
2026/04/10 16:52:56.206874 📌 标签: [猫 meme 万恶之源]
|
||||
2026/04/10 16:52:56.206874 📌 ==================================================
|
||||
2026/04/10 16:52:56.206874 📌 初始化浏览器。。。。
|
||||
2026/04/10 16:52:56.233002 [任务 4] ✅ 图片下载成功: D:\gop\geoGo\images\4_769c6040-bff9-472b-9b9c-33d8f74cf61f.png
|
||||
2026/04/10 16:52:56.233002 [任务 4] 开始执行发布...
|
||||
2026/04/10 16:52:56.233002 📌 ==================================================
|
||||
2026/04/10 16:52:56.233002 📌 开始执行:xhssp
|
||||
2026/04/10 16:52:56.233002 📌 标题: 萌妹
|
||||
2026/04/10 16:52:56.233002 📌 标签: [萌妹 宅舞 超性感]
|
||||
2026/04/10 16:52:56.233002 📌 ==================================================
|
||||
2026/04/10 16:52:56.233002 📌 初始化浏览器。。。。
|
||||
2026/04/10 16:52:56.907120 [任务 6] 开始提取文档内容...
|
||||
2026/04/10 16:52:58.614081 [任务 6] ✅ 内容提取成功,长度: 69
|
||||
2026/04/10 16:52:58.614081 [任务 6] 开始执行发布...
|
||||
2026/04/10 16:52:58.614081 📌 ==================================================
|
||||
2026/04/10 16:52:58.614081 📌 开始执行:zh
|
||||
2026/04/10 16:52:58.614081 📌 标题: 地推看过来!!!
|
||||
2026/04/10 16:52:58.614081 📌 标签: [#地推 #四川地推 #创业]
|
||||
2026/04/10 16:52:58.614081 📌 ==================================================
|
||||
2026/04/10 16:52:58.614081 📌 初始化浏览器。。。。
|
||||
2026/04/10 16:52:58.616804 ✅ 初始化页面: 成功
|
||||
2026/04/10 16:52:59.468517 [任务 5] ❌ 发布失败: 需要登录
|
||||
2026/04/10 16:52:59.617059 📌 开始上传视频: D:\gop\geoGo\docs\4.mp4
|
||||
2026/04/10 16:52:59.646726 📌 视频文件已选择: D:\gop\geoGo\docs\4.mp4
|
||||
2026/04/10 16:52:59.646726 📌 等待视频上传完成...
|
||||
|
||||
2026/04/10 16:52:59 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[429.171ms] [rows:1] UPDATE publish SET status = 3, msg = '需要登录' WHERE token_id=1 AND request_id = '5'
|
||||
publish
|
||||
2026/04/10 16:52:59.897687 ================================================================================
|
||||
2026/04/10 16:52:59.897687 任务结束 | RequestID: 5 | 结果: false
|
||||
2026/04/10 16:52:59.898712 [任务 5] 已删除文档文件: D:\gop\geoGo\docs\5.mp4
|
||||
2026/04/10 16:52:59.899367 [任务 5] 已删除图片文件: D:\gop\geoGo\images\5_003e4110-e937-491f-8cf2-92df3de00a8c.png
|
||||
2026/04/10 16:52:59 [Worker-0] 任务失败: 需要登录
|
||||
2026/04/10 16:53:00.050108 📌 发布按钮已可点击,视频上传完成
|
||||
2026/04/10 16:53:00.050108 ✅ 上传视频: 成功
|
||||
2026/04/10 16:53:01.050256 📌 输入视频标题: 萌妹
|
||||
2026/04/10 16:53:01.755888 📌 未登录或登录已过期,需要重新登录
|
||||
2026/04/10 16:53:01.755888 ❌ 初始化页面: 失败 需要登录
|
||||
2026/04/10 16:53:01.779792 [任务 6] ❌ 发布失败: 初始化页面失败: 需要登录
|
||||
|
||||
2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[427.718ms] [rows:1] UPDATE publish SET status = 3, msg = '初始化页面失败: 需要登录' WHERE token_id=1 AND request_id = '6'
|
||||
publish
|
||||
2026/04/10 16:53:02.207510 ================================================================================
|
||||
2026/04/10 16:53:02.207510 任务结束 | RequestID: 6 | 结果: false
|
||||
2026/04/10 16:53:02.208014 [任务 6] 已删除文档文件: D:\gop\geoGo\docs\6.docx
|
||||
2026/04/10 16:53:02.208014 [任务 6] 已删除图片文件: D:\gop\geoGo\images\6_1e3dcdb4-0f8a-4b57-aac2-85ecff03ff12.jpg
|
||||
2026/04/10 16:53:02 [Worker-1] 任务失败: 初始化页面失败: 需要登录
|
||||
|
||||
2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[406.214ms] [rows:1]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='e3a191eb-07d2-48'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:53:01'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:53:02.529767 ❌ 输入标题: 失败 未找到标题输入框
|
||||
2026/04/10 16:53:02.529767 [任务 4] ❌ 发布失败: 输入标题失败: 未找到标题输入框
|
||||
|
||||
2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[379.609ms] [rows:1]
|
||||
SELECT
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
p.tag,
|
||||
p.user_index,
|
||||
p.url,
|
||||
p.img,
|
||||
p.publish_time,
|
||||
p.status,
|
||||
pl.index as plat_index_value,
|
||||
pl.status as plat_status,
|
||||
pl.login_url,
|
||||
pl.edit_url,
|
||||
pl.logined_url,
|
||||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE uid='e3a191eb-07d2-48' AND p.token_id = 1
|
||||
ORDER BY p.publish_time DESC
|
||||
LIMIT 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:53:02.686657 ================================================================================
|
||||
2026/04/10 16:53:02.686657 任务开始 | RequestID: 1 | 时间: 2026-04-10 16:53:02.686
|
||||
2026/04/10 16:53:02.686657 ================================================================================
|
||||
2026/04/10 16:53:02.686657 [任务 1] 开始处理(headless=true)
|
||||
2026/04/10 16:53:02.686657 [任务 1] 任务详情 - 平台:xhs,标题:房地产新格局,用户:0d86b848uu2183uu4a08
|
||||
2026/04/10 16:53:02.686657 [任务 1] 标签解析完成: [房地产 房地产格局]
|
||||
2026/04/10 16:53:02.686657 [任务 1] 开始下载文档...
|
||||
2026/04/10 16:53:02 [Worker-0] 开始处理任务 requestID=1
|
||||
2026/04/10 16:53:02.750797 [任务 1] ✅ 文档下载成功: D:\gop\geoGo\docs\1.docx
|
||||
2026/04/10 16:53:02.750797 [任务 1] 开始下载图片...
|
||||
|
||||
2026/04/10 16:53:02 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[445.705ms] [rows:1] UPDATE publish SET status = 3, msg = '输入标题失败: 未找到标题输入框' WHERE token_id=1 AND request_id = '4'
|
||||
publish
|
||||
2026/04/10 16:53:02.975473 ================================================================================
|
||||
2026/04/10 16:53:02.975473 任务结束 | RequestID: 4 | 结果: false
|
||||
2026/04/10 16:53:02.976009 [任务 4] 已删除文档文件: D:\gop\geoGo\docs\4.mp4
|
||||
2026/04/10 16:53:02.976539 [任务 4] 已删除图片文件: D:\gop\geoGo\images\4_769c6040-bff9-472b-9b9c-33d8f74cf61f.png
|
||||
2026/04/10 16:53:02 [Worker-2] 任务失败: 输入标题失败: 未找到标题输入框
|
||||
2026/04/10 16:53:03.042424 [任务 1] ✅ 图片下载成功: D:\gop\geoGo\images\1_9ffe0dd7-108b-455d-aca4-bf729eba7ab9.png
|
||||
2026/04/10 16:53:03.042424 [任务 1] 开始提取文档内容...
|
||||
|
||||
2026/04/10 16:53:04 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[378.221ms] [rows:1]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='5b37ab96-e0de-46'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:53:04'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:53:04.715720 [任务 1] ✅ 内容提取成功,长度: 5372
|
||||
2026/04/10 16:53:04.715720 [任务 1] 开始执行发布...
|
||||
2026/04/10 16:53:04.715720 📌 ==================================================
|
||||
2026/04/10 16:53:04.715720 📌 开始执行:xhs
|
||||
2026/04/10 16:53:04.715720 📌 标题: 房地产新格局
|
||||
2026/04/10 16:53:04.715720 📌 标签: [房地产 房地产格局]
|
||||
2026/04/10 16:53:04.715720 📌 ==================================================
|
||||
2026/04/10 16:53:04.715720 📌 初始化浏览器。。。。
|
||||
|
||||
2026/04/10 16:53:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[421.319ms] [rows:1]
|
||||
SELECT
|
||||
p.request_id,
|
||||
p.plat_index,
|
||||
p.title,
|
||||
p.tag,
|
||||
p.user_index,
|
||||
p.url,
|
||||
p.img,
|
||||
p.publish_time,
|
||||
p.status,
|
||||
pl.index as plat_index_value,
|
||||
pl.status as plat_status,
|
||||
pl.login_url,
|
||||
pl.edit_url,
|
||||
pl.logined_url,
|
||||
pl.desc
|
||||
FROM publish p
|
||||
INNER JOIN plat pl ON p.plat_index COLLATE utf8mb4_unicode_ci = pl.index AND pl.status = 1
|
||||
WHERE uid='5b37ab96-e0de-46' AND p.token_id = 1
|
||||
ORDER BY p.publish_time DESC
|
||||
LIMIT 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:53:05.009080 ================================================================================
|
||||
2026/04/10 16:53:05.009080 任务开始 | RequestID: 2 | 时间: 2026-04-10 16:53:05.009
|
||||
2026/04/10 16:53:05.009080 ================================================================================
|
||||
2026/04/10 16:53:05.009080 [任务 2] 开始处理(headless=true)
|
||||
2026/04/10 16:53:05.009080 [任务 2] 任务详情 - 平台:xhs,标题:健身与猝死的关系,用户:0d86b848uu2183uu4a08
|
||||
2026/04/10 16:53:05.009080 [任务 2] 标签解析完成: [健身 猝死]
|
||||
2026/04/10 16:53:05.009080 [任务 2] 开始下载文档...
|
||||
2026/04/10 16:53:05 [Worker-1] 开始处理任务 requestID=2
|
||||
2026/04/10 16:53:05.067271 [任务 2] ✅ 文档下载成功: D:\gop\geoGo\docs\2.docx
|
||||
2026/04/10 16:53:05.067271 [任务 2] 开始下载图片...
|
||||
2026/04/10 16:53:05.309691 [任务 2] ✅ 图片下载成功: D:\gop\geoGo\images\2_ec459546-2873-4539-ae96-4d99c19ec62d.jpg
|
||||
2026/04/10 16:53:05.309691 [任务 2] 开始提取文档内容...
|
||||
|
||||
2026/04/10 16:53:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[401.004ms] [rows:0]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='d54d1bab-80a4-4a'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:53:04'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:53:06.894855 [任务 2] ✅ 内容提取成功,长度: 2274
|
||||
2026/04/10 16:53:06.894855 [任务 2] 开始执行发布...
|
||||
2026/04/10 16:53:06.894855 📌 ==================================================
|
||||
2026/04/10 16:53:06.894855 📌 开始执行:xhs
|
||||
2026/04/10 16:53:06.894855 📌 标题: 健身与猝死的关系
|
||||
2026/04/10 16:53:06.894855 📌 标签: [健身 猝死]
|
||||
2026/04/10 16:53:06.894855 📌 ==================================================
|
||||
2026/04/10 16:53:06.894855 📌 初始化浏览器。。。。
|
||||
2026/04/10 16:53:07.849886 ✅ 初始化: 成功
|
||||
2026/04/10 16:53:08.352714 ✅ 保存cookie: 成功
|
||||
2026/04/10 16:53:09.245978 ✅ 初始化: 成功
|
||||
2026/04/10 16:53:09.748755 ✅ 保存cookie: 成功
|
||||
2026/04/10 16:53:10.331882 📌 已点击上传按钮
|
||||
2026/04/10 16:53:11.332203 ✅ 点击上传按钮: 成功
|
||||
2026/04/10 16:53:11.832762 📌 输入文章内容...
|
||||
2026/04/10 16:53:12.378724 📌 清空编辑器失败: eval js error: TypeError: Cannot set properties of undefined (setting 'innerText')
|
||||
at HTMLDivElement.<anonymous> (<anonymous>:1:44)
|
||||
at HTMLDivElement.<anonymous> (<anonymous>:1:127) <nil>
|
||||
2026/04/10 16:53:12.748818 📌 内容已输入,长度: 2274
|
||||
2026/04/10 16:53:12.748818 ✅ 输入内容: 成功
|
||||
2026/04/10 16:53:13.249362 📌 输入标题...
|
||||
|
||||
2026/04/10 16:53:37 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[438.945ms] [rows:0]
|
||||
UPDATE publish p
|
||||
SET p.status = 2,uid='49e9bf0f-120a-4c'
|
||||
WHERE p.request_id = (
|
||||
SELECT request_id FROM (
|
||||
SELECT p2.request_id
|
||||
FROM publish p2
|
||||
INNER JOIN plat pl ON p2.plat_index COLLATE utf8mb4_unicode_ci = pl.index
|
||||
WHERE p2.token_id = 1
|
||||
AND p2.status = 1
|
||||
AND p2.publish_time <= '2026-04-10 16:53:37'
|
||||
AND pl.status = 1
|
||||
ORDER BY p2.publish_time ASC
|
||||
LIMIT 1
|
||||
) AS tmp
|
||||
)
|
||||
AND p.status = 1
|
||||
|
||||
publish
|
||||
2026/04/10 16:54:02 任务执行超时,[Worker-0] context deadline exceeded requestID=1
|
||||
2026/04/10 16:54:02.688485 click fail:context deadline exceeded
|
||||
2026/04/10 16:54:02.688485 ❌ 点击上传按钮: 失败 JS点击按钮失败: context deadline exceeded
|
||||
2026/04/10 16:54:02.689219 [任务 1] ❌ 发布失败: 点击上传按钮失败: JS点击按钮失败: context deadline exceeded
|
||||
|
||||
2026/04/10 16:54:03 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[421.134ms] [rows:1] UPDATE publish SET status = 3, msg = '任务执行超时,[Worker-0] context deadline exceeded requestID=1' WHERE token_id=1 AND request_id = '1'
|
||||
publish
|
||||
|
||||
2026/04/10 16:54:03 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[470.041ms] [rows:1] UPDATE publish SET status = 3, msg = '点击上传按钮失败: JS点击按钮失败: context deadline exceeded' WHERE token_id=1 AND request_id = '1'
|
||||
publish
|
||||
2026/04/10 16:54:03.159260 ================================================================================
|
||||
2026/04/10 16:54:03.159260 任务结束 | RequestID: 1 | 结果: false
|
||||
2026/04/10 16:54:03.159767 [任务 1] 已删除文档文件: D:\gop\geoGo\docs\1.docx
|
||||
2026/04/10 16:54:03.160296 [任务 1] 已删除图片文件: D:\gop\geoGo\images\1_9ffe0dd7-108b-455d-aca4-bf729eba7ab9.png
|
||||
2026/04/10 16:54:05 任务执行超时,[Worker-1] context deadline exceeded requestID=2
|
||||
2026/04/10 16:54:05.009280 ❌ 输入标题: 失败 未找到标题输入框
|
||||
2026/04/10 16:54:05.009280 [任务 2] ❌ 发布失败: 输入标题失败: 未找到标题输入框
|
||||
|
||||
2026/04/10 16:54:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[403.700ms] [rows:1] UPDATE publish SET status = 3, msg = '任务执行超时,[Worker-1] context deadline exceeded requestID=2' WHERE token_id=1 AND request_id = '2'
|
||||
publish
|
||||
|
||||
2026/04/10 16:54:05 D:/gop/geoGo/utils/utils_gorm/sql_log.go:46 SLOW SQL >= 200ms
|
||||
[428.723ms] [rows:1] UPDATE publish SET status = 3, msg = '输入标题失败: 未找到标题输入框' WHERE token_id=1 AND request_id = '2'
|
||||
publish
|
||||
2026/04/10 16:54:05.438513 ================================================================================
|
||||
2026/04/10 16:54:05.438513 任务结束 | RequestID: 2 | 结果: false
|
||||
2026/04/10 16:54:05.439077 [任务 2] 已删除文档文件: D:\gop\geoGo\docs\2.docx
|
||||
2026/04/10 16:54:05.439641 [任务 2] 已删除图片文件: D:\gop\geoGo\images\2_ec459546-2873-4539-ae96-4d99c19ec62d.jpg
|
||||
|
||||
|
||||
Loading…
Reference in New Issue