From 7c57f14a31c3516ae8ff207743134c8ad9830b8a Mon Sep 17 00:00:00 2001 From: wangjia <809946525@qq.com> Date: Mon, 7 Sep 2026 09:18:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(backend):=20=E5=BA=93=E5=AD=98=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=A1=86=E6=94=AF=E6=8C=81=E6=8C=89=E7=94=9F=E4=BA=A7?= =?UTF-8?q?=E6=97=A5=E6=9C=9F=E6=A3=80=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - List 关键词查询在 名称/编码/拼音/首字母 之外增加生产日期匹配 CAST(COALESCE(DATE(sii.production_date),DATE(inv.production_date)) AS CHAR) LIKE 支持输入 年/年月/完整日期(2010 · 2010-06 · 2010-06-04),UI 无需改动 - 口径与列表显示/排序一致(入库明细快照优先,回退库存行快照) - 加回归测试 TestInventoryHandler_List_SearchByProductionDate Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5 --- backend/internal/handler/inventory.go | 6 +++-- backend/internal/handler/inventory_test.go | 30 ++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/backend/internal/handler/inventory.go b/backend/internal/handler/inventory.go index 0acfce3..d3b1d1d 100644 --- a/backend/internal/handler/inventory.go +++ b/backend/internal/handler/inventory.go @@ -105,9 +105,11 @@ func (h *InventoryHandler) List(c *gin.Context) { specStr := c.Query("spec") if keyword != "" { - baseWhere += " AND (COALESCE(NULLIF(p.name,''), NULLIF(sii.product_name,''), inv.product_name) LIKE ? OR COALESCE(NULLIF(p.code,''), NULLIF(sii.product_code,''), inv.product_code) LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ?)" + // 关键词匹配:商品名/拼音/首字母/编码 + 生产日期(对生产日期文本 LIKE,支持 "2010"/"2010-06"/"2010-06-04")。 + // 生产日期口径与 SELECT/排序一致:COALESCE(入库明细快照, 库存行快照)。 + baseWhere += " AND (COALESCE(NULLIF(p.name,''), NULLIF(sii.product_name,''), inv.product_name) LIKE ? OR COALESCE(NULLIF(p.code,''), NULLIF(sii.product_code,''), inv.product_code) LIKE ? OR p.name_pinyin LIKE ? OR p.name_initials LIKE ? OR CAST(COALESCE(DATE(sii.production_date), DATE(inv.production_date)) AS CHAR) LIKE ?)" like := "%" + keyword + "%" - args = append(args, like, like, like, like) + args = append(args, like, like, like, like, like) } // 商品编码独立筛选(库存屏工具栏第二个搜索框,对齐原型 codeInput) if code := c.Query("code"); code != "" { diff --git a/backend/internal/handler/inventory_test.go b/backend/internal/handler/inventory_test.go index 2ad9d39..c857ff8 100644 --- a/backend/internal/handler/inventory_test.go +++ b/backend/internal/handler/inventory_test.go @@ -316,6 +316,36 @@ func TestInventoryHandler_List_FilterByCode(t *testing.T) { assert.Equal(t, float64(0), parseResponse(w)["total"].(float64)) } +// 关键词搜索生产日期(库存搜索框扩展:UI 不变,输入年/年月/完整日期即可命中) +func TestInventoryHandler_List_SearchByProductionDate(t *testing.T) { + db := testutil.SetupTestDB() + shop := testutil.CreateTestShop(db, "INV_PDATE") + user := testutil.CreateTestUser(db, shop.ID, "admin", "pass", "admin") + warehouse := testutil.CreateTestWarehouse(db, shop.ID, "Warehouse") + p1 := testutil.CreateTestProduct(db, shop.ID, "MaotaiA") + p2 := testutil.CreateTestProduct(db, shop.ID, "MaotaiB") + token := getAuthToken(user.ID, shop.ID, "admin") + r := setupProtectedRouter(db) + + d2010 := &model.Date{Time: time.Date(2010, 6, 4, 0, 0, 0, 0, time.Local)} + d1999 := &model.Date{Time: time.Date(1999, 12, 16, 0, 0, 0, 0, time.Local)} + require.NoError(t, db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &p1.ID, Quantity: 10, ProductionDate: d2010}).Error) + require.NoError(t, db.Create(&model.Inventory{ShopID: shop.ID, WarehouseID: &warehouse.ID, ProductID: &p2.ID, Quantity: 20, ProductionDate: d1999}).Error) + + // 年份命中一条 + w := makeRequest(r, "GET", "/api/v1/inventory?keyword=2010", token, nil) + assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) + // 年-月命中一条 + w = makeRequest(r, "GET", "/api/v1/inventory?keyword=2010-06", token, nil) + assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) + // 完整日期命中一条 + w = makeRequest(r, "GET", "/api/v1/inventory?keyword=1999-12-16", token, nil) + assert.Equal(t, float64(1), parseResponse(w)["total"].(float64)) + // 不存在的日期零命中(同时验证不误伤名称/编码) + w = makeRequest(r, "GET", "/api/v1/inventory?keyword=2001", token, nil) + assert.Equal(t, float64(0), parseResponse(w)["total"].(float64)) +} + // Summary 月初快照字段:月初数量 = 当前数量 − 本月净流水 func TestInventoryHandler_Summary_LastMonth(t *testing.T) { db := testutil.SetupTestDB()