diff --git a/backend/internal/modules/csmanualentry/repository.go b/backend/internal/modules/csmanualentry/repository.go index c188d49d..0d3f4b56 100644 --- a/backend/internal/modules/csmanualentry/repository.go +++ b/backend/internal/modules/csmanualentry/repository.go @@ -114,9 +114,17 @@ func (r *Repository) List(ctx context.Context, query ListQuery) (*PaginatedResul db := r.db.WithContext(ctx).Model(&model.CSManualEntry{}) countDB := r.db.WithContext(ctx).Model(&model.CSManualEntry{}) + // 编号查询:精确匹配该编号,并同时展示其带后缀的变体(如 202611060124-0、202611060124/1)。 if query.EntryNo != "" { - db = db.Where("entry_no = ?", query.EntryNo) - countDB = countDB.Where("entry_no = ?", query.EntryNo) + base := query.EntryNo + dashVariant := base + "-%" + slashVariant := base + "/%" + cond := r.db.Where( + "entry_no = ? OR entry_no LIKE ? OR entry_no LIKE ?", + base, dashVariant, slashVariant, + ) + db = db.Where(cond) + countDB = countDB.Where(cond) } if query.EntryGroup != "" { db = db.Where("entry_group = ?", query.EntryGroup) diff --git a/backend/internal/modules/csmanualentry/repository_test.go b/backend/internal/modules/csmanualentry/repository_test.go index 86b638a7..7434ccc4 100644 --- a/backend/internal/modules/csmanualentry/repository_test.go +++ b/backend/internal/modules/csmanualentry/repository_test.go @@ -230,3 +230,51 @@ func TestRepositoryEntryGroup(t *testing.T) { t.Fatalf("更新后组别标记 = %q, want sell", updated.GroupTag) } } + +func TestRepositoryListEntryNoWithSuffixVariants(t *testing.T) { + repo, db := newManualEntryTestRepo(t) + ctx := t.Context() + + admin := model.AdminUser{Username: "cs003", Nickname: "客服小王", PasswordHash: "x"} + if err := db.Create(&admin).Error; err != nil { + t.Fatalf("创建管理员失败: %v", err) + } + + // 基础编号 + 带 - / 后缀的变体 + numbers := []string{"202611060124", "202611060124-0", "202611060124/1", "202611060157", "202611060124-0-2"} + for _, no := range numbers { + if _, err := repo.Create(ctx, admin.ID, "客服小王", "cs003", no, EntryGroupCollect, "", "", ""); err != nil { + t.Fatalf("录入 %s 失败: %v", no, err) + } + } + + // 按基础编号搜索:应命中本体、-0、/1、-0-2,不命中无关编号 + list, err := repo.List(ctx, ListQuery{EntryNo: "202611060124", Page: 1, PageSize: 20}) + if err != nil { + t.Fatalf("按编号搜索失败: %v", err) + } + if list.Total != 4 { + t.Fatalf("按编号搜索命中 %d 条, want 4", list.Total) + } + got := make(map[string]bool) + for _, item := range list.Items { + got[item.EntryNo] = true + } + for _, want := range []string{"202611060124", "202611060124-0", "202611060124/1", "202611060124-0-2"} { + if !got[want] { + t.Fatalf("按编号搜索结果缺少 %s, got %v", want, got) + } + } + if got["202611060157"] { + t.Fatalf("不应命中无关编号 202611060157") + } + + // 按后缀变体精确搜索仍可用 + list, err = repo.List(ctx, ListQuery{EntryNo: "202611060124-0", Page: 1, PageSize: 20}) + if err != nil { + t.Fatalf("按带后缀编号搜索失败: %v", err) + } + if list.Total != 2 { + t.Fatalf("按带后缀编号搜索命中 %d 条, want 2 (本体变体 -0 与 -0-2)", list.Total) + } +} diff --git a/frontend/src/features/admin/views/AdminManualEntryView.vue b/frontend/src/features/admin/views/AdminManualEntryView.vue index a1b2fc6d..bc03ea75 100644 --- a/frontend/src/features/admin/views/AdminManualEntryView.vue +++ b/frontend/src/features/admin/views/AdminManualEntryView.vue @@ -473,7 +473,7 @@ async function handleRemoveOption(item: ManualEntryOption) {