feat: 增加商品目录导入记录 (#134)

This commit is contained in:
chengma
2026-08-11 10:11:15 +08:00
parent 1961dd8356
commit 3ac4467f6c
12 changed files with 298 additions and 1 deletions
+65
View File
@@ -64,6 +64,71 @@ func GetCatalogImportRun(q Execer, source, batchID string) (model.CatalogImportR
return run, nil
}
// ListCatalogImportRuns 在数据库中按来源、状态筛选并倒序分页。
func ListCatalogImportRuns(q Execer, source string, status model.CatalogImportStatus, limit, offset int) ([]model.CatalogImportRun, int, error) {
where := " WHERE 1=1"
args := make([]any, 0, 4)
if source != "" {
where += " AND source=?"
args = append(args, source)
}
if status != "" {
where += " AND status=?"
args = append(args, status)
}
var total int
if err := q.QueryRow(`SELECT COUNT(*) FROM catalog_import_runs`+where, args...).Scan(&total); err != nil {
return nil, 0, fmt.Errorf("统计商品目录批次失败: %w", err)
}
listArgs := append(append([]any{}, args...), limit, offset)
rows, err := q.Query(`SELECT source,batch_id FROM catalog_import_runs`+where+` ORDER BY created_at DESC,source,batch_id LIMIT ? OFFSET ?`, listArgs...)
if err != nil {
return nil, 0, fmt.Errorf("查询商品目录批次列表失败: %w", err)
}
defer rows.Close()
keys := make([][2]string, 0, limit)
for rows.Next() {
var key [2]string
if err := rows.Scan(&key[0], &key[1]); err != nil {
return nil, 0, err
}
keys = append(keys, key)
}
if err := rows.Err(); err != nil {
return nil, 0, err
}
if err := rows.Close(); err != nil {
return nil, 0, err
}
list := make([]model.CatalogImportRun, 0, len(keys))
for _, key := range keys {
run, err := GetCatalogImportRun(q, key[0], key[1])
if err != nil {
return nil, 0, err
}
list = append(list, run)
}
return list, total, nil
}
// ListCatalogImportSources 返回筛选下拉框所需的稳定来源名。
func ListCatalogImportSources(q Execer) ([]string, error) {
rows, err := q.Query(`SELECT DISTINCT source FROM catalog_import_runs ORDER BY source`)
if err != nil {
return nil, err
}
defer rows.Close()
var list []string
for rows.Next() {
var source string
if err := rows.Scan(&source); err != nil {
return nil, err
}
list = append(list, source)
}
return list, rows.Err()
}
// RecordCatalogImportReplay 记录相同请求的重复提交,业务数据不会再次写入。
func RecordCatalogImportReplay(q Execer, source, batchID, requestedAt string) error {
result, err := q.Exec(`UPDATE catalog_import_runs SET request_count=request_count+1,last_request_at=?
+26
View File
@@ -3,6 +3,7 @@ package repository
import (
"database/sql"
"errors"
"fmt"
"testing"
_ "modernc.org/sqlite"
@@ -49,4 +50,29 @@ func TestCatalogImportRun_登记查询重放和冲突(t *testing.T) {
if got.RequestCount != 3 || got.ConflictCount != 1 || got.LastConflictAt == "" {
t.Fatalf("批次计数不正确:%+v", got)
}
other := run
other.Source, other.BatchID = "script-b", "batch-2"
if err := InsertCatalogImportRun(db, other); err != nil {
t.Fatal(err)
}
list, total, err := ListCatalogImportRuns(db, "script-a", model.CatalogImportProcessing, 20, 0)
if err != nil || total != 1 || len(list) != 1 || list[0].BatchID != "batch-1" {
t.Fatalf("分页筛选错误:total=%d list=%+v err=%v", total, list, err)
}
sources, err := ListCatalogImportSources(db)
if err != nil || len(sources) != 2 {
t.Fatalf("来源列表错误:%v %v", sources, err)
}
for i := 3; i <= 1001; i++ {
bulk := run
bulk.Source = "script-b"
bulk.BatchID = fmt.Sprintf("batch-%04d", i)
if err := InsertCatalogImportRun(db, bulk); err != nil {
t.Fatal(err)
}
}
page, total, err := ListCatalogImportRuns(db, "script-b", "", 20, 20)
if err != nil || total != 1000 || len(page) != 20 {
t.Fatalf("1000 条数据库分页错误:total=%d rows=%d err=%v", total, len(page), err)
}
}