fix: 允许已采集 PDD 商品重新采集 (#121)
This commit is contained in:
@@ -589,6 +589,75 @@ func CreatePddCollectTasksForUser(db *sql.DB, actor *model.User, goodsIDs []stri
|
||||
return createPddCollectTasks(db, goodsIDs, strings.TrimSpace(clientID), visibleUserID)
|
||||
}
|
||||
|
||||
// RecollectPddProductForUser 为详情页一次明确的重新采集创建单商品任务。
|
||||
// 普通批量入口仍跳过 collected;本入口允许 collected,但保留旧采集数据,
|
||||
// 等 Client 成功提交新结果后再由既有提交逻辑覆盖。
|
||||
func RecollectPddProductForUser(db *sql.DB, actor *model.User, goodsID, clientID string) (CollectTaskResult, error) {
|
||||
var result CollectTaskResult
|
||||
goodsID = strings.TrimSpace(goodsID)
|
||||
clientID = strings.TrimSpace(clientID)
|
||||
if goodsID == "" {
|
||||
return result, invalidInput("商品 ID 不能为空")
|
||||
}
|
||||
|
||||
visibleUserID, err := visibleClientUserID(actor)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("开始事务失败: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
if clientID != "" {
|
||||
visible, err := repository.ClientVisibleToUser(tx, clientID, visibleUserID)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if !visible {
|
||||
return result, invalidInput("所选客户端不存在或不在当前账号可见范围")
|
||||
}
|
||||
}
|
||||
|
||||
p, err := repository.GetPddProductByGoodsID(tx, goodsID)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if p == nil || p.IsDeleted() {
|
||||
result.SkippedDeleted = 1
|
||||
if err := tx.Commit(); err != nil {
|
||||
return CollectTaskResult{}, fmt.Errorf("提交事务失败: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
ok, err := repository.MarkRecollecting(tx, goodsID)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
if !ok {
|
||||
result.SkippedCollecting = 1
|
||||
if wait, ok := retryWaitFor(p.UpdatedAt); ok {
|
||||
result.RetryWaitText = formatRetryWait(wait)
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return CollectTaskResult{}, fmt.Errorf("提交事务失败: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
if err := repository.InsertCollectTaskForClient(
|
||||
tx, newCollectTaskID(), p.GoodsID, p.URL, clientID); err != nil {
|
||||
return result, err
|
||||
}
|
||||
result.Created = 1
|
||||
if err := tx.Commit(); err != nil {
|
||||
return CollectTaskResult{}, fmt.Errorf("提交事务失败: %w", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func createPddCollectTasks(db *sql.DB, goodsIDs []string, clientID, visibleUserID string) (CollectTaskResult, error) {
|
||||
var result CollectTaskResult
|
||||
|
||||
|
||||
@@ -720,6 +720,90 @@ func TestCreatePddCollectTasksForUser_不指定时保持无主待领(t *testing.
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecollectPddProductForUser_已采集商品保留旧结果并创建任务(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
admin := prepareAdminUser(t, db, time.Date(2026, 8, 10, 1, 0, 0, 0, time.UTC))
|
||||
createProduct(t, db, "737116531267")
|
||||
if err := repository.SetCollectResult(
|
||||
db, "737116531267", "旧标题", "旧店铺", sampleSkusJSON); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
before, _ := repository.GetPddProductByGoodsID(db, "737116531267")
|
||||
|
||||
result, err := RecollectPddProductForUser(db, admin, "737116531267", "")
|
||||
if err != nil || result.Created != 1 || result.Skipped() != 0 {
|
||||
t.Fatalf("已采集商品应该能明确重采: result=%+v err=%v", result, err)
|
||||
}
|
||||
after, _ := repository.GetPddProductByGoodsID(db, "737116531267")
|
||||
if after.CollectStatus != model.CollectCollecting {
|
||||
t.Errorf("重采后状态应为 collecting,实际 %s", after.CollectStatus)
|
||||
}
|
||||
if after.Title != before.Title || after.ShopName != before.ShopName ||
|
||||
after.SkusJSON != before.SkusJSON || after.CollectedAt != before.CollectedAt {
|
||||
t.Errorf("重采开始时不应清空旧结果,before=%+v after=%+v", before, after)
|
||||
}
|
||||
status, assigned, _, ok := collectTaskOf(t, db, "737116531267")
|
||||
if !ok || status != "pending" || assigned != "" {
|
||||
t.Fatalf("应该创建无主待领任务: status=%q assigned=%q ok=%t", status, assigned, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecollectPddProductForUser_连续点击只创建一条任务(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
admin := prepareAdminUser(t, db, time.Date(2026, 8, 10, 1, 0, 0, 0, time.UTC))
|
||||
createProduct(t, db, "737116531267")
|
||||
if err := repository.SetCollectResult(db, "737116531267", "已采集", "", sampleSkusJSON); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
first, err := RecollectPddProductForUser(db, admin, "737116531267", "")
|
||||
if err != nil || first.Created != 1 {
|
||||
t.Fatalf("第一次重采失败: result=%+v err=%v", first, err)
|
||||
}
|
||||
second, err := RecollectPddProductForUser(db, admin, "737116531267", "")
|
||||
if err != nil || second.Created != 0 || second.SkippedCollecting != 1 {
|
||||
t.Fatalf("第二次应识别正在采集: result=%+v err=%v", second, err)
|
||||
}
|
||||
var taskCount int
|
||||
if err := db.QueryRow(`SELECT COUNT(*) FROM tasks WHERE task_type='collect' AND pdd_goods_id=?`,
|
||||
"737116531267").Scan(&taskCount); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if taskCount != 1 {
|
||||
t.Fatalf("连续点击只能创建一条任务,实际 %d", taskCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecollectPddProductForUser_不可见客户端时完整回滚(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
admin, buyerA, buyerB := prepareClientAssignmentUsers(t, db)
|
||||
RegisterClient(db, model.Client{ClientID: "client-b", Name: "B 的机器"}, true)
|
||||
if _, _, err := AssignClient(db, admin, "client-b", buyerB.UserID,
|
||||
time.Date(2026, 8, 10, 1, 0, 0, 0, time.UTC)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
createProduct(t, db, "737116531267")
|
||||
if err := repository.SetCollectResult(db, "737116531267", "旧标题", "", sampleSkusJSON); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
_, err := RecollectPddProductForUser(db, buyerA, "737116531267", "client-b")
|
||||
if !IsValidationError(err) {
|
||||
t.Fatalf("不可见客户端应返回表单错误,实际 %v", err)
|
||||
}
|
||||
p, _ := repository.GetPddProductByGoodsID(db, "737116531267")
|
||||
if p.CollectStatus != model.CollectCollected {
|
||||
t.Errorf("拒绝后商品仍应为 collected,实际 %s", p.CollectStatus)
|
||||
}
|
||||
var taskCount int
|
||||
if err := db.QueryRow(`SELECT COUNT(*) FROM tasks WHERE task_type='collect'`).Scan(&taskCount); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if taskCount != 0 {
|
||||
t.Fatalf("拒绝后不应创建任务,实际 %d", taskCount)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreatePddCollectTasks_按商品去重(t *testing.T) {
|
||||
db := newTestDB(t)
|
||||
createProduct(t, db, "737116531267")
|
||||
|
||||
Reference in New Issue
Block a user